From 3fc4539ba44f8aeff714583a6042d88aa7059649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 22 Apr 2024 13:54:22 -0700 Subject: [PATCH 01/99] fix: reformat --- .../bold/concepts/bold-technical-deep-dive.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index f515fe54b..45d56ace5 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -8,21 +8,19 @@ author: leeederek target_audience: 'Developers, users and researchers interested in the Arbitrum product suite.' sme: leeederek sidebar_position: 1 - --- - ## Overview Under the hood, a reason why BOLD can offer time-bounded, permissionless validation is because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond on the correct state and, through interactive fraud proofs, can prove their claim is correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BOLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. -Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it *can* help prove their correctness. *Anyone* in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. +Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. The assertions being disputed over are about block hashes of an Arbitrum chain at a given batch / inbox position. Given Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of a one-step-proof, Ethereum can check if someone is making a fraudulent assertion or not. -If a claim is honest, it can be confirmed on Ethereum after a 6.4 day period (although this period can be changed by the DAO). If a claim is malicious, anyone that knows the correct Arbitrum state can successfully challenge it within that 6.4 day window *and always win* within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4 day period (although this period can be changed by the DAO). If a claim is malicious, anyone that knows the correct Arbitrum state can successfully challenge it within that 6.4 day window _and always win_ within a challenge period. The current implementation of BOLD involves both on-chain and off-chain components: @@ -60,11 +58,11 @@ The current implementation of BOLD involves both on-chain and off-chain componen When it comes to implementing the protocol, BOLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain where the full protocol can be deployed to, with challenge moves performed as transactions to the protocol’s smart contracts. -A helpful mental model to understand the system is that it uses Ethereum itself as the ultimate *referee* for deciding results of assertions. Participants in the challenge protocol can disagree over *results of L2 state transitions*, and they can provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. +A helpful mental model to understand the system is that it uses Ethereum itself as the ultimate _referee_ for deciding results of assertions. Participants in the challenge protocol can disagree over _results of L2 state transitions_, and they can provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. ![Enter image alt description](../assets/KSf_Image_1.png) -*From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each in which anyone can challenge their validity on Ethereum.* +_From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each in which anyone can challenge their validity on Ethereum._ In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, and this is why this mini-VM is built to handle “one-step proofs” which consist of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM . @@ -73,7 +71,7 @@ All actors in the protocol have a local state of which they can produce valid pr ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BOLD requires several changes to how assertions work in this contract and it now contains a reference to another contract called a ChallengeManager, new in BOLD +- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BOLD requires several changes to how assertions work in this contract and it now contains a reference to another contract called a ChallengeManager, new in BOLD - **ChallengeManager:** this is a contract that allows for initiating challenge on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entrypoints for making challenge moves, opening leaves, creating subchallenges, and confirming challenges @@ -185,7 +183,7 @@ The number of steps of execution at which validators could disagree within a sin First, validators disagree over Arbitrum blocks in between two assertions. They make “edges” containing history commitments to all the blocks in between those two assertions, and play the bisection game. Once they narrow down to a single block of disagreement, they now need to find where they disagree in the actual WASM execution of the block through the Arbitrum state transition function. This is what we call the first “subchallenge”. -The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in *ranges* of steps. +The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “mini-bond”. The magnitudes of mini-bonds are different at each subchallenge level. @@ -195,7 +193,7 @@ Once validators reach a single, individual step of disagreement after reaching t #### Timers -Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge’s timer stops ticking the moment it has a rival edge created onchain. +Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge’s timer stops ticking the moment it has a rival edge created onchain. Edges also have something called an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge’s children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, the assertion it claims can also be confirmed as its associated challenge has completed. A minor, but important detail is that edges also inherit the time their claimed assertion was unrivaled. From 287c713f0953d80b6ceb1aae2d1d86b5faffc14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 13:31:23 -0700 Subject: [PATCH 02/99] feat: added new images > economics of disputes --- arbitrum-docs/bold/assets/9Pr_Image_1.png | Bin 0 -> 93982 bytes arbitrum-docs/bold/assets/BnF_Image_3.png | Bin 0 -> 5932 bytes arbitrum-docs/bold/assets/CRA_Image_4.png | Bin 0 -> 36992 bytes arbitrum-docs/bold/assets/csI_Image_2.png | Bin 0 -> 104406 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 arbitrum-docs/bold/assets/9Pr_Image_1.png create mode 100644 arbitrum-docs/bold/assets/BnF_Image_3.png create mode 100644 arbitrum-docs/bold/assets/CRA_Image_4.png create mode 100644 arbitrum-docs/bold/assets/csI_Image_2.png diff --git a/arbitrum-docs/bold/assets/9Pr_Image_1.png b/arbitrum-docs/bold/assets/9Pr_Image_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2d4e114bc9765bf428273eebbfb46984fdad000b GIT binary patch literal 93982 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�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

    W^_>hg?q2-o?Yd43)3QU1(DgKXFS|R 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 t%Ici6>YLLN6_k8iz_0!B{{h|OQE31G literal 0 HcmV?d00001 diff --git a/arbitrum-docs/bold/assets/BnF_Image_3.png b/arbitrum-docs/bold/assets/BnF_Image_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9b499f2eee765c8ad5f26d574bafa436abec7684 GIT binary patch literal 5932 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
    -| Flag | Description | -|-------------------------------|------------------------------------------------------------------------------------------------------| -| `--init` | Removes all the data, rebuilds, and deploys a new rollup | -| `--pos` | L1 is a proof-of-stake chain (using Prysm for consensus) | -| `--validate` | Validates all blocks in WASM, heavy computation | -| `--l3node` | Deploys an L3 node on top of the L2 | -| `--l3-fee-token` | Sets up the L3 chain to use a custom fee token. Only valid if `--l3node` flag is provided | -| `--l3-fee-token-decimals` | Number of decimals to use for a custom fee token. Only valid if `--l3-fee-token` flag is provided | -| `--l3-token-bridge` | Deploys an L2-L3 token bridge. Only valid if `--l3node` flag is provided | -| `--batchposters` | Batch posters [0-3] | -| `--redundantsequencers` | Redundant sequencers [0-3] | -| `--detach` | Detaches from nodes after running them | -| `--blockscout` | Builds or launches the Blockscout | -| `--simple` | Runs a simple configuration: one node as a sequencer/batch-poster/staker (default unless using `--dev`) | -| `--tokenbridge` | Deploy an L1-L2 token bridge | -| `--no-tokenbridge` | Opt out of building or launching the token bridge | -| `--no-run` | Does not launch nodes (useful with build or init) | -| `--no-simple` | Runs a full configuration with separate sequencer/batch-poster/validator/relayer | + | Flag | Description | + |-------------------------------|------------------------------------------------------------------------------------------------------| + | `--init` | Removes all the data, rebuilds, and deploys a new rollup | | `--pos` | L1 is a + proof-of-stake chain (using Prysm for consensus) | | `--validate` | Validates all blocks in WASM, + heavy computation | | `--l3node` | Deploys an L3 node on top of the L2 | | `--l3-fee-token` | Sets + up the L3 chain to use a custom fee token. Only valid if `--l3node` flag is provided | | + `--l3-fee-token-decimals` | Number of decimals to use for a custom fee token. Only valid if + `--l3-fee-token` flag is provided | | `--l3-token-bridge` | Deploys an L2-L3 token bridge. Only + valid if `--l3node` flag is provided | | `--batchposters` | Batch posters [0-3] | | + `--redundantsequencers` | Redundant sequencers [0-3] | | `--detach` | Detaches from nodes after + running them | | `--blockscout` | Builds or launches the Blockscout | | `--simple` | Runs a simple + configuration: one node as a sequencer/batch-poster/staker (default unless using `--dev`) | | + `--tokenbridge` | Deploy an L1-L2 token bridge | | `--no-tokenbridge` | Opt out of building or + launching the token bridge | | `--no-run` | Does not launch nodes (useful with build or init) | | + `--no-simple` | Runs a full configuration with separate sequencer/batch-poster/validator/relayer |
    diff --git a/arbitrum-docs/run-arbitrum-node/01-overview.md b/arbitrum-docs/run-arbitrum-node/01-overview.md index 6288e0f83..ec287fd1c 100644 --- a/arbitrum-docs/run-arbitrum-node/01-overview.md +++ b/arbitrum-docs/run-arbitrum-node/01-overview.md @@ -11,7 +11,7 @@ In order to be able to _interact with_ or _build applications on_ any of the Arb Here, you can find resources that help you run different types of Arbitrum nodes: -- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local dev node](/run-arbitrum-node/04-run-local-dev-node.md), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) +- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full node simulation](/run-arbitrum-node/04-run-local-full-node-simulation.md), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) - Step-by-step instructions for how to [read the sequencer feed](/run-arbitrum-node/sequencer/02-read-sequencer-feed.md), [build the Nitro locally](/run-arbitrum-node/nitro/01-build-nitro-locally.md) and [run the sequencer coordinator manager UI tool](/run-arbitrum-node/sequencer/03-run-sequencer-coordination-manager.md) - Step-by-step instructions for [how to configure a Data Availability Committee](/run-arbitrum-node/data-availability-committees/01-get-started.md) - [Troubleshooting page](/run-arbitrum-node/06-troubleshooting.md) diff --git a/arbitrum-docs/run-arbitrum-node/04-run-local-dev-node.md b/arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md similarity index 91% rename from arbitrum-docs/run-arbitrum-node/04-run-local-dev-node.md rename to arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md index 1be6182d5..74647c941 100644 --- a/arbitrum-docs/run-arbitrum-node/04-run-local-dev-node.md +++ b/arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md @@ -1,13 +1,15 @@ --- -title: 'How to run a local dev node' -description: Learn how to run an Arbitrum local dev node on your local machine. +title: 'How to run a local full node simulation' +description: This page provides instructions for setting up a complete local development environment for testing Arbitrum contracts in a fully simulated environment. author: jose-franco sme: jose-franco sidebar_position: 6 content_type: how-to --- -A local Arbitrum Nitro dev node can help you deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of deploying and running a full development environment on your local machine that includes a Nitro dev node, a dev-mode geth L1, and multiple instances with different roles. +## Overview + +A local full node simulation allows you to deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of setting up and running a complete development environment on your local machine, including a Nitro node, a dev-mode Geth L1, and multiple instances with different roles Note that the node is now Stylus-enabled by default, and the setup instructions remain the same as for running a Stylus dev node. diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx new file mode 100644 index 000000000..3a0448f0b --- /dev/null +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -0,0 +1,99 @@ +--- +title: 'How to run a local Nitro dev node' +description: 'This page provides instructions for setting up and running a local Nitro dev node for contract testing and development.' +author: mahsamoosavi +sme: mahsamoosavi +target_audience: 'Developers deploying smart contracts using Stylus' +content_type: how-to +sidebar_position: 5 +--- + +import PublicPreviewBannerPartial from '../partials/_public-preview-banner-partial.mdx'; + + + +## Overview + +This page provides step-by-step instructions for setting up and running a local Nitro dev node in `--dev` mode. This mode is ideal for developers who want to quickly test contracts using a single node, as it offers a simpler and faster setup compared to more complex environments. + +While some teams use `nitro-testnode` for testing cross-layer messaging, which involves launching both Geth as L1 and Nitro as L2, this setup can be more complex and time-consuming. If your primary goal is to test contracts on a local node without needing cross-layer interactions, Nitro's `--dev` mode offers a lightweight and efficient alternative. + +However, if you need more advanced functionality—such as cross-layer messaging, working with both L1 and L2 chains, or testing interactions between different layers—`nitro-testnode` is the preferred option. The testnode setup allows you to simulate a full L1-L2 environment, which is critical for those scenarios. See here for instructions. + +Note that Nitro `--dev` mode is particularly ideal for Stylus contract testing, as it is much lighter and faster to set up compared to the full nitro-testnode environment. + +## Prerequisites + +Before beginning, ensure [Docker](https://docs.docker.com/get-docker/) is installed and running on your machine. + +## Run the Nitro dev node + +Start the Nitro dev node in `--dev` mode using the following command. If the Docker image is not already present, Docker will automatically pull it for you. + +```bash +docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0 + +``` + +- Replace `offchainlabs/nitro-node:v3.2.1-d81324d` with the latest version of the Nitro image (@latestNitroNodeImage@) to ensure you're using the most up-to-date node. +- The node will listen for JSON-RPC requests on port 8547. +- The `--dev` flag initializes the node in development mode, providing an L2-only environment for testing. +- `--http.addr 0.0.0.0` binds the node to all available interfaces, making it accessible via both IPv4 (127.0.0.1) and IPv6 (::1). + +## Verify the node is running + +Once the node is up and running, you can verify its status by making a simple RPC request to check the network ID: + +```bash +curl -X POST -H "Content-Type: application/json" \ + --data '{ + "jsonrpc":"2.0", + "method":"net_version", + "params":[], + "id":1 + }' http://127.0.0.1:8547 +``` + +You should receive a response like: + +```bash +{ + "jsonrpc": "2.0", + "id": 1, + "result": "412346" +} +``` + +This confirms that your node is running and accessible. + +## What the `--dev` flag does + +The `--dev` flag simplifies the setup by initializing a development environment with a number of preset parameters, creating an L2-only chain without requiring an L1 listener. When you use the `--dev` flag, Nitro automatically applies the following parameters: + +In `--dev` mode, a default development account is available, which is pre-funded with ETH in all networks. This account can be used for deploying contracts, interacting with the chain, and assuming chain ownership. + +- **Address:** 0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E +- **Private key:** 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 + +## Setting the chain owner with `ArbDebug` precompile + +In Nitro `--dev` mode, the default chain owner is set to `0x0000000000000000000000000000000000000000`. However, you can use the [`ArbDebug` precompile](https://github.com/OffchainLabs/nitro-contracts/blob/main/src/precompiles/ArbDebug.sol) to set the chain owner. This precompile includes [the `becomeChainOwner()` function](https://github.com/OffchainLabs/nitro-contracts/blob/fbbcef09c95f69decabaced3da683f987902f3e2/src/precompiles/ArbDebug.sol#L13), which can be called to assume ownership of the chain. Chain ownership is important because it allows the owner to perform certain critical functions within the Arbitrum environment. + +To set the chain owner, you can call the `becomeChainOwner()` function with your preffered private key, we'll use the dev account as an example: + +```bash +cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 --rpc-url http://127.0.0.1:8547 +``` +- `0x00000000000000000000000000000000000000FF`: This is the address of the ArbDebug precompile on Arbitrum. +- `becomeChainOwner()`: This is the function call that transfers ownership of the chain to the caller. +- `--private-key`: Use the private key of the account that should become the chain owner. +- `--rpc-url http://127.0.0.1:8547`: Ensure that this points to your local Nitro dev node running in `--dev` mode. + + +Once you're the chain owner, you'll be able to access various Arbitrum-specific functions, such as: + +- Managing the Sequencer +- Modifying chain parameters +- Accessing debugging features + +This functionality is especially useful for development and testing purposes when using Nitro in `--dev` mode. \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index 92483af4a..2f2c13cb7 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -575,7 +575,7 @@ const sidebars = { { type: 'html', value: - 'Run a Stylus dev node', + 'Run a Stylus dev node', // q: why use an anchor html tag here?/node-running/how-tos/running-an-stylus-node // a: see note at end of file }, @@ -634,7 +634,12 @@ const sidebars = { }, { type: 'doc', - id: 'run-arbitrum-node/run-local-dev-node', + id: 'run-arbitrum-node/run-local-full-node-simulation', + label: 'Run a local full node simulation', + }, + { + type: 'doc', + id: 'run-arbitrum-node/run-nitro-dev-node', label: 'Run a local dev node', }, { From 08fbd1491ab670bfb92a10c033d0c3259ce7236c Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Thu, 24 Oct 2024 11:24:40 -0400 Subject: [PATCH 67/99] add dev node w cache manager script --- .../partials/_contribute-docs-partial.mdx | 2 +- .../run-arbitrum-node/01-overview.md | 2 +- ... => 04-run-local-full-chain-simulation.md} | 4 +- .../run-arbitrum-node/run-nitro-dev-node.mdx | 77 ++++- arbitrum-docs/stylus/stylus-quickstart.md | 318 ------------------ website/sidebars.js | 4 +- 6 files changed, 79 insertions(+), 328 deletions(-) rename arbitrum-docs/run-arbitrum-node/{04-run-local-full-node-simulation.md => 04-run-local-full-chain-simulation.md} (94%) delete mode 100644 arbitrum-docs/stylus/stylus-quickstart.md diff --git a/arbitrum-docs/partials/_contribute-docs-partial.mdx b/arbitrum-docs/partials/_contribute-docs-partial.mdx index 6d3c8dfdc..50c6111b1 100644 --- a/arbitrum-docs/partials/_contribute-docs-partial.mdx +++ b/arbitrum-docs/partials/_contribute-docs-partial.mdx @@ -114,7 +114,7 @@ Every document should be a specific _type_ of document. Each type of document ha | ------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Gentle introduction | Onboard a specific reader audience with tailored questions and answers | [A gentle introduction to Orbit](/launch-orbit-chain/orbit-gentle-introduction.md) | | Quickstart | Onboard a specific reader audience with step-by-step "learn by doing" instructions | [Quickstart: Build dApps](/build-decentralized-apps/01-quickstart-solidity-hardhat.md) | -| How-to | Provide task-oriented procedural guidance | [How to run a local dev node](/run-arbitrum-node/04-run-local-full-node-simulation.md) | +| How-to | Provide task-oriented procedural guidance | [How to run a full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md) | | Concept | Explain what things are and how they work | [Token bridging](/build-decentralized-apps/token-bridging/03-token-bridge-erc20.md)
    [Nodes and networks](https://docs.prylabs.network/docs/concepts/nodes-networks) | | FAQ | Address frequently asked questions | [FAQ: Run a node](../node-running/faq.md) | | Troubleshooting | List common troubleshooting scenarios and solutions | [Troubleshooting: Run a node](/run-arbitrum-node/06-troubleshooting.md) | diff --git a/arbitrum-docs/run-arbitrum-node/01-overview.md b/arbitrum-docs/run-arbitrum-node/01-overview.md index ec287fd1c..7ad0ae69f 100644 --- a/arbitrum-docs/run-arbitrum-node/01-overview.md +++ b/arbitrum-docs/run-arbitrum-node/01-overview.md @@ -11,7 +11,7 @@ In order to be able to _interact with_ or _build applications on_ any of the Arb Here, you can find resources that help you run different types of Arbitrum nodes: -- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full node simulation](/run-arbitrum-node/04-run-local-full-node-simulation.md), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) +- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) - Step-by-step instructions for how to [read the sequencer feed](/run-arbitrum-node/sequencer/02-read-sequencer-feed.md), [build the Nitro locally](/run-arbitrum-node/nitro/01-build-nitro-locally.md) and [run the sequencer coordinator manager UI tool](/run-arbitrum-node/sequencer/03-run-sequencer-coordination-manager.md) - Step-by-step instructions for [how to configure a Data Availability Committee](/run-arbitrum-node/data-availability-committees/01-get-started.md) - [Troubleshooting page](/run-arbitrum-node/06-troubleshooting.md) diff --git a/arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md b/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md similarity index 94% rename from arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md rename to arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md index 74647c941..b6d4af2cc 100644 --- a/arbitrum-docs/run-arbitrum-node/04-run-local-full-node-simulation.md +++ b/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md @@ -1,5 +1,5 @@ --- -title: 'How to run a local full node simulation' +title: 'How to run a local full chain simulation' description: This page provides instructions for setting up a complete local development environment for testing Arbitrum contracts in a fully simulated environment. author: jose-franco sme: jose-franco @@ -9,7 +9,7 @@ content_type: how-to ## Overview -A local full node simulation allows you to deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of setting up and running a complete development environment on your local machine, including a Nitro node, a dev-mode Geth L1, and multiple instances with different roles +A local full chain simulation allows you to deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of setting up and running a complete development environment on your local machine, including a Nitro node, a dev-mode Geth L1, and multiple instances with different roles Note that the node is now Stylus-enabled by default, and the setup instructions remain the same as for running a Stylus dev node. diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 3a0448f0b..85aa5c49c 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -14,7 +14,7 @@ import PublicPreviewBannerPartial from '../partials/_public-preview-banner-parti ## Overview -This page provides step-by-step instructions for setting up and running a local Nitro dev node in `--dev` mode. This mode is ideal for developers who want to quickly test contracts using a single node, as it offers a simpler and faster setup compared to more complex environments. +This page provides step-by-step instructions for setting up and running a local Nitro node in `--dev` mode. This mode is ideal for developers who want to quickly test contracts using a single node, as it offers a simpler and faster setup compared to more complex environments. While some teams use `nitro-testnode` for testing cross-layer messaging, which involves launching both Geth as L1 and Nitro as L2, this setup can be more complex and time-consuming. If your primary goal is to test contracts on a local node without needing cross-layer interactions, Nitro's `--dev` mode offers a lightweight and efficient alternative. @@ -31,7 +31,7 @@ Before beginning, ensure [Docker](https://docs.docker.com/get-docker/) is instal Start the Nitro dev node in `--dev` mode using the following command. If the Docker image is not already present, Docker will automatically pull it for you. ```bash -docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0 +docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0local Nitro dev node in `--dev` mode ``` @@ -84,16 +84,85 @@ To set the chain owner, you can call the `becomeChainOwner()` function with your ```bash cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 --rpc-url http://127.0.0.1:8547 ``` + - `0x00000000000000000000000000000000000000FF`: This is the address of the ArbDebug precompile on Arbitrum. - `becomeChainOwner()`: This is the function call that transfers ownership of the chain to the caller. - `--private-key`: Use the private key of the account that should become the chain owner. - `--rpc-url http://127.0.0.1:8547`: Ensure that this points to your local Nitro dev node running in `--dev` mode. - Once you're the chain owner, you'll be able to access various Arbitrum-specific functions, such as: - Managing the Sequencer - Modifying chain parameters - Accessing debugging features -This functionality is especially useful for development and testing purposes when using Nitro in `--dev` mode. \ No newline at end of file +This functionality is especially useful for development and testing purposes when using Nitro in `--dev` mode. + +## Running Nitro dev node for Stylus testing + +If your goal is to test Stylus contracts on Nitro in `--dev` mode, you can set up the environment in the same way, but with the added step of deploying the `Stylus Cache Manager`, which is necessary for Stylus-specific functionality. + +To automate this process, you can use a bash script that both runs the Nitro dev node and deploys the `Stylus Cache Manager` contract automatically. Here's how you can do it: + +### Step 1: Create a Bash script to automate the process + +Create a new file called `run_nitro_with_cache_manager.sh` and add the following content: + +```bash +#!/bin/bash + +# Start Nitro Dev Node in the background +echo "Starting Nitro dev node..." +docker run --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0 & + +# Wait for the node to initialize +echo "Waiting for the Nitro node to initialize..." +sleep 15 # Adjust the sleep time if necessary based on node startup time + +# Check if node is running +curl_output=$(curl -s -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":1}' \ + http://127.0.0.1:8547) + +if [[ "$curl_output" == *"result"* ]]; then + echo "Nitro node is running!" +else + echo "Failed to start Nitro node." + exit 1 +fi + +echo "Deploying Cache Manager contract..." +cast send --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ +--rpc-url http://127.0.0.1:8547 \ +--create 0x60a06040523060805234801561001457600080fd5b50608051611d1c61003060003960006105260152611d1c6000f3fe60806040526004361061011f5760003560e01c8063b187bd26116100a0578063c77ed13e11610064578063c77ed13e14610353578063cadb43e214610373578063d29b303e14610393578063e4940157146103b3578063e9c1bc0f146103c657600080fd5b8063b187bd261461027c578063b30906d4146102ad578063bae6c2ad146102f9578063c1c013c414610320578063c565a2081461033357600080fd5b806354fac919116100e757806354fac919146101de5780635c32e9431461021d5780635c975abb14610232578063674a64e014610247578063a8d6fe041461026757600080fd5b806317be85c31461012457806320f2f3451461014f5780632dd4f5661461017157806332052a9b146101915780633f4ba83a146101c9575b600080fd5b34801561013057600080fd5b506101396103e6565b6040516101469190611a2c565b60405180910390f35b34801561015b57600080fd5b5061016f61016a366004611ab3565b610473565b005b34801561017d57600080fd5b5061016f61018c366004611ae6565b6105f9565b34801561019d57600080fd5b506101b16101ac366004611b16565b6106d3565b6040516001600160c01b039091168152602001610146565b3480156101d557600080fd5b5061016f6106ee565b3480156101ea57600080fd5b5060035461020590600160801b90046001600160401b031681565b6040516001600160401b039091168152602001610146565b34801561022957600080fd5b5061016f6107aa565b34801561023e57600080fd5b5061016f610847565b34801561025357600080fd5b50600354610205906001600160401b031681565b34801561027357600080fd5b5061016f610909565b34801561028857600080fd5b5060035461029d90600160c01b900460ff1681565b6040519015158152602001610146565b3480156102b957600080fd5b506102cd6102c8366004611b33565b6109d4565b604080519384526001600160401b0390921660208401526001600160c01b031690820152606001610146565b34801561030557600080fd5b5060035461020590600160401b90046001600160401b031681565b61020561032e366004611ae6565b610a1d565b34801561033f57600080fd5b506101b161034e366004611b33565b610ab6565b34801561035f57600080fd5b5061016f61036e366004611ae6565b610ac4565b34801561037f57600080fd5b5061016f61038e366004611b33565b610ba3565b34801561039f57600080fd5b506101b16103ae366004611ae6565b610c7a565b61016f6103c1366004611b16565b610e5f565b3480156103d257600080fd5b506101396103e1366004611b33565b610ef0565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561046a5760008481526020908190206040805160608101825260028602909201805483526001908101546001600160401b03811684860152600160401b90046001600160c01b031691830191909152908352909201910161040a565b50505050905090565b600054610100900460ff1661048e5760005460ff1615610492565b303b155b6104fa5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff1615801561051c576000805461ffff19166101011790555b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036105a95760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104f1565b600380546001600160401b03848116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169086161717905580156105f4576000805461ff00191690555b505050565b6040516304ddefed60e31b8152606b906326ef7f689061061d903390600401611b4c565b602060405180830381865afa15801561063a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065e9190611b60565b61067d5733604051639531eff160e01b81526004016104f19190611b4c565b6003805467ffffffffffffffff19166001600160401b0383169081179091556040519081527fca22875e098f3b9c06ff3950c0cded621c968253a16623e890165451094c1839906020015b60405180910390a150565b60006106e8826001600160a01b03163f610ab6565b92915050565b6040516304ddefed60e31b8152606b906326ef7f6890610712903390600401611b4c565b602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190611b60565b6107725733604051639531eff160e01b81526004016104f19190611b4c565b6003805460ff60c01b191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b6040516304ddefed60e31b8152606b906326ef7f68906107ce903390600401611b4c565b602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190611b60565b61082e5733604051639531eff160e01b81526004016104f19190611b4c565b610839600019610ba3565b610845600260006119f1565b565b6040516304ddefed60e31b8152606b906326ef7f689061086b903390600401611b4c565b602060405180830381865afa158015610888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ac9190611b60565b6108cb5733604051639531eff160e01b81526004016104f19190611b4c565b6003805460ff60c01b1916600160c01b1790556040517f6985a02210a168e66602d3235cb6 +0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610708565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b606061028583836040518060600160405280602781526020016108076027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f5565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051d565b6000825111806103b15750805b156101c3576103" + +# Keep the Nitro node running +echo "Cache Manager deployed. Nitro node is running..." +wait # Keep the script alive and the node running +``` + +### Step 2: Make the script executable + +After creating the file, make the script executable by running the following command: + +```bash +chmod +x run_nitro_with_cache_manager.sh +``` + +### Step 3: Run the script + +To run the script and start the Nitro `dev` node along with deploying the `Cache Manager`, use the following command: + +```bash +./run_nitro_with_cache_manager.sh +``` + +This script will: + +- Start the Nitro `dev` node in the background using Docker. +- Wait for the node to initialize. +- Deploy the `Cache Manager` contarct using the bytecode provided. +- Keep the node running for further interactions. + +At the end of the process, you'll have the Nitro `dev` mode running with the Stylus `Cache Manager` deployed. You can now proceed to test and interact with your Stylus contracts in this environment, leveraging the deployed `Cache Manager` for added Stylus functionality. diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md deleted file mode 100644 index 91d85aedd..000000000 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ /dev/null @@ -1,318 +0,0 @@ ---- -title: 'Quickstart: write a smart contract in Rust using Stylus' -description: 'Leads a developer from 0 to 1 writing and deploying a smart contract in Rust using Stylus' -author: chrisco512, anegg0 -sme: chrisco512, anegg0 -sidebar_position: 2 -target_audience: Developers writing Stylus contracts in Rust using Stylus ---- - -import PublicPreviewBannerPartial from '../partials/_public-preview-banner-partial.mdx'; - - - -This guide will get you started with Stylus' basics. We'll cover the following steps: - -1. [Setting up your development environment](./stylus-quickstart#setting-up-your-development-environment) -2. [Creating a Stylus project with cargo stylus](./stylus-quickstart#creating-a-stylus-project-with-cargo-stylus) -3. [Checking the validity of your contract](./stylus-quickstart#checking-if-your-stylus-project-is-valid) -4. [Deploying your contract](./stylus-quickstart#deploying-your-contract) -5. [Exporting your contract's ABIs](./stylus-quickstart#exporting-solidity-abis) -6. [Calling your contract](./stylus-quickstart#calling-your-contract) -7. [Sending a transaction to your contract](./stylus-quickstart#sending-a-transaction-to-your-contract) - -## Setting up your development environment - -### Prerequisites - -#### Rust toolchain - -Follow the instructions on [Rust Lang’s installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. - -#### VS Code - -We recommend [VSCode](https://code.visualstudio.com/) as the IDE of choice for its excellent Rust support, but feel free to use another text editor or IDE if you’re comfortable with those. - -Some helpful VS Code extensions for Rust development: - -- [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer): Provides advanced features like smart code completion and on-the-fly error checks -- [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens): Immediately highlights errors and warnings in your code -- [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml): Improves syntax highlighting and other features for TOML files, often used in Rust projects -- [Dependi](https://marketplace.visualstudio.com/items?itemName=fill-labs.dependi): Helps manage Rust crate versions directly from the editor - -#### Docker - -The testnode we will use as well as some `cargo stylus` commands require Docker to operate. - -You can download Docker from [Docker’s website](https://www.docker.com/products/docker-desktop). - -#### Foundry's Cast - -[Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool that allows you to interact with your EVM contracts. - -#### Nitro testnode - -Stylus is available on Arbitrum Sepolia, but we'll use nitro testnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. - -```shell title="Install your testnode" -git clone -b release --recurse-submodules https://github.com/OffchainLabs/nitro-testnode.git && cd nitro-testnode -``` - -```shell title="Launch your testnode" -./test-node.bash --init -``` - -The initialization part might take up to a few minutes, but you can move on to the next section while it launches. - -```shell title="Re-use your testnode" -./test-node.bash -``` - -## Creating a Stylus project with cargo stylus - -[cargo stylus](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) is a CLI toolkit built to facilitate the development of Stylus contracts. - -It is available as a plugin to the standard cargo tool used for developing Rust programs. - -### Installing cargo stylus - -In your terminal, run: - -```shell -cargo install --force cargo-stylus -``` - -Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: - -```shell -rustup default 1.80 -rustup target add wasm32-unknown-unknown --toolchain 1.80 -``` - -You can verify that cargo stylus is installed by running `cargo stylus --help` in your terminal, which will return a list of helpful commands, we will use some of them in this guide: - -```shell title="cargo stylus --help returns:" -Cargo command for developing Stylus projects - -Usage: cargo stylus - -Commands: - new Create a new Stylus project - init Initializes a Stylus project in the current directory - export-abi Export a Solidity ABI - activate Activate an already deployed contract [aliases: a] - cache Cache a contract using the Stylus CacheManager for Arbitrum chains - check Check a contract [aliases: c] - deploy Deploy a contract [aliases: d] - verify Verify the deployment of a Stylus contract [aliases: v] - cgen Generate c code bindings for a Stylus contract - replay Replay a transaction in gdb [aliases: r] - trace Trace a transaction [aliases: t] - help Print this message or the help of the given command(s) - -Options: - -h, --help Print help - -V, --version Print version -``` - -### Creating a project - -Let's create our first Stylus project by running: - -```shell -cargo stylus new -``` - -`cargo stylus new` generates a starter template that implements a Rust version of the [Solidity `Counter` smart contract example](https://github.com/OffchainLabs/counter_contract/blob/master/contracts/Counter.sol). - -At this point, you can move on to the next step of this guide or develop your first Rust smart contract. Feel free to use the [Stylus Rust SDK reference section](./reference/overview) as a starting point; it offers many examples to help you quickly familiarize yourself with Stylus. - -## Checking if your Stylus project is valid - -By running `cargo stylus check` against your first contract, you can check if your program can be successfully **deployed and activated** onchain. - -**Important:** Ensure your Docker service runs so this command works correctly. - -```shell -cargo stylus check -``` - -`cargo stylus check` executes a dry run on your project by compiling your contract to WASM and verifying if it can be deployed and activated onchain. - -If the command above fails, you'll see detailed information about why your contract would be rejected: - -```shell -Reading WASM file at bad-export.wat -Compressed WASM size: 55 B -Stylus checks failed: program pre-deployment check failed when checking against -ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: program activation failed: failed to parse program) - -Caused by: - binary exports reserved symbol stylus_ink_left - -Location: - prover/src/binary.rs:493:9, data: None -``` - -The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. - -If your contract succeeds, you'll see something like this: - -```shell -Finished release [optimized] target(s) in 1.88s -Reading WASM file at hello-stylus/target/wasm32-unknown-unknown/release/hello-stylus.wasm -Compressed WASM size: 3 KB -Program succeeded Stylus onchain activation checks with Stylus version: 1 -``` - -Note that running `cargo stylus check` may take a few minutes, especially if you're verifying a contract for the first time. - -See `cargo stylus check --help` for more options. - -## Deploying your contract - -Once you're ready to deploy your contract onchain, `cargo stylus deploy` will help you with the deployment and its gas estimation. - -### Estimating gas - -Note: For every transaction, we'll use the testnode pre-funded wallet, you can use `0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659` as your private key. - -You can estimate the gas required to deploy your contract by running: - -```shell -cargo stylus deploy \ - --endpoint='http://localhost:8547' \ - --private-key="0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" \ - --estimate-gas -``` - -The command should return something like this: - -```shell -deployment tx gas: 7123737 -gas price: "0.100000000" gwei -deployment tx total cost: "0.000712373700000000" ETH -``` - -### Deployment - -Let's move on to the contract's actual deployment. Two transactions will be sent onchain: the contract deployment and its [activation](stylus/stylus-gentle-introduction.md#activation). - -```shell -cargo stylus deploy \ - --endpoint='http://localhost:8547' \ - --private-key="0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" -``` - -Once the deployment and activations are successful, you'll see an output similar to this: - -```shell -deployed code at address: 0x33f54de59419570a9442e788f5dd5cf635b3c7ac -deployment tx hash: 0xa55efc05c45efc63647dff5cc37ad328a47ba5555009d92ad4e297bf4864de36 -wasm already activated! -``` - -Make sure to save the contract's deployment address for future interactions! - -More options are available for sending and outputting your transaction data. See `cargo stylus deploy --help` for more details. - -## Exporting the Solidity ABI interface - -The cargo stylus tool makes it easy to export your contract's ABI using `cargo stylus export-abi`. - -This command returns the Solidity ABI interface of your smart contract. If you have been running `cargo stylus new` without modifying the output, `cargo stylus export-abi` will return: - -```shell -/** - * This file was automatically generated by Stylus and represents a Rust program. - * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs). - */ - -// SPDX-License-Identifier: MIT-OR-APACHE-2.0 -pragma solidity ^0.8.23; - -interface ICounter { - function number() external view returns (uint256); - - function setNumber(uint256 new_number) external; - - function mulNumber(uint256 new_number) external; - - function addNumber(uint256 new_number) external; - - function increment() external; -} -``` - -Ensure you save the console output to a file that you'll be able to use with your dApp. - -## Interacting with your Stylus contract - -Stylus contracts are EVM-compatible, you can interact with them with your tool of choice, such as [Hardhat](https://hardhat.org/), [Foundry's Cast](https://book.getfoundry.sh/cast/), or any other Ethereum-compatible tool. - -In this example, we'll use Foundry's Cast to send a call and then a transaction to our contract. - -### Calling your contract - -Our contract is a counter; in its initial state, it should store a counter value of `0`. -You can call your contract so it returns its current counter value by sending it the following command: - -```shell title="Call to the function: number()(uint256)" -cast call --rpc-url 'http://localhost:8547' --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ -[deployed-contract-address] "number()(uint256)" -``` - -Let's break down the command: - -- `cast call` command sends a call to your contract -- The `--rpc-url` option is the `RPC URL` endpoint of our testnode: http://localhost:8547 -- The `--private-key` option is the private key of our pre-funded development account. It corresponds to the address `0x3f1eae7d46d88f08fc2f8ed27fcb2ab183eb2d0e` -- The [deployed-contract-address] is the address we want to interact with, it's the address that was returned by `cargo stylus deploy` -- `number()(uint256)` is the function we want to call in Solidity-style signature. The function returns the counter's current value - -```shell title="Calling 'number()(uint256)' returns:" -0 -``` - -The `number()(uint256)` function returns a value of `0`, the contract's initial state. - -### Sending a transaction to your contract - -Let's increment the counter by sending a transaction to your contract's `increment()` function. -We'll use Cast's `send` command to send our transaction. - -```shell title="Sending a transaction to the function: increment()" -cast send --rpc-url 'http://localhost:8547' --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ -[deployed-contract-address] "increment()" -``` - -```shell title="Transaction returns:" -blockHash 0xfaa2cce3b9995f3f2e2a2f192dc50829784da9ca4b7a1ad21665a25b3b161f7c -blockNumber 20 -contractAddress -cumulativeGasUsed 97334 -effectiveGasPrice 100000000 -from 0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E -gasUsed 97334 -logs [] -logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -root -status 1 (success) -transactionHash 0x28c6ba8a0b9915ed3acc449cf6c645ecc406a4b19278ec1eb67f5a7091d18f6b -transactionIndex 1 -type 2 -blobGasPrice -blobGasUsed -authorizationList -to 0x11B57FE348584f042E436c6Bf7c3c3deF171de49 -gasUsedForL1 "0x0" -l1BlockNumber "0x1223" -``` - -Our transactions returned a status of `1`, indicating success, and the counter has been incremented (you can verify this by calling your contract's `number()(uint256)` function again). - -## Conclusion - -Congratulations! You've successfully initialized, deployed, and interacted with your first contract using Stylus and Rust. - -Feel free to explore the [Stylus Rust SDK reference](./reference/overview) for more information on using Stylus in your Arbitrum projects. diff --git a/website/sidebars.js b/website/sidebars.js index 2f2c13cb7..9cfb7b052 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -634,8 +634,8 @@ const sidebars = { }, { type: 'doc', - id: 'run-arbitrum-node/run-local-full-node-simulation', - label: 'Run a local full node simulation', + id: 'run-arbitrum-node/run-local-full-chain-simulation', + label: 'Run a local full chain simulation', }, { type: 'doc', From 6ca936c9fedbbbe2b10f8fc4b8660f102966eb1d Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Thu, 24 Oct 2024 12:05:34 -0400 Subject: [PATCH 68/99] Restore stylus-quickstart.md --- arbitrum-docs/stylus/stylus-quickstart.md | 318 ++++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 arbitrum-docs/stylus/stylus-quickstart.md diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md new file mode 100644 index 000000000..91d85aedd --- /dev/null +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -0,0 +1,318 @@ +--- +title: 'Quickstart: write a smart contract in Rust using Stylus' +description: 'Leads a developer from 0 to 1 writing and deploying a smart contract in Rust using Stylus' +author: chrisco512, anegg0 +sme: chrisco512, anegg0 +sidebar_position: 2 +target_audience: Developers writing Stylus contracts in Rust using Stylus +--- + +import PublicPreviewBannerPartial from '../partials/_public-preview-banner-partial.mdx'; + + + +This guide will get you started with Stylus' basics. We'll cover the following steps: + +1. [Setting up your development environment](./stylus-quickstart#setting-up-your-development-environment) +2. [Creating a Stylus project with cargo stylus](./stylus-quickstart#creating-a-stylus-project-with-cargo-stylus) +3. [Checking the validity of your contract](./stylus-quickstart#checking-if-your-stylus-project-is-valid) +4. [Deploying your contract](./stylus-quickstart#deploying-your-contract) +5. [Exporting your contract's ABIs](./stylus-quickstart#exporting-solidity-abis) +6. [Calling your contract](./stylus-quickstart#calling-your-contract) +7. [Sending a transaction to your contract](./stylus-quickstart#sending-a-transaction-to-your-contract) + +## Setting up your development environment + +### Prerequisites + +#### Rust toolchain + +Follow the instructions on [Rust Lang’s installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. + +#### VS Code + +We recommend [VSCode](https://code.visualstudio.com/) as the IDE of choice for its excellent Rust support, but feel free to use another text editor or IDE if you’re comfortable with those. + +Some helpful VS Code extensions for Rust development: + +- [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer): Provides advanced features like smart code completion and on-the-fly error checks +- [Error Lens](https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens): Immediately highlights errors and warnings in your code +- [Even Better TOML](https://marketplace.visualstudio.com/items?itemName=tamasfe.even-better-toml): Improves syntax highlighting and other features for TOML files, often used in Rust projects +- [Dependi](https://marketplace.visualstudio.com/items?itemName=fill-labs.dependi): Helps manage Rust crate versions directly from the editor + +#### Docker + +The testnode we will use as well as some `cargo stylus` commands require Docker to operate. + +You can download Docker from [Docker’s website](https://www.docker.com/products/docker-desktop). + +#### Foundry's Cast + +[Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool that allows you to interact with your EVM contracts. + +#### Nitro testnode + +Stylus is available on Arbitrum Sepolia, but we'll use nitro testnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. + +```shell title="Install your testnode" +git clone -b release --recurse-submodules https://github.com/OffchainLabs/nitro-testnode.git && cd nitro-testnode +``` + +```shell title="Launch your testnode" +./test-node.bash --init +``` + +The initialization part might take up to a few minutes, but you can move on to the next section while it launches. + +```shell title="Re-use your testnode" +./test-node.bash +``` + +## Creating a Stylus project with cargo stylus + +[cargo stylus](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) is a CLI toolkit built to facilitate the development of Stylus contracts. + +It is available as a plugin to the standard cargo tool used for developing Rust programs. + +### Installing cargo stylus + +In your terminal, run: + +```shell +cargo install --force cargo-stylus +``` + +Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: + +```shell +rustup default 1.80 +rustup target add wasm32-unknown-unknown --toolchain 1.80 +``` + +You can verify that cargo stylus is installed by running `cargo stylus --help` in your terminal, which will return a list of helpful commands, we will use some of them in this guide: + +```shell title="cargo stylus --help returns:" +Cargo command for developing Stylus projects + +Usage: cargo stylus + +Commands: + new Create a new Stylus project + init Initializes a Stylus project in the current directory + export-abi Export a Solidity ABI + activate Activate an already deployed contract [aliases: a] + cache Cache a contract using the Stylus CacheManager for Arbitrum chains + check Check a contract [aliases: c] + deploy Deploy a contract [aliases: d] + verify Verify the deployment of a Stylus contract [aliases: v] + cgen Generate c code bindings for a Stylus contract + replay Replay a transaction in gdb [aliases: r] + trace Trace a transaction [aliases: t] + help Print this message or the help of the given command(s) + +Options: + -h, --help Print help + -V, --version Print version +``` + +### Creating a project + +Let's create our first Stylus project by running: + +```shell +cargo stylus new +``` + +`cargo stylus new` generates a starter template that implements a Rust version of the [Solidity `Counter` smart contract example](https://github.com/OffchainLabs/counter_contract/blob/master/contracts/Counter.sol). + +At this point, you can move on to the next step of this guide or develop your first Rust smart contract. Feel free to use the [Stylus Rust SDK reference section](./reference/overview) as a starting point; it offers many examples to help you quickly familiarize yourself with Stylus. + +## Checking if your Stylus project is valid + +By running `cargo stylus check` against your first contract, you can check if your program can be successfully **deployed and activated** onchain. + +**Important:** Ensure your Docker service runs so this command works correctly. + +```shell +cargo stylus check +``` + +`cargo stylus check` executes a dry run on your project by compiling your contract to WASM and verifying if it can be deployed and activated onchain. + +If the command above fails, you'll see detailed information about why your contract would be rejected: + +```shell +Reading WASM file at bad-export.wat +Compressed WASM size: 55 B +Stylus checks failed: program pre-deployment check failed when checking against +ARB_WASM_ADDRESS 0x0000…0071: (code: -32000, message: program activation failed: failed to parse program) + +Caused by: + binary exports reserved symbol stylus_ink_left + +Location: + prover/src/binary.rs:493:9, data: None +``` + +The contract can fail the check for various reasons (on compile, deployment, etc...). Reading the [Invalid Stylus WASM Contracts explainer](https://github.com/OffchainLabs/cargo-stylus/blob/main/main/VALID_WASM.md) can help you understand what makes a WASM contract valid or not. + +If your contract succeeds, you'll see something like this: + +```shell +Finished release [optimized] target(s) in 1.88s +Reading WASM file at hello-stylus/target/wasm32-unknown-unknown/release/hello-stylus.wasm +Compressed WASM size: 3 KB +Program succeeded Stylus onchain activation checks with Stylus version: 1 +``` + +Note that running `cargo stylus check` may take a few minutes, especially if you're verifying a contract for the first time. + +See `cargo stylus check --help` for more options. + +## Deploying your contract + +Once you're ready to deploy your contract onchain, `cargo stylus deploy` will help you with the deployment and its gas estimation. + +### Estimating gas + +Note: For every transaction, we'll use the testnode pre-funded wallet, you can use `0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659` as your private key. + +You can estimate the gas required to deploy your contract by running: + +```shell +cargo stylus deploy \ + --endpoint='http://localhost:8547' \ + --private-key="0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" \ + --estimate-gas +``` + +The command should return something like this: + +```shell +deployment tx gas: 7123737 +gas price: "0.100000000" gwei +deployment tx total cost: "0.000712373700000000" ETH +``` + +### Deployment + +Let's move on to the contract's actual deployment. Two transactions will be sent onchain: the contract deployment and its [activation](stylus/stylus-gentle-introduction.md#activation). + +```shell +cargo stylus deploy \ + --endpoint='http://localhost:8547' \ + --private-key="0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659" +``` + +Once the deployment and activations are successful, you'll see an output similar to this: + +```shell +deployed code at address: 0x33f54de59419570a9442e788f5dd5cf635b3c7ac +deployment tx hash: 0xa55efc05c45efc63647dff5cc37ad328a47ba5555009d92ad4e297bf4864de36 +wasm already activated! +``` + +Make sure to save the contract's deployment address for future interactions! + +More options are available for sending and outputting your transaction data. See `cargo stylus deploy --help` for more details. + +## Exporting the Solidity ABI interface + +The cargo stylus tool makes it easy to export your contract's ABI using `cargo stylus export-abi`. + +This command returns the Solidity ABI interface of your smart contract. If you have been running `cargo stylus new` without modifying the output, `cargo stylus export-abi` will return: + +```shell +/** + * This file was automatically generated by Stylus and represents a Rust program. + * For more information, please see [The Stylus SDK](https://github.com/OffchainLabs/stylus-sdk-rs). + */ + +// SPDX-License-Identifier: MIT-OR-APACHE-2.0 +pragma solidity ^0.8.23; + +interface ICounter { + function number() external view returns (uint256); + + function setNumber(uint256 new_number) external; + + function mulNumber(uint256 new_number) external; + + function addNumber(uint256 new_number) external; + + function increment() external; +} +``` + +Ensure you save the console output to a file that you'll be able to use with your dApp. + +## Interacting with your Stylus contract + +Stylus contracts are EVM-compatible, you can interact with them with your tool of choice, such as [Hardhat](https://hardhat.org/), [Foundry's Cast](https://book.getfoundry.sh/cast/), or any other Ethereum-compatible tool. + +In this example, we'll use Foundry's Cast to send a call and then a transaction to our contract. + +### Calling your contract + +Our contract is a counter; in its initial state, it should store a counter value of `0`. +You can call your contract so it returns its current counter value by sending it the following command: + +```shell title="Call to the function: number()(uint256)" +cast call --rpc-url 'http://localhost:8547' --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ +[deployed-contract-address] "number()(uint256)" +``` + +Let's break down the command: + +- `cast call` command sends a call to your contract +- The `--rpc-url` option is the `RPC URL` endpoint of our testnode: http://localhost:8547 +- The `--private-key` option is the private key of our pre-funded development account. It corresponds to the address `0x3f1eae7d46d88f08fc2f8ed27fcb2ab183eb2d0e` +- The [deployed-contract-address] is the address we want to interact with, it's the address that was returned by `cargo stylus deploy` +- `number()(uint256)` is the function we want to call in Solidity-style signature. The function returns the counter's current value + +```shell title="Calling 'number()(uint256)' returns:" +0 +``` + +The `number()(uint256)` function returns a value of `0`, the contract's initial state. + +### Sending a transaction to your contract + +Let's increment the counter by sending a transaction to your contract's `increment()` function. +We'll use Cast's `send` command to send our transaction. + +```shell title="Sending a transaction to the function: increment()" +cast send --rpc-url 'http://localhost:8547' --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ +[deployed-contract-address] "increment()" +``` + +```shell title="Transaction returns:" +blockHash 0xfaa2cce3b9995f3f2e2a2f192dc50829784da9ca4b7a1ad21665a25b3b161f7c +blockNumber 20 +contractAddress +cumulativeGasUsed 97334 +effectiveGasPrice 100000000 +from 0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E +gasUsed 97334 +logs [] +logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +root +status 1 (success) +transactionHash 0x28c6ba8a0b9915ed3acc449cf6c645ecc406a4b19278ec1eb67f5a7091d18f6b +transactionIndex 1 +type 2 +blobGasPrice +blobGasUsed +authorizationList +to 0x11B57FE348584f042E436c6Bf7c3c3deF171de49 +gasUsedForL1 "0x0" +l1BlockNumber "0x1223" +``` + +Our transactions returned a status of `1`, indicating success, and the counter has been incremented (you can verify this by calling your contract's `number()(uint256)` function again). + +## Conclusion + +Congratulations! You've successfully initialized, deployed, and interacted with your first contract using Stylus and Rust. + +Feel free to explore the [Stylus Rust SDK reference](./reference/overview) for more information on using Stylus in your Arbitrum projects. From 10cb87918e906317125f524ce1736a70ae7d06b6 Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Fri, 25 Oct 2024 10:07:21 -0400 Subject: [PATCH 69/99] address comments --- arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx | 5 ++--- arbitrum-docs/stylus/stylus-quickstart.md | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 85aa5c49c..5979b7765 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -31,11 +31,10 @@ Before beginning, ensure [Docker](https://docs.docker.com/get-docker/) is instal Start the Nitro dev node in `--dev` mode using the following command. If the Docker image is not already present, Docker will automatically pull it for you. ```bash -docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0local Nitro dev node in `--dev` mode - +docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:@latestNitroNodeImage@ --dev --http.addr 0.0.0.0 ``` -- Replace `offchainlabs/nitro-node:v3.2.1-d81324d` with the latest version of the Nitro image (@latestNitroNodeImage@) to ensure you're using the most up-to-date node. +- @latestNitroNodeImage@ is the latest version of the Nitro image. - The node will listen for JSON-RPC requests on port 8547. - The `--dev` flag initializes the node in development mode, providing an L2-only environment for testing. - `--http.addr 0.0.0.0` binds the node to all available interfaces, making it accessible via both IPv4 (127.0.0.1) and IPv6 (::1). diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md index 91d85aedd..270bbe357 100644 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -82,7 +82,7 @@ In your terminal, run: cargo install --force cargo-stylus ``` -Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: +Add WASM ([WebAssembly](https://webassembly.org/)) as a build target for the specific Rust toolchain you are using. The below example sets your default Rust toolchain to 1.80 as well as adding the WASM build target: ```shell rustup default 1.80 From b18736ca73338feb627d67d4216016f8602af326 Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Fri, 25 Oct 2024 10:39:22 -0400 Subject: [PATCH 70/99] Add ArbOwner functionality for modifying chain parameters --- arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 5979b7765..fee4b62cc 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -91,11 +91,13 @@ cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --priv Once you're the chain owner, you'll be able to access various Arbitrum-specific functions, such as: -- Managing the Sequencer -- Modifying chain parameters -- Accessing debugging features +- Adding or removing other chain owners +- Setting the L1 and L2 base fees directly +- Adjusting the gas pricing inertia and backlog tolerance +- Modifying the computational speed limit and transaction gas limits +- Managing network and infrastructure fee accounts -This functionality is especially useful for development and testing purposes when using Nitro in `--dev` mode. +These functions allow you to fully configure and optimize the chain for your development needs. ## Running Nitro dev node for Stylus testing From cfe1141c9794d50e24d8df5c826f3a1c27cfbcfd Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Fri, 25 Oct 2024 11:39:42 -0400 Subject: [PATCH 71/99] update the instructions to use the devnode repo --- .../run-arbitrum-node/run-nitro-dev-node.mdx | 140 ++++-------------- 1 file changed, 32 insertions(+), 108 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index fee4b62cc..292e58b33 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -24,72 +24,57 @@ Note that Nitro `--dev` mode is particularly ideal for Stylus contract testing, ## Prerequisites -Before beginning, ensure [Docker](https://docs.docker.com/get-docker/) is installed and running on your machine. +Before beginning, ensure the following is installed and running on your machine: -## Run the Nitro dev node +- Docker: Required to run the Nitro dev node in a container. Install Docker by following [the official installation guide](https://docs.docker.com/get-started/get-docker/) for your operating system. +- cast: A command-line tool from Foundry for interacting with Ethereum smart contracts. You can install it via Foundry by following [the installation instructions](https://book.getfoundry.sh/getting-started/installation). +- jq: A lightweight JSON parsing tool used to extract contract addresses from the script output. -Start the Nitro dev node in `--dev` mode using the following command. If the Docker image is not already present, Docker will automatically pull it for you. +## Clone the [nitro-devnode](https://github.com/OffchainLabs/nitro-devnode) repository + +use the following command to clone the repository: ```bash -docker run -it --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:@latestNitroNodeImage@ --dev --http.addr 0.0.0.0 +git clone https://github.com/OffchainLabs/nitro-devnode.git +cd nitro-devnode ``` -- @latestNitroNodeImage@ is the latest version of the Nitro image. -- The node will listen for JSON-RPC requests on port 8547. -- The `--dev` flag initializes the node in development mode, providing an L2-only environment for testing. -- `--http.addr 0.0.0.0` binds the node to all available interfaces, making it accessible via both IPv4 (127.0.0.1) and IPv6 (::1). - -## Verify the node is running +## Make the script executable: -Once the node is up and running, you can verify its status by making a simple RPC request to check the network ID: +Ensure the script has executable permissions: ```bash -curl -X POST -H "Content-Type: application/json" \ - --data '{ - "jsonrpc":"2.0", - "method":"net_version", - "params":[], - "id":1 - }' http://127.0.0.1:8547 +chmod +x run_dev_node.sh ``` -You should receive a response like: +## Run the dev node script: + +Run the script to start the Nitro dev node, deploy the Stylus `Cache Manager` contract, and register it as a WASM cache manager using the default development account: ```bash -{ - "jsonrpc": "2.0", - "id": 1, - "result": "412346" -} +./run_dev_node.sh ``` -This confirms that your node is running and accessible. - -## What the `--dev` flag does +The script will: -The `--dev` flag simplifies the setup by initializing a development environment with a number of preset parameters, creating an L2-only chain without requiring an L1 listener. When you use the `--dev` flag, Nitro automatically applies the following parameters: +- Start the Nitro dev node in the background using Docker. +- Deploy the Stylus `Cache Manager` contract on the local Nitro network. +- Register the `Cache Manager` contract as a WASM cache manager. -In `--dev` mode, a default development account is available, which is pre-funded with ETH in all networks. This account can be used for deploying contracts, interacting with the chain, and assuming chain ownership. +## Development account (used by default) -- **Address:** 0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E -- **Private key:** 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 +In `--dev` mode, the script uses a pre-funded development account by default. This account is pre-funded with ETH in all networks and is used to deploy contracts, interact with the chain, and assume chain ownership. -## Setting the chain owner with `ArbDebug` precompile +- Address: 0x3f1Eae7D46d88F08fc2F8ed27FCb2AB183EB2d0E +- Private key: 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 -In Nitro `--dev` mode, the default chain owner is set to `0x0000000000000000000000000000000000000000`. However, you can use the [`ArbDebug` precompile](https://github.com/OffchainLabs/nitro-contracts/blob/main/src/precompiles/ArbDebug.sol) to set the chain owner. This precompile includes [the `becomeChainOwner()` function](https://github.com/OffchainLabs/nitro-contracts/blob/fbbcef09c95f69decabaced3da683f987902f3e2/src/precompiles/ArbDebug.sol#L13), which can be called to assume ownership of the chain. Chain ownership is important because it allows the owner to perform certain critical functions within the Arbitrum environment. +You don’t need to set up a private key manually unless you prefer using your own key. -To set the chain owner, you can call the `becomeChainOwner()` function with your preffered private key, we'll use the dev account as an example: +## Chain ownership in `--dev` mode -```bash -cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 --rpc-url http://127.0.0.1:8547 -``` +In Nitro `--dev` mode, the default chain owner is set to `0x0000000000000000000000000000000000000000`. However, you can use the `ArbDebug` precompile to set the chain owner. This precompile includes the `becomeChainOwner()` function, which can be called to assume ownership of the chain. -- `0x00000000000000000000000000000000000000FF`: This is the address of the ArbDebug precompile on Arbitrum. -- `becomeChainOwner()`: This is the function call that transfers ownership of the chain to the caller. -- `--private-key`: Use the private key of the account that should become the chain owner. -- `--rpc-url http://127.0.0.1:8547`: Ensure that this points to your local Nitro dev node running in `--dev` mode. - -Once you're the chain owner, you'll be able to access various Arbitrum-specific functions, such as: +Chain ownership is important because it allows the owner to perform certain critical functions within the Arbitrum environment, such as: - Adding or removing other chain owners - Setting the L1 and L2 base fees directly @@ -97,73 +82,12 @@ Once you're the chain owner, you'll be able to access various Arbitrum-specific - Modifying the computational speed limit and transaction gas limits - Managing network and infrastructure fee accounts -These functions allow you to fully configure and optimize the chain for your development needs. - -## Running Nitro dev node for Stylus testing - -If your goal is to test Stylus contracts on Nitro in `--dev` mode, you can set up the environment in the same way, but with the added step of deploying the `Stylus Cache Manager`, which is necessary for Stylus-specific functionality. - -To automate this process, you can use a bash script that both runs the Nitro dev node and deploys the `Stylus Cache Manager` contract automatically. Here's how you can do it: - -### Step 1: Create a Bash script to automate the process - -Create a new file called `run_nitro_with_cache_manager.sh` and add the following content: +The script automatically sets the chain owner to the pre-funded dev account before registering the `Cache Manager` contract. Here’s how the `becomeChainOwner()` function is called within the script: ```bash -#!/bin/bash - -# Start Nitro Dev Node in the background -echo "Starting Nitro dev node..." -docker run --rm --name nitro-dev -p 8547:8547 offchainlabs/nitro-node:v3.2.1-d81324d --dev --http.addr 0.0.0.0 & - -# Wait for the node to initialize -echo "Waiting for the Nitro node to initialize..." -sleep 15 # Adjust the sleep time if necessary based on node startup time - -# Check if node is running -curl_output=$(curl -s -X POST -H "Content-Type: application/json" \ - --data '{"jsonrpc":"2.0","method":"net_version","params":[],"id":1}' \ - http://127.0.0.1:8547) - -if [[ "$curl_output" == *"result"* ]]; then - echo "Nitro node is running!" -else - echo "Failed to start Nitro node." - exit 1 -fi - -echo "Deploying Cache Manager contract..." -cast send --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 \ ---rpc-url http://127.0.0.1:8547 \ ---create 0x60a06040523060805234801561001457600080fd5b50608051611d1c61003060003960006105260152611d1c6000f3fe60806040526004361061011f5760003560e01c8063b187bd26116100a0578063c77ed13e11610064578063c77ed13e14610353578063cadb43e214610373578063d29b303e14610393578063e4940157146103b3578063e9c1bc0f146103c657600080fd5b8063b187bd261461027c578063b30906d4146102ad578063bae6c2ad146102f9578063c1c013c414610320578063c565a2081461033357600080fd5b806354fac919116100e757806354fac919146101de5780635c32e9431461021d5780635c975abb14610232578063674a64e014610247578063a8d6fe041461026757600080fd5b806317be85c31461012457806320f2f3451461014f5780632dd4f5661461017157806332052a9b146101915780633f4ba83a146101c9575b600080fd5b34801561013057600080fd5b506101396103e6565b6040516101469190611a2c565b60405180910390f35b34801561015b57600080fd5b5061016f61016a366004611ab3565b610473565b005b34801561017d57600080fd5b5061016f61018c366004611ae6565b6105f9565b34801561019d57600080fd5b506101b16101ac366004611b16565b6106d3565b6040516001600160c01b039091168152602001610146565b3480156101d557600080fd5b5061016f6106ee565b3480156101ea57600080fd5b5060035461020590600160801b90046001600160401b031681565b6040516001600160401b039091168152602001610146565b34801561022957600080fd5b5061016f6107aa565b34801561023e57600080fd5b5061016f610847565b34801561025357600080fd5b50600354610205906001600160401b031681565b34801561027357600080fd5b5061016f610909565b34801561028857600080fd5b5060035461029d90600160c01b900460ff1681565b6040519015158152602001610146565b3480156102b957600080fd5b506102cd6102c8366004611b33565b6109d4565b604080519384526001600160401b0390921660208401526001600160c01b031690820152606001610146565b34801561030557600080fd5b5060035461020590600160401b90046001600160401b031681565b61020561032e366004611ae6565b610a1d565b34801561033f57600080fd5b506101b161034e366004611b33565b610ab6565b34801561035f57600080fd5b5061016f61036e366004611ae6565b610ac4565b34801561037f57600080fd5b5061016f61038e366004611b33565b610ba3565b34801561039f57600080fd5b506101b16103ae366004611ae6565b610c7a565b61016f6103c1366004611b16565b610e5f565b3480156103d257600080fd5b506101396103e1366004611b33565b610ef0565b60606002805480602002602001604051908101604052809291908181526020016000905b8282101561046a5760008481526020908190206040805160608101825260028602909201805483526001908101546001600160401b03811684860152600160401b90046001600160c01b031691830191909152908352909201910161040a565b50505050905090565b600054610100900460ff1661048e5760005460ff1615610492565b303b155b6104fa5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b600054610100900460ff1615801561051c576000805461ffff19166101011790555b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036105a95760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b60648201526084016104f1565b600380546001600160401b03848116600160801b0277ffffffffffffffff0000000000000000ffffffffffffffff199092169086161717905580156105f4576000805461ff00191690555b505050565b6040516304ddefed60e31b8152606b906326ef7f689061061d903390600401611b4c565b602060405180830381865afa15801561063a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065e9190611b60565b61067d5733604051639531eff160e01b81526004016104f19190611b4c565b6003805467ffffffffffffffff19166001600160401b0383169081179091556040519081527fca22875e098f3b9c06ff3950c0cded621c968253a16623e890165451094c1839906020015b60405180910390a150565b60006106e8826001600160a01b03163f610ab6565b92915050565b6040516304ddefed60e31b8152606b906326ef7f6890610712903390600401611b4c565b602060405180830381865afa15801561072f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107539190611b60565b6107725733604051639531eff160e01b81526004016104f19190611b4c565b6003805460ff60c01b191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b6040516304ddefed60e31b8152606b906326ef7f68906107ce903390600401611b4c565b602060405180830381865afa1580156107eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080f9190611b60565b61082e5733604051639531eff160e01b81526004016104f19190611b4c565b610839600019610ba3565b610845600260006119f1565b565b6040516304ddefed60e31b8152606b906326ef7f689061086b903390600401611b4c565b602060405180830381865afa158015610888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ac9190611b60565b6108cb5733604051639531eff160e01b81526004016104f19190611b4c565b6003805460ff60c01b1916600160c01b1790556040517f6985a02210a168e66602d3235cb6 -0x60806040526004361061004e5760003560e01c80633659cfe6146100655780634f1ef286146100855780635c60da1b146100985780638f283970146100c9578063f851a440146100e95761005d565b3661005d5761005b6100fe565b005b61005b6100fe565b34801561007157600080fd5b5061005b6100803660046106ed565b610118565b61005b610093366004610708565b61015f565b3480156100a457600080fd5b506100ad6101d0565b6040516001600160a01b03909116815260200160405180910390f35b3480156100d557600080fd5b5061005b6100e43660046106ed565b61020b565b3480156100f557600080fd5b506100ad610235565b61010661029b565b61011661011161033a565b610344565b565b610120610368565b6001600160a01b0316336001600160a01b03161415610157576101548160405180602001604052806000815250600061039b565b50565b6101546100fe565b610167610368565b6001600160a01b0316336001600160a01b031614156101c8576101c38383838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506001925061039b915050565b505050565b6101c36100fe565b60006101da610368565b6001600160a01b0316336001600160a01b03161415610200576101fb61033a565b905090565b6102086100fe565b90565b610213610368565b6001600160a01b0316336001600160a01b0316141561015757610154816103c6565b600061023f610368565b6001600160a01b0316336001600160a01b03161415610200576101fb610368565b606061028583836040518060600160405280602781526020016108076027913961041a565b9392505050565b6001600160a01b03163b151590565b6102a3610368565b6001600160a01b0316336001600160a01b031614156101165760405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b60006101fb6104f5565b3660008037600080366000845af43d6000803e808015610363573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b6103a48361051d565b6000825111806103b15750805b156101c3576103" - -# Keep the Nitro node running -echo "Cache Manager deployed. Nitro node is running..." -wait # Keep the script alive and the node running -``` - -### Step 2: Make the script executable - -After creating the file, make the script executable by running the following command: - -```bash -chmod +x run_nitro_with_cache_manager.sh -``` - -### Step 3: Run the script - -To run the script and start the Nitro `dev` node along with deploying the `Cache Manager`, use the following command: - -```bash -./run_nitro_with_cache_manager.sh +cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 --rpc-url http://127.0.0.1:8547 ``` -This script will: - -- Start the Nitro `dev` node in the background using Docker. -- Wait for the node to initialize. -- Deploy the `Cache Manager` contarct using the bytecode provided. -- Keep the node running for further interactions. +This step ensures that the dev account has ownership of the chain, which is necessary to register the `Cache Manager` as a WASM cache manager. -At the end of the process, you'll have the Nitro `dev` mode running with the Stylus `Cache Manager` deployed. You can now proceed to test and interact with your Stylus contracts in this environment, leveraging the deployed `Cache Manager` for added Stylus functionality. +At the end of the process, you'll have the Nitro `dev` mode running with the necessary components deployed. This environment is ready for testing and interacting with your contracts, including those written in Stylus, using the deployed `Cache Manager` to support enhanced functionality for Stylus-based smart contracts. From 4530e8ec59bee20daab7515a45d59627374c93f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 25 Oct 2024 11:40:06 -0700 Subject: [PATCH 72/99] Update arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md --- .../run-arbitrum-node/04-run-local-full-chain-simulation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md b/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md index b6d4af2cc..ede8fe566 100644 --- a/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md +++ b/arbitrum-docs/run-arbitrum-node/04-run-local-full-chain-simulation.md @@ -9,7 +9,7 @@ content_type: how-to ## Overview -A local full chain simulation allows you to deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of setting up and running a complete development environment on your local machine, including a Nitro node, a dev-mode Geth L1, and multiple instances with different roles +A local full-chain simulation allows you to deploy and test smart contracts in a fully controlled environment. This how-to walks you through the process of setting up and running a complete development environment on your local machine, including a Nitro node, a dev-mode Geth L1, and multiple instances with different roles. Note that the node is now Stylus-enabled by default, and the setup instructions remain the same as for running a Stylus dev node. From 6a6e428c3d2730b88d66e910457fc470f383c02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 25 Oct 2024 11:43:24 -0700 Subject: [PATCH 73/99] Update arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx --- .../run-arbitrum-node/run-nitro-dev-node.mdx | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 292e58b33..357999133 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -32,21 +32,11 @@ Before beginning, ensure the following is installed and running on your machine: ## Clone the [nitro-devnode](https://github.com/OffchainLabs/nitro-devnode) repository -use the following command to clone the repository: +Use the following command to clone the repository: -```bash +```shell git clone https://github.com/OffchainLabs/nitro-devnode.git cd nitro-devnode -``` - -## Make the script executable: - -Ensure the script has executable permissions: - -```bash -chmod +x run_dev_node.sh -``` - ## Run the dev node script: Run the script to start the Nitro dev node, deploy the Stylus `Cache Manager` contract, and register it as a WASM cache manager using the default development account: From 8ed44a602eabb3b49c9f9bd79cad33c8e1e08906 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 25 Oct 2024 11:44:23 -0700 Subject: [PATCH 74/99] Update arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx --- arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 357999133..83ffe9adc 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -41,10 +41,8 @@ cd nitro-devnode Run the script to start the Nitro dev node, deploy the Stylus `Cache Manager` contract, and register it as a WASM cache manager using the default development account: -```bash +```shell ./run_dev_node.sh -``` - The script will: - Start the Nitro dev node in the background using Docker. From 05d4a2e8169c56f7a095c48a01bda3fc804c7f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 25 Oct 2024 11:46:52 -0700 Subject: [PATCH 75/99] Update arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx --- arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 83ffe9adc..8b4290eda 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -72,7 +72,7 @@ Chain ownership is important because it allows the owner to perform certain crit The script automatically sets the chain owner to the pre-funded dev account before registering the `Cache Manager` contract. Here’s how the `becomeChainOwner()` function is called within the script: -```bash +```shell cast send 0x00000000000000000000000000000000000000FF "becomeChainOwner()" --private-key 0xb6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 --rpc-url http://127.0.0.1:8547 ``` From 9bd17b7547f1093a6e1dc3dd4db2abe3ef534f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 25 Oct 2024 11:50:48 -0700 Subject: [PATCH 76/99] Update arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx --- arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 8b4290eda..a2a652327 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -20,7 +20,7 @@ While some teams use `nitro-testnode` for testing cross-layer messaging, which i However, if you need more advanced functionality—such as cross-layer messaging, working with both L1 and L2 chains, or testing interactions between different layers—`nitro-testnode` is the preferred option. The testnode setup allows you to simulate a full L1-L2 environment, which is critical for those scenarios. See here for instructions. -Note that Nitro `--dev` mode is particularly ideal for Stylus contract testing, as it is much lighter and faster to set up compared to the full nitro-testnode environment. +Note that Nitro `--dev` mode is ideal for Stylus contract testing, as it is much lighter and faster to set up than the full nitro-testnode environment. ## Prerequisites From e34e0f7af6a10239246e4158f242b693cf01cbbd Mon Sep 17 00:00:00 2001 From: Derek Lee <103802618+leeederek@users.noreply.github.com> Date: Mon, 28 Oct 2024 00:09:56 -0400 Subject: [PATCH 77/99] apply some commits to address pepper's comments --- .../bold/concepts/bold-technical-deep-dive.md | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index f4a41730e..0d5393f4a 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -16,7 +16,7 @@ import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_ ## Overview -Arbitrum's current dispute protocol involves defending against challengers individually in a 1-vs-1 tournament setting. In contrast, BoLD enables an all-vs-all battle royale between Good and Evil categories, with a single winner always determined. +Arbitrum's current dispute protocol involves defending against challengers individually in a 1-vs-1 tournament setting. In contrast, BoLD enables an all-vs-all battle royale between Good and Evil, with a single winner always determined. This dynamic is made possible by BoLD's time-bounded, permissionless validation using deterministic Merkle proofs and hashes. This allows any party to bond in the correct state and prove their claim through interactive fraud proofs, ensuring that a single honest party bonding in the correct state will always prevail in disputes. Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. @@ -36,11 +36,11 @@ The current implementation of BoLD involves both on-chain and off-chain componen ### Key terminology - **Arbitrum rollup contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made. -- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “challenge-bonds” each time. -- **Validating bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed. -- **Fraud proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. -- **Challenge protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's rollup contracts. -- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn. +- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires posting smaller "challenge bonds". +- **Validating bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed. +- **Fraud proofs:** Proofs that prove or disprove that an invalid state transition has taken place. These proofs are generated by challenge participants and are submitted to a chain's parent chain. For example, Arbitrum Rollups that settle onto Ethereum will have their proofs submitted to Ethereum and verified via a smart contract. In this case, these proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. +- **Challenge protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that will confirm a challenge winner in Arbitrum's rollup contracts once the challenge period has elapsed. +- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. When an assertion is confirmed, the associated bonded funds can be withdrawn. - **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and who may want to participate in creating assertions, confirming assertions, and/or challenging invalid assertions if they exist. More specifically, this entity must run an Arbitrum full node in `MakeNodes`, `Defensive`, `StakeLatest`, or `ResolveNodes` mode as described in the [How to run a validator](https://docs.arbitrum.io/run-arbitrum-node/more-types/run-validator-node). Note that there must always be an active proposer to advance the chain and who will need to run a validator in `MakeNodes` mode. - **Challenge period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. - **Edge:** Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. @@ -58,7 +58,7 @@ A helpful mental model for understanding the system is that it uses Ethereum its _From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period has elapsed and nobody has challenged their validity on Ethereum._ -In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contract](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol) to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. +In effect, there is a miniature Arbitrum state-transition VM [deployed as an Ethereum smart contract](https://github.com/OffchainLabs/nitro-contracts/blob/main/src/osp/OneStepProofEntry.sol) to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. All actors in the protocol have a local state from which they can produce valid proofs, and all honest parties will have the same local state. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth. @@ -77,7 +77,7 @@ All actors in the protocol have a local state from which they can produce valid - **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. - **Validator client:** A validator client is software that knows the correct history of the Arbitrum L2 chain via a state manager backend and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participating in challenging those it disagrees with. In BoLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. -- **Challenge manager client:** Software that can manage the life cycles of challenges a validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. This and the validator's responsibilities can be coupled into a single binary. +- **Challenge manager client:** Software that can manage the life cycles of challenges that an active validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. ### Assertions @@ -99,7 +99,7 @@ Assertions form a chain in which there can be forks. For instance, a validator m #### Overflow assertions -Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up overflow assertion needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. +Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, one or more follow-up overflow assertions needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. #### Trustless bonding pools @@ -117,11 +117,11 @@ and make moves on challenges without sacrificing decentralization. ### Opening challenges -To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on the parent chain. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet and for Arbitrum One and Arbitrum Nova). This bond is much lower than the one required to become an assertion poster. +To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on the parent chain. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet and for Arbitrum One and Arbitrum Nova). This bond is much lower than the one required to become an assertion proposer. Anyone can open a challenge on an assertion without needing to be a bonder in the Rollup contract, so long as they post a challenge bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate. -Recall that a challenge is a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BoLD protocol allows them to interactively narrow down their disagreement via cryptographic proofs such that Ethereum can be the final referee and claim a winner. +Recall that a challenge is a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BoLD protocol allows them to interactively narrow down their disagreement via fraud proofs such that Ethereum can be the final referee and claim a winner. At its core, the disagreement between validators looks something like this: @@ -133,19 +133,19 @@ At its core, the disagreement between validators looks something like this: Their disagreement is about an Arbitrum block somewhere between batch 5 and batch 10. Here’s how the actual challenge begins in this example: -Validators have to fetch all blocks between batch 5 and batch 10 and create a Merkle commitment out of them as a Merkle tree with 2^26 leaves. If there are fewer than 2^26 blocks in between the assertions, the last block is repeated to pad the leaves of the tree to that value. Validators then create an “edge” data structure, which contains the following fields: +Validators have to fetch all blocks between batch 5 and batch 10 and create a Merkle commitment out of them as a Merkle tree with 2^26+1 leaves. If there are fewer than 2^26 blocks in between the assertions, the last block is repeated to pad the leaves of the tree to that value. Validators then create an “edge” data structure, which contains the following fields: - **start_hash:** the start hash of the block from the common parent assertion -- **end_hash:** the end hash of the block at the claimed child assertion +- **end_hash:** the end hash of the last block in the child assertion that a validator claims is correct. - **merkle_root:** the Merkle root that results from committing to a Merkle tree from the start block hash to the end block hash -- **inclusion_proofs:** Merkle proofs that the start and end hashes are indeed leaves of the Merkle tree committing to a root +- **inclusion_proofs:** Merkle proofs that the end hashes are indeed leaves of the Merkle tree committing to a root The concept of a history commitment is at the core of challenges and BoLD itself. -The validators above provide a Merkle proof of their commitment to some history. In this case, all the Arbitrum block hashes from batch 5 to batch 10. Using this tree, validators can narrow their disagreement to a single block using Merkle proofs. +The validators above provide a Merkle proof of their commitment to some history. In this case, all the Arbitrum block hashes from batch 5 to batch 10. Using this tree, validators can narrow their disagreement to a single block using Merkle proofs by iteratively bisecting the set of leaves and creating sub-challenge edges which have their own history commitments to each half of the tree. ### Challenge resolution @@ -175,10 +175,10 @@ A validator can make a move on an edge as long as that edge is “rivaled”. Th The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^42. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 4.35Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^42 hashes that we call "subchallenges" that can be viewed as "phases" of the dispute resolution process. -As a reminder, the bisection game is an iterative process. The first subchallenge is at the block level and is where validators disagree over Arbitrum blocks between two assertions. The disagreeing validators)create “edges” containing history commitments to all the blocks in between those two assertions, which is a max of 2^26 L2 blocks, and commence the bisection game. As they progressively narrow down to a single block of disagreement, the validators then begin the next phase of the challenge process by opening a subchallenge over a maximum subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over a maximum of 2^23 SmallSteps, which are each a single step of WASM execution. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. +As a reminder, the bisection game is an iterative process. The first subchallenge is at the block level and is where validators disagree over Arbitrum blocks between two assertions. The disagreeing validators)create “edges” containing history commitments to all the blocks in between those two assertions, which is a max of 2^26 L2 blocks, and commence the bisection game. As they progressively narrow down to a single block of disagreement, the validators then begin the next phase of the challenge process by opening a subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over a maximum of 2^23 SmallSteps, which are each a single step of WASM execution. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. #### One step proof -Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is a proof of `WASM` execution showing that executing the Arbitrum state transition function at hash A leads to hash B. The parent chain, like Ethereum is for Arbitrum One, then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. +Once validators reach a single step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is a fraud proof of `WASM` execution showing that executing the Arbitrum state transition function at machine hash A leads to machine hash B. The parent chain, like Ethereum is for Arbitrum One, then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. #### Timers @@ -194,7 +194,7 @@ An edge's "inherited timer" value exists on-chain and can be updated via a trans #### Confirmation -Once an edge has a total on-chain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed on-chain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed. +Once an edge has a total on-chain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed on-chain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed by time. ### Bonding in challenges @@ -202,9 +202,8 @@ To create a challenge, there must be a fork in the Arbitrum assertion chain smar Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the -economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the -actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between -honest and evil parties to discourage spam. +[Economics of Disputes](https://docs.arbitrum.io/how-arbitrum-works/bold/bold-economics-of-disputes), which also explains the cost profile and spam prevention in BoLD. In short, the +actual cost of a bond encompasses many costs associated with participating in the dispute game. More information on the bond sizes and how they were calculated can be found in the [Economics of Disputes](https://docs.arbitrum.io/how-arbitrum-works/bold/bold-economics-of-disputes) document mentioned above. Each subchallenge that is created requires depositing a challenge bond. For Arbitrum One, the first unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol while all confiscated bonds are sent to the ArbitrumDAO treasury. It is important to not offer the majority of the bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks in self-challenges or to discourage needless competition between honest parties. From 1d1c252cb3b3d30ca9541f415fb7d1773ea1bfa3 Mon Sep 17 00:00:00 2001 From: Derek Lee <103802618+leeederek@users.noreply.github.com> Date: Mon, 28 Oct 2024 00:46:36 -0400 Subject: [PATCH 78/99] second round of commits to address Pepper's feedback --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 0d5393f4a..fbba20fd4 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -44,6 +44,7 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and who may want to participate in creating assertions, confirming assertions, and/or challenging invalid assertions if they exist. More specifically, this entity must run an Arbitrum full node in `MakeNodes`, `Defensive`, `StakeLatest`, or `ResolveNodes` mode as described in the [How to run a validator](https://docs.arbitrum.io/run-arbitrum-node/more-types/run-validator-node). Note that there must always be an active proposer to advance the chain and who will need to run a validator in `MakeNodes` mode. - **Challenge period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. - **Edge:** Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. +- **Timers:** Each unrivaled edge (that is, an edge without another competing edge) will have a timer that _ticks up_. Time in the protocol is measured using L1 blocks and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. Most importantly, timers are used to confirm assertions when an unrivaled edge's timer, and associated assertion, reaches the specified challenge period. - **Delay attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation. - **Permissionless validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. - **Validator software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. @@ -163,11 +164,11 @@ To narrow down a disagreement, validators have to figure out what exact hash the For instance: -Alice commits to 32 hashes with start = A, end = B +Alice commits to 33 hashes with start = A, end = B -Bob commits to 32 hashes with start = A, end = B’ +Bob commits to 33 hashes with start = A, end = B’ -Either of them can perform a “bisection” move on their edge. For instance, if Alice “bisects” her edge E, the bisection transaction will produce two children, E_1 and E_2. E_1 commits to 16 hashes from height A to B/2, and E_2 commits to 16 hashes from height B/2 to B. +Either of them can perform a “bisection” move on their edge. For instance, if Alice “bisects” her edge E, the bisection transaction will produce two children, E_1 and E_2. E_1 commits to 17 hashes from height A to B/2, and E_2 commits to 17 hashes from height B/2 to B. A validator can make a move on an edge as long as that edge is “rivaled”. That is, the children just created due to Alice’s bisection will have increasing timers until Bob also bisects and possibly creates rivals for Alice’s edges. From acc4e3375f413be01559acef94db8acc46d87e6d Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Mon, 28 Oct 2024 14:04:05 +0900 Subject: [PATCH 79/99] additional polish --- .../bold/concepts/bold-technical-deep-dive.md | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index fbba20fd4..aeaac055e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -44,7 +44,7 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and who may want to participate in creating assertions, confirming assertions, and/or challenging invalid assertions if they exist. More specifically, this entity must run an Arbitrum full node in `MakeNodes`, `Defensive`, `StakeLatest`, or `ResolveNodes` mode as described in the [How to run a validator](https://docs.arbitrum.io/run-arbitrum-node/more-types/run-validator-node). Note that there must always be an active proposer to advance the chain and who will need to run a validator in `MakeNodes` mode. - **Challenge period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. - **Edge:** Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. -- **Timers:** Each unrivaled edge (that is, an edge without another competing edge) will have a timer that _ticks up_. Time in the protocol is measured using L1 blocks and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. Most importantly, timers are used to confirm assertions when an unrivaled edge's timer, and associated assertion, reaches the specified challenge period. +- **Timers:** Each unrivaled edge (that is, an edge without another competing edge) will have a timer that _ticks up_. Time in the protocol is measured using L1 blocks and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. Most importantly, timers are used to confirm assertions when an unrivaled edge's timer, and associated assertion, reaches the specified challenge period. See the section on [Timers](./bold-technical-deep-dive.md#timers) for more details. - **Delay attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation. - **Permissionless validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. - **Validator software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. @@ -70,17 +70,16 @@ All actors in the protocol have a local state from which they can produce valid - **OneStepProver:** A set of contracts that implement a miniature `WASM` VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the `OSP` contracts are needed for BoLD. -**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the specifications section. +- **Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the specifications section. ### Off-chain components - **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the on-chain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers. - - **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. - **Validator client:** A validator client is software that knows the correct history of the Arbitrum L2 chain via a state manager backend and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participating in challenging those it disagrees with. In BoLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. - **Challenge manager client:** Software that can manage the life cycles of challenges that an active validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. -### Assertions +## Assertions A key responsibility for Arbitrum proposers is to regularly post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions (and are sometimes called L2 state roots). Assertions contain information, most critically: @@ -170,13 +169,14 @@ Bob commits to 33 hashes with start = A, end = B’ Either of them can perform a “bisection” move on their edge. For instance, if Alice “bisects” her edge E, the bisection transaction will produce two children, E_1 and E_2. E_1 commits to 17 hashes from height A to B/2, and E_2 commits to 17 hashes from height B/2 to B. -A validator can make a move on an edge as long as that edge is “rivaled”. That is, the children just created due to Alice’s bisection will have increasing timers until Bob also bisects and possibly creates rivals for Alice’s edges. +A validator can make a move on an edge as long as that edge is “rivaled”. That is, the children just created due to Alice’s bisection will have increasing timers until Bob also bisects and possibly creates rivals for Alice’s edges (see [timers](./bold-technical-deep-dive.md#timers) for more details). #### Subchallenges The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^42. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 4.35Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^42 hashes that we call "subchallenges" that can be viewed as "phases" of the dispute resolution process. -As a reminder, the bisection game is an iterative process. The first subchallenge is at the block level and is where validators disagree over Arbitrum blocks between two assertions. The disagreeing validators)create “edges” containing history commitments to all the blocks in between those two assertions, which is a max of 2^26 L2 blocks, and commence the bisection game. As they progressively narrow down to a single block of disagreement, the validators then begin the next phase of the challenge process by opening a subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over a maximum of 2^23 SmallSteps, which are each a single step of WASM execution. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. +As a reminder, the bisection game is an iterative process. The first subchallenge is at the block level and is where validators disagree over Arbitrum blocks between two assertions. The disagreeing validators) create “edges” containing history commitments to all the blocks in between those two assertions, which is a max of 2^26 L2 blocks, and commence the bisection game. As they progressively narrow down to a single block of disagreement, the validators then begin the next phase of the challenge process by opening a subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over a maximum of 2^23 SmallSteps, which are each a single step of WASM execution. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. + #### One step proof Once validators reach a single step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is a fraud proof of `WASM` execution showing that executing the Arbitrum state transition function at machine hash A leads to machine hash B. The parent chain, like Ethereum is for Arbitrum One, then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. @@ -203,16 +203,14 @@ To create a challenge, there must be a fork in the Arbitrum assertion chain smar Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the -[Economics of Disputes](https://docs.arbitrum.io/how-arbitrum-works/bold/bold-economics-of-disputes), which also explains the cost profile and spam prevention in BoLD. In short, the -actual cost of a bond encompasses many costs associated with participating in the dispute game. More information on the bond sizes and how they were calculated can be found in the [Economics of Disputes](https://docs.arbitrum.io/how-arbitrum-works/bold/bold-economics-of-disputes) document mentioned above. +[Economics of Disputes](../../how-arbitrum-works/bold/bold-economics-of-disputes.md), which also explains the cost profile and spam prevention in BoLD. In short, the +actual cost of a bond encompasses many costs associated with participating in the dispute game. More information on the bond sizes and how they were calculated can be found in the [Economics of Disputes](../../how-arbitrum-works/bold/bold-economics-of-disputes.md) document mentioned above. Each subchallenge that is created requires depositing a challenge bond. For Arbitrum One, the first unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol while all confiscated bonds are sent to the ArbitrumDAO treasury. It is important to not offer the majority of the bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks in self-challenges or to discourage needless competition between honest parties. ### Reimbursements of bonds -It is important to emphasize that the reimbursement of assertion bonds and challenge bonds for honest parties will be handled “in-band” by the protocol. While reimbursing honest parties for gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum Foundation. There will be a procedure, to be published later, that can be followed to calculate the reimbursements for gas costs to honest parties. - -Lastly, reimbursement will not be made for off-chain compute costs as we view these as costs borne by the operator, alongside the maintenance and infra costs that regularly arise from running a node. It is also difficult to attribute computation, as honest validators that are not necessarily posting claims would still perform similar computations if they are following a challenge. However, the costs of the on-chain bonds to participate in challenges far exceed the cost of compute required to resolve these challenges. +The reimbursement of assertion bonds and challenge bonds for honest parties will be handled “in-band” by the protocol. Please see [Economics of Disputes](../../how-arbitrum-works/bold/bold-economics-of-disputes.md) for more information about this topic. ### Upgrade mechanism From 6d274d5a8a2cf80519828f110b04a96bc14d7ac9 Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Mon, 28 Oct 2024 19:49:05 +0900 Subject: [PATCH 80/99] address a few other comments --- .../bold/concepts/bold-technical-deep-dive.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index aeaac055e..bbb1e0e99 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -87,19 +87,19 @@ A key responsibility for Arbitrum proposers is to regularly post claims about th 2. The batch number it corresponds to for the Arbitrum chain -3. The number of messages in the Arbitrum inbox at the time the assertion was posted on-chain +3. The number of messages in the Arbitrum seqiemcer inbox at the time the assertion was posted on-chain -The following assertion to be posted on-chain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to equal 1 hour for BoLD. +The following assertion to be posted on-chain must consume the specified number of inbox messages from the previous assertion. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to equal 1 hour for BoLD. Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion on-chain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. Validators must become proposers in the Rollup contract before being allowed to post assertions. For Arbitrum One and Arbitrum Nova, this involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. -Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the Rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree on the history committment of block state hashes, which an assertion contains. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the Rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. #### Overflow assertions -Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, one or more follow-up overflow assertions needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. +Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since the previous assertion. If this value is overflowed, one or more follow-up overflow assertions needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. #### Trustless bonding pools @@ -135,7 +135,7 @@ Their disagreement is about an Arbitrum block somewhere between batch 5 and batc Validators have to fetch all blocks between batch 5 and batch 10 and create a Merkle commitment out of them as a Merkle tree with 2^26+1 leaves. If there are fewer than 2^26 blocks in between the assertions, the last block is repeated to pad the leaves of the tree to that value. Validators then create an “edge” data structure, which contains the following fields: -- **start_hash:** the start hash of the block from the common parent assertion +- **start_hash:** the start_hash of the claimed assertion and is also the end_hash of the previous assertion - **end_hash:** the end hash of the last block in the child assertion that a validator claims is correct. @@ -187,7 +187,7 @@ Once a validator creates an edge, and if it does not have any rival edge contest Edges also have an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge's children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, its assertion can also be confirmed as its associated challenge has completed. A minor but important detail is that edges also inherit the time their claimed assertion was unrivaled. -We believe timer inheritance from ancestor edges is fundamentally broken. Honest edges could have evil ancestors or vice versa, and edges could steal/claim timer credit from others to which they should not be entitled. The [research specification](https://arxiv.org/abs/2404.10491) goes in-depth into the proven lemmas of timer inheritance and why children's inheritance solves critical attack vectors. +Feel free to read the [BoLD whitepaper](https://arxiv.org/abs/2404.10491) for more details around how timers are tracked. #### Cached timer updates @@ -199,7 +199,7 @@ Once an edge has a total on-chain timer greater than or equal to a challenge per ### Bonding in challenges -To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. +To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the previous assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the From 1cef2ca672f1dce4c7d885a4334ae0c863133c42 Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Mon, 28 Oct 2024 20:46:01 +0900 Subject: [PATCH 81/99] change point 3 under assertions section --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index bbb1e0e99..5977ff099 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -87,7 +87,7 @@ A key responsibility for Arbitrum proposers is to regularly post claims about th 2. The batch number it corresponds to for the Arbitrum chain -3. The number of messages in the Arbitrum seqiemcer inbox at the time the assertion was posted on-chain +3. The number of messages in the Arbitrum sequencer inbox at the time the assertion is created The following assertion to be posted on-chain must consume the specified number of inbox messages from the previous assertion. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to equal 1 hour for BoLD. From 0c5158d3d1592e0b2383f9760f94d72739aa5398 Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Mon, 28 Oct 2024 12:45:16 -0400 Subject: [PATCH 82/99] Address review comments --- .../run-arbitrum-node/01-overview.md | 2 +- .../run-arbitrum-node/run-nitro-dev-node.mdx | 12 ++-------- arbitrum-docs/stylus/stylus-quickstart.md | 23 ++++++++----------- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/arbitrum-docs/run-arbitrum-node/01-overview.md b/arbitrum-docs/run-arbitrum-node/01-overview.md index 7ad0ae69f..8210d8795 100644 --- a/arbitrum-docs/run-arbitrum-node/01-overview.md +++ b/arbitrum-docs/run-arbitrum-node/01-overview.md @@ -11,7 +11,7 @@ In order to be able to _interact with_ or _build applications on_ any of the Arb Here, you can find resources that help you run different types of Arbitrum nodes: -- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) +- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md), [Nitro dev node](/run-arbitrum-node/more-types/run-nitro-dev-node.mdx), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) - Step-by-step instructions for how to [read the sequencer feed](/run-arbitrum-node/sequencer/02-read-sequencer-feed.md), [build the Nitro locally](/run-arbitrum-node/nitro/01-build-nitro-locally.md) and [run the sequencer coordinator manager UI tool](/run-arbitrum-node/sequencer/03-run-sequencer-coordination-manager.md) - Step-by-step instructions for [how to configure a Data Availability Committee](/run-arbitrum-node/data-availability-committees/01-get-started.md) - [Troubleshooting page](/run-arbitrum-node/06-troubleshooting.md) diff --git a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx index 292e58b33..2c03b7d5f 100644 --- a/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx +++ b/arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx @@ -28,7 +28,7 @@ Before beginning, ensure the following is installed and running on your machine: - Docker: Required to run the Nitro dev node in a container. Install Docker by following [the official installation guide](https://docs.docker.com/get-started/get-docker/) for your operating system. - cast: A command-line tool from Foundry for interacting with Ethereum smart contracts. You can install it via Foundry by following [the installation instructions](https://book.getfoundry.sh/getting-started/installation). -- jq: A lightweight JSON parsing tool used to extract contract addresses from the script output. +- jq: A lightweight JSON parsing tool used to extract contract addresses from the script output. Install jq by following [the official installation guide](https://jqlang.github.io/jq/download/) for your operating system. ## Clone the [nitro-devnode](https://github.com/OffchainLabs/nitro-devnode) repository @@ -39,20 +39,12 @@ git clone https://github.com/OffchainLabs/nitro-devnode.git cd nitro-devnode ``` -## Make the script executable: - -Ensure the script has executable permissions: - -```bash -chmod +x run_dev_node.sh -``` - ## Run the dev node script: Run the script to start the Nitro dev node, deploy the Stylus `Cache Manager` contract, and register it as a WASM cache manager using the default development account: ```bash -./run_dev_node.sh +./run-dev-node.sh ``` The script will: diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md index 270bbe357..dc1f9ba39 100644 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -50,23 +50,18 @@ You can download Docker from [Docker’s website](https://www.docker.com/product [Foundry's Cast](https://book.getfoundry.sh/cast/) is a command-line tool that allows you to interact with your EVM contracts. -#### Nitro testnode +#### Nitro devnode -Stylus is available on Arbitrum Sepolia, but we'll use nitro testnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. +Stylus is available on Arbitrum Sepolia, but we'll use nitro devnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. -```shell title="Install your testnode" -git clone -b release --recurse-submodules https://github.com/OffchainLabs/nitro-testnode.git && cd nitro-testnode -``` - -```shell title="Launch your testnode" -./test-node.bash --init -``` +````shell title="Run the devnode" +git clone https://github.com/OffchainLabs/nitro-devnode.git +cd nitro-devnode +`` -The initialization part might take up to a few minutes, but you can move on to the next section while it launches. - -```shell title="Re-use your testnode" -./test-node.bash -``` +```shell title="Launch your devnode" +./run-dev-node.sh +```` ## Creating a Stylus project with cargo stylus From 02db5b69b0794787bc058085b1e03e7852a0e36d Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Mon, 28 Oct 2024 12:50:43 -0400 Subject: [PATCH 83/99] Small updates --- arbitrum-docs/stylus/stylus-quickstart.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md index dc1f9ba39..b774ec58f 100644 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -54,14 +54,14 @@ You can download Docker from [Docker’s website](https://www.docker.com/product Stylus is available on Arbitrum Sepolia, but we'll use nitro devnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. -````shell title="Run the devnode" +```shell title="Run the devnode" git clone https://github.com/OffchainLabs/nitro-devnode.git cd nitro-devnode -`` +``` ```shell title="Launch your devnode" ./run-dev-node.sh -```` +``` ## Creating a Stylus project with cargo stylus From cce1006f7cb0ff30daa27b9629acf427ce0b3315 Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Mon, 28 Oct 2024 12:54:43 -0400 Subject: [PATCH 84/99] Fix devnode URL in overview page --- arbitrum-docs/run-arbitrum-node/01-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/run-arbitrum-node/01-overview.md b/arbitrum-docs/run-arbitrum-node/01-overview.md index 8210d8795..a1252f9db 100644 --- a/arbitrum-docs/run-arbitrum-node/01-overview.md +++ b/arbitrum-docs/run-arbitrum-node/01-overview.md @@ -11,7 +11,7 @@ In order to be able to _interact with_ or _build applications on_ any of the Arb Here, you can find resources that help you run different types of Arbitrum nodes: -- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md), [Nitro dev node](/run-arbitrum-node/more-types/run-nitro-dev-node.mdx), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) +- Step-by-step instructions for running different Arbitrum nodes, including [full Nitro node](/run-arbitrum-node/03-run-full-node.md), [full Classic node](/run-arbitrum-node/more-types/03-run-classic-node.md), [local full chain simulation](/run-arbitrum-node/04-run-local-full-chain-simulation.md), [Nitro dev node](/run-arbitrum-node/run-nitro-dev-node.mdx), [feed relay](/run-arbitrum-node/sequencer/01-run-feed-relay.md), and [validator](/run-arbitrum-node/more-types/02-run-validator-node.md) - Step-by-step instructions for how to [read the sequencer feed](/run-arbitrum-node/sequencer/02-read-sequencer-feed.md), [build the Nitro locally](/run-arbitrum-node/nitro/01-build-nitro-locally.md) and [run the sequencer coordinator manager UI tool](/run-arbitrum-node/sequencer/03-run-sequencer-coordination-manager.md) - Step-by-step instructions for [how to configure a Data Availability Committee](/run-arbitrum-node/data-availability-committees/01-get-started.md) - [Troubleshooting page](/run-arbitrum-node/06-troubleshooting.md) From 79b1569788ef6ce7b921732e271485a6b4923273 Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Mon, 28 Oct 2024 17:36:12 -0400 Subject: [PATCH 85/99] Update arbitrum-docs/stylus/stylus-quickstart.md Co-authored-by: Joshua Colvin --- arbitrum-docs/stylus/stylus-quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md index b774ec58f..ff28f0766 100644 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -54,7 +54,7 @@ You can download Docker from [Docker’s website](https://www.docker.com/product Stylus is available on Arbitrum Sepolia, but we'll use nitro devnode which has a pre-funded wallet saving us the effort of wallet provisioning or running out of tokens to send transactions. -```shell title="Run the devnode" +```shell title="Install your devnode" git clone https://github.com/OffchainLabs/nitro-devnode.git cd nitro-devnode ``` From 12c9a67a4df3c2612a9b1674d52fae2e6ca472b9 Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Mon, 28 Oct 2024 19:41:08 -0700 Subject: [PATCH 86/99] Stylus does not currently support Rust 1.82 --- arbitrum-docs/stylus/stylus-quickstart.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/stylus-quickstart.md b/arbitrum-docs/stylus/stylus-quickstart.md index ff28f0766..14bc81736 100644 --- a/arbitrum-docs/stylus/stylus-quickstart.md +++ b/arbitrum-docs/stylus/stylus-quickstart.md @@ -27,7 +27,7 @@ This guide will get you started with Stylus' #### Rust toolchain -Follow the instructions on [Rust Lang’s installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. +Follow the instructions on [Rust Lang’s installation page](https://www.rust-lang.org/tools/install) to install a complete Rust toolchain (v1.81 or older, v1.82 is currently not supported) on your system. After installation, ensure you can access the programs `rustup`, `rustc`, and `cargo` from your preferred terminal application. #### VS Code From 95613f580f30d29626f362aec15d7b8f374afa39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 29 Oct 2024 15:00:27 -0700 Subject: [PATCH 87/99] fix: renamed "Why Nitro?" to "Nitro vs. Classic" + add to sidebar --- arbitrum-docs/how-arbitrum-works/why-nitro.md | 5 ++--- website/sidebars.js | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arbitrum-docs/how-arbitrum-works/why-nitro.md b/arbitrum-docs/how-arbitrum-works/why-nitro.md index 98f4c83f0..ab690c738 100644 --- a/arbitrum-docs/how-arbitrum-works/why-nitro.md +++ b/arbitrum-docs/how-arbitrum-works/why-nitro.md @@ -1,13 +1,12 @@ --- +title: Nitro vs. Classic author: dzgoldman --- -# Why Nitro? +Why Nitro? Nitro represents the latest step in the evolution of Arbitrum technology; it is an upgrade from the tech stack first released on the mainnet Arbitrum One chain, which we now refer to as “Arbitrum Classic” (and several steps beyond what was described in the [initial Arbitrum whitepaper back in 2018](https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-kalodner.pdf)). Here, we’ll explain the rationale behind the Nitro upgrade, and outline Nitro’s core benefits over the classic system. -### Nitro vs. Classic - Viewed from a distance, the Classic and Nitro systems do similar things: both seek to create an execution environment as close to the EVM as possible which operates as a second layer to Ethereum; i.e., safety of the L2 virtual machine’s state updates can be guaranteed and enforced via succinct fraud proofs on Ethereum itself. In Arbitrum Classic, this was achieved via a custom-made virtual machine, which we call the Arbitrum Virtual Machine (AVM). The implementation of Arbitrum’s L2 state machine—known as [“ArbOS”](/how-arbitrum-works/arbos/introduction.md) — is effectively a program that is compiled and uploaded to the AVM; ArbOS includes (among other things) the ability to emulate EVM execution. diff --git a/website/sidebars.js b/website/sidebars.js index b2212400c..ff6093612 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -820,11 +820,6 @@ const sidebars = { label: 'Introductory concepts', collapsed: true, items: [ - { - type: 'doc', - id: 'how-arbitrum-works/why-nitro', - label: 'Why Nitro?', - }, { type: 'doc', id: 'how-arbitrum-works/tx-lifecycle', @@ -878,6 +873,11 @@ const sidebars = { id: 'how-arbitrum-works/assertion-tree', label: 'Assertion tree', }, + { + type: 'doc', + id: 'how-arbitrum-works/why-nitro', + label: 'Nitro vs. Classic', + }, { type: 'category', label: 'Cross-chain messaging', From b5fe8b2fe1abfd21a1a33795ff49df6d49e67adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 29 Oct 2024 15:45:33 -0700 Subject: [PATCH 88/99] fix: remove third-party projects from glossary --- arbitrum-docs/partials/_glossary-partial.mdx | 116 ++++++------------- 1 file changed, 34 insertions(+), 82 deletions(-) diff --git a/arbitrum-docs/partials/_glossary-partial.mdx b/arbitrum-docs/partials/_glossary-partial.mdx index 1f268453e..424d1345c 100644 --- a/arbitrum-docs/partials/_glossary-partial.mdx +++ b/arbitrum-docs/partials/_glossary-partial.mdx @@ -1,5 +1,10 @@ +### 🧱 State Transition Function {#-state-transition-function} +

    +The STF (State Transition Function) defines how new blocks are produced from input messages (i.e. transactions) in an Arbitrum chain. +

    + ### Active Validator {#active-validator}

    A staked Validator that makes disputable assertions to advance the state of an Arbitrum chain or to challenge the validity of others' assertions. (Not to be confused with the Sequencer ). @@ -95,6 +100,16 @@ Arbitrum's "operating system" that trustlessly handles system-level operations; A staked claim by an Arbitrum Validator. An assertion may, e.g., propose a new RBlock, or may be a step in a Challenge.

    +### Auction Contract {#auction-contract} +

    +A smart contract that handles the state, accounting of funds for bids, and various operations of the Timeboost auction. The contract is deployed on the target chain for which Timeboost is enabled. +

    + +### Autonomous Auctioneer {#autonomous-auctioneer} +

    +Off chain software that receives bids from Timeboost participants, processes and validates bids, and then posts the top valid bid (or top two valid bids in the case of a tie) to the Auction Contract to resolve the on-going Timeboost auction. The autonomous auctioneer, for a given chain, is provisioned & deployed by an entity designated by the chain's owner. +

    + ### Batch {#batch}

    A group of Arbitrum transactions posted in a single transaction on the Underlying Chain into the Fast Inbox by the Sequencer. @@ -120,15 +135,6 @@ Short for "Bounded Liquidity Delay"; latest version of the Arbitrum Cross-chain messages between blockchains. Every Arbitrum chain includes a bridge to/from its Parent chain.

    -### 🧢 CAP Finance {#cap-finance} -

    -Widely considered the most degen community on Arbitrum. -
    - -
    -CAP is a decentralized trading protocol. It's designed to be fast and easy to use by anyone. -

    - ### Chain Owner {#chain-owner}

    An entity (i.e., a smart contract) with affordance to carry out critical upgrades to an Arbitrum chain's core protocol; this includes upgrading protocol contracts, setting core system parameters, and adding and removing other chain owners. @@ -221,15 +227,6 @@ Web application built and maintained by A step in the Challenge protocol in which two challenging parties interactively narrow down their disagreement until they reach a One Step Proof.

    -### 💎 Dopex {#dopex} -

    -A shiny gem in the Arbitrum community. -
    - -
    -Commonly associated with the esteemed Diamond Pepe's NFT and Dopex community. Dopex is a decentralized options exchange protocol on Arbitrum. -

    - ### ☕ Espresso {#espresso}

    Project partnering with Offchain Labs for research and development around Sequencer transaction ordering and Shared Sequencing technology. @@ -245,6 +242,16 @@ A software application used for transacting with the Ethereum Stylus in which Arbitrum's EVM compatibility is preserved while new features and improvements are introduced.

    +### Express Lane {#express-lane} +

    +A component of Timeboost, the express lane is a special endpoint on the Sequencer that immediately sequences incoming, valid transactions signed by the current express lane controller. +

    + +### Express Lane Controller {#express-lane-controller} +

    +An address, defined in the Auction Contract, that is granted the privilege to use the Express Lane. These privileges are granted after verifying that the incoming transactions were properly signed by the express lane controller, among other checks. +

    + ### Fair Ordering Algorithm {#fair-ordering-algorithm}

    BFT algorithm in which a committee comes to consensus on transaction ordering; current single-party Sequencer on Arbitrum may eventually be replaced by a fair-ordering committee. @@ -260,6 +267,11 @@ A means by which a user can bypass an Arbitrum chain's Sequencer or indirectly through the Delayed Inbox.

    +### First Come First Serve (FCFS) {#first-come-first-serve-fcfs} +

    +A type of Transaction Ordering Policy used by the sequencer in Arbitrum chains whereby incoming transactions are sequenced into a block in the order that the transactions arrived. +

    + ### Force-Inclusion {#forceinclusion}

    Censorship resistant path for including a message into an Arbitrum chain via the Delayed Inbox on its Parent chain; bypasses any Sequencer involvement. @@ -290,15 +302,6 @@ A particular Custom gateway via whi An execution-layer client that defines the Ethereum state transition function and handles network-layer logic like transaction memory pooling. Arbitrum Nitro utilizes a fork of Geth to implement Arbitrum's state transition function.

    -### 🫐 GMX {#gmx} -

    -If you've seen some blueberries wandering around on crypto Twitter, you might wonder .. where did they come from? -
    - -
    -The iconic blueberries come from the community of the decentralized exchange, GMX. -

    - ### Ink {#ink}

    The equivalent of gas in the Stylus vm. Ink is introduced for finer granularity than gas offers since Stylus's operations are considerably cheaper than their EVM analogs. @@ -418,15 +421,6 @@ A protocol design space in which multiple rollups use the same entity as their < A computer program whose operations are defined and executed within a blockchain consensus protocol.

    -### 🐵 Smolverse {#smolverse} -

    -Near the core of Arbitrum community is Smolverse, a world filled with Smol Brains and Smol Bodies. -
    - -
    -If you see any Smol's with giga brains, swole arms or hear the sound of "EEEE" in the Arbitrum community, you've encountered the Smol Brains and Smol Bodies. -

    - ### Soft Confirmation {#soft-confirmation}

    A semi-trusted promise from the Sequencer to post a user's transaction in the near future; soft-confirmations happen prior to posting on the Parent chain, and thus can be given near-instantaneously (i.e., faster than the parent chain's block times) @@ -457,29 +451,9 @@ An token contract on an Arbitrum chain deployed via the Arbitrum Nitro virtual machine that allows smart contract support for languages like Rust and C++ by taking advantage of Nitro's use of WASM. Currently on testnet (read more).

    -### 🏹 Tales of Elleria {#tales-of-elleria} -

    -The bow and arrow are commonly associated with the Hero's of Tales of Elleria. -
    - -
    -Jump into the world of Elleria and go on adventures. -

    - -### Time boost {#time-boost} +### Timeboost {#timeboost}

    -A proposed (not currently live) transaction policy in which users can pay a fee to the Sequencer for a small ordering advantage. See [here](https://medium.com/offchainlabs/time-boost-a-new-transaction-ordering-policy-for-arbitrum-5b3066382d62) for more. -

    - -### 🐸 Toadstoolz {#toadstoolz} -

    -Hidden in the Croakshire, you will find the friendly Toadstoolz. -
    - -
    -The iconic Toads of Arbitrum love to hunt BUGZ -
    - and collect NFTs. !CROAK +A transaction ordering policy in which entities can bid for the right to access an express lane on the Sequencer for faster transaction inclusion. See the research specification to learn more.

    ### Token Gateway {#token-gateway} @@ -487,27 +461,14 @@ The iconic Toads of Arbitrum love to hunt BUGZ A pair of contracts in the token bridge — one on the Parent chain , one on the Child chain — that provide a particular mechanism for handling the transfer of tokens between layers. Token gateways currently active in the bridge include the StandardERC20 gateway , the Generic-Custom Gateway , and the WETH Gateway.

    -### 🏡 TownStory {#townstory-} -

    -If you see some homes along your road trip in the Arbitrum ecosystem, you've made it to TownStory. -
    - -
    -Build a warm and prosperous town with friends in TownStory. -

    - ### Transaction {#transaction}

    A user-initiated interaction with a Blockchain. Transactions are typically signed by users via wallets and are paid for via transaction fees.

    -### ✨ Treasure DAO {#treasure-dao} +### Transaction Ordering Policy {#transaction-ordering-policy}

    -While exploring the Arbitrum ecosystem, you may see some shining stars. -
    - -
    -The iconic stars symbolize the magic of Treasure DAO. Treasure DAO is the decentralized gaming ecosystem connecting games and players on Arbitrum. +The rules and logic employed by a chain to order incoming transactions into a block.

    ### Trustless {#trustless} @@ -555,13 +516,4 @@ A Validator that never stakes / never t Token Gateway for handing the bridging of wrapped Ether (WETH). WETH is unwrapped on L1 and rewrapped on L1 upon depositing (and vice-versa upon withdrawing), ensuring WETH on L2 always remains collateralized.

    -### 👺 Zeeverse {#zeeverse} -

    -As you're exploring the Arbitrum world, you may bump into a world filled with monsters and Zee's. -
    - -
    -Explore a mythical Spirit Realm as a young Shaman and take part in strategic turn-based battles to help protect Zeeverse from the looming corrupted forces. -

    - From 60d99a99a42aea7ee65a52a4c40a03c4353ad9b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 29 Oct 2024 15:48:00 -0700 Subject: [PATCH 89/99] feat: update files based on notion data import --- .../_troubleshooting-nodes-partial.mdx | 2 +- .../_troubleshooting-orbit-partial.mdx | 3 +-- .../_troubleshooting-stylus-partial.mdx | 10 +--------- website/static/glossary.json | 20 +++++++++---------- website/static/node-running-faqs.json | 2 +- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/arbitrum-docs/partials/_troubleshooting-nodes-partial.mdx b/arbitrum-docs/partials/_troubleshooting-nodes-partial.mdx index 04b4d8f93..f688cc668 100644 --- a/arbitrum-docs/partials/_troubleshooting-nodes-partial.mdx +++ b/arbitrum-docs/partials/_troubleshooting-nodes-partial.mdx @@ -166,7 +166,7 @@ Keep in mind that this must be done after a clean shutdown, while the node is no ### When querying Classic transactions from a Nitro node, I sometimes get incorrect data, like the zero address as the sender. Why is that?

    -Some old Nitro genesis database snapshots didn't properly set the retry sender for Classic blocks and contain said error. If you need to access that information, you can either resync your nitro node with one of the current snapshots, or run a Classic node along with your nitro node and configure a redirection for requests to Classic blocks. Please note that this only happens on Arbitrum One. +Some old Nitro genesis database snapshots didn't properly set the retry sender for Classic blocks and contain said error. If you need to access that information, you can either resync your nitro node with one of the current snapshots, or run a Classic node along with your nitro node and configure a redirection for requests to Classic blocks. Please note that this only happens on Arbitrum One.

    diff --git a/arbitrum-docs/partials/_troubleshooting-orbit-partial.mdx b/arbitrum-docs/partials/_troubleshooting-orbit-partial.mdx index 6c8eecb5e..bd8c7358f 100644 --- a/arbitrum-docs/partials/_troubleshooting-orbit-partial.mdx +++ b/arbitrum-docs/partials/_troubleshooting-orbit-partial.mdx @@ -54,14 +54,13 @@ Yes, you can make any changes you require to the underlying Nitro code base. ### What Data Availability (DA) solutions are currently available for Orbit chains?

    -Arbitrum Orbit currently supports 4 different DA solutions: +Arbitrum Orbit currently supports 3 different DA solutions:

    • Rollup, posting data to the parent chain which ultimately posts the data to Ethereum.
    • AnyTrust, posting data to a Data Availability Committee, selected by the chain owner.
    • Celestia, posting data to Celestia network.
    • -
    • AvailDA, posting data to AvailDA.

    Note that using AnyTrust gives the chain owner the most flexibility and cheapest fees. diff --git a/arbitrum-docs/partials/_troubleshooting-stylus-partial.mdx b/arbitrum-docs/partials/_troubleshooting-stylus-partial.mdx index d98438bb7..92f712d59 100644 --- a/arbitrum-docs/partials/_troubleshooting-stylus-partial.mdx +++ b/arbitrum-docs/partials/_troubleshooting-stylus-partial.mdx @@ -107,16 +107,8 @@ As an alternative solution, you can use Arbitrum Node Upgrade Announcement channel on Telegram, join both the #dev-announcements and #node-runners Discord channels in the Arbitrum Discord server, and follow the official Arbitrum Arbitrum Developers X accounts. -

    -### Why do I get an error "no library targets found in package" when trying to compile an old example? +### Why do I get an error "no library targets found in package" when trying to compile and old example?

    Some of the first Stylus examples were built and deployed using a previous version of cargo-stylus (0.1.x). In that version, Stylus projects were structured as regular Rust binaries.

    diff --git a/website/static/glossary.json b/website/static/glossary.json index d87422759..ac48a3b49 100644 --- a/website/static/glossary.json +++ b/website/static/glossary.json @@ -1,4 +1,5 @@ { +"-state-transition-function":{"title":"🧱 State Transition Function","text":"

    \nThe STF (State Transition Function) defines how new blocks are produced from input messages (i.e. transactions) in an Arbitrum chain.\n

    "}, "active-validator":{"title":"Active Validator","text":"

    \nA staked Validator that makes disputable assertions to advance the state of an Arbitrum chain or to challenge the validity of others' assertions. (Not to be confused with the Sequencer ).\n

    "}, "address-alias":{"title":"Address Alias","text":"

    \nAn address deterministically generated from an L1 contract address used on L2 to safely identify the source of an L1 to L2 message.\n

    "}, "arb-token-bridge":{"title":"Arb Token Bridge","text":"

    \nA series of contracts on an Arbitrum chain and its underlying chain that facilitate trustless movement of ERC-20 tokens between the two layers.\n

    "}, @@ -18,12 +19,13 @@ "arbitrum-rollup-protocol":{"title":"Arbitrum Rollup Protocol","text":"

    \nA trustless, permissionless Arbitrum protocol that uses its underlying base layer for data availability and inherits its security. This protocol is implemented by our Arbitrum One chain. \n

    "}, "arbos":{"title":"ArbOS","text":"

    \nArbitrum's \"operating system\" that trustlessly handles system-level operations; includes the ability to emulate the EVM.\n

    "}, "assertion":{"title":"Assertion","text":"

    \nA staked claim by an Arbitrum Validator. An assertion may, e.g., propose a new RBlock, or may be a step in a Challenge.\n

    "}, +"auction-contract":{"title":"Auction Contract","text":"

    \nA smart contract that handles the state, accounting of funds for bids, and various operations of the Timeboost auction. The contract is deployed on the target chain for which Timeboost is enabled.\n

    "}, +"autonomous-auctioneer":{"title":"Autonomous Auctioneer","text":"

    \nOff chain software that receives bids from Timeboost participants, processes and validates bids, and then posts the top valid bid (or top two valid bids in the case of a tie) to the Auction Contract to resolve the on-going Timeboost auction. The autonomous auctioneer, for a given chain, is provisioned & deployed by an entity designated by the chain's owner.\n

    "}, "batch":{"title":"Batch","text":"

    \nA group of Arbitrum transactions posted in a single transaction on the Underlying Chain into the Fast Inbox by the Sequencer.\n

    "}, "blockchain":{"title":"Blockchain","text":"

    \nA distributed digital ledger that is used to record transactions and store data in a secure, transparent, and tamper-resistant way, notably in cryptocurrency protocols. \n

    "}, "bls-signature":{"title":"BLS Signature","text":"

    \nA cryptographic scheme that allows multiple signatures to be aggregated and compacted into one efficiently verifiable, constant-sized signature. Used in the Arbitrum AnyTrust Protocol for the Data Availability Committee (DAC)'s signatures.\n

    "}, "bold":{"title":"BoLD","text":"

    \nShort for \"Bounded Liquidity Delay\"; latest version of the Arbitrum Challenge protocol designed to eliminate delay attack vectors (see here for more). Not currently on mainnet. \n

    "}, "bridge":{"title":"Bridge","text":"

    \nA set of smart contracts for sending Cross-chain messages between blockchains. Every Arbitrum chain includes a bridge to/from its Parent chain. \n

    "}, -"cap-finance":{"title":"CAP Finance","text":"

    \nWidely considered the most degen community on Arbitrum.\n
    \n\n
    \nCAP is a decentralized trading protocol. It's designed to be fast and easy to use by anyone.\n

    "}, "chain-owner":{"title":"Chain Owner","text":"

    \nAn entity (i.e., a smart contract) with affordance to carry out critical upgrades to an Arbitrum chain's core protocol; this includes upgrading protocol contracts, setting core system parameters, and adding and removing other chain owners.\n

    "}, "chain-state":{"title":"Chain state","text":"

    \nA particular point in the history of an Arbitrum chain. A chain's state is determined by applying Arbitrum state-transition function to sequence of transactions (i.e., the chain's history).\n

    "}, "challenge":{"title":"Challenge","text":"

    \nWhen two Stakers disagree about the correct verdict on an Assertion, those stakers can be put in a challenge. The challenge is refereed by the contracts on the underlying chain. Eventually one staker wins the challenge. The protocol guarantees that an honest party will always win a challenge; the loser forfeits their stake. \n

    "}, @@ -42,20 +44,21 @@ "delayed-inbox":{"title":"Delayed Inbox","text":"

    \nA contract that holds Parent chain initiated messages to be eventually included in the Fast Inbox. Inclusion of messages doesn't depend on the Sequencer.\n

    "}, "devtools-dashboard":{"title":"Dev-Tools Dashboard","text":"

    \nWeb application built and maintained by Offchain Labs for developers and users to debug Arbitrum transactions; i.e., executing or checking the status of Cross-chain messages; visit it here. \n

    "}, "dissection":{"title":"Dissection","text":"

    \nA step in the Challenge protocol in which two challenging parties interactively narrow down their disagreement until they reach a One Step Proof.\n

    "}, -"dopex":{"title":"Dopex","text":"

    \nA shiny gem in the Arbitrum community.\n
    \n\n
    \nCommonly associated with the esteemed Diamond Pepe's NFT and Dopex community. Dopex is a decentralized options exchange protocol on Arbitrum.\n

    "}, "espresso":{"title":"Espresso","text":"

    \nProject partnering with Offchain Labs for research and development around Sequencer transaction ordering and Shared Sequencing technology. \n

    "}, "ethereum-wallet":{"title":"Ethereum Wallet","text":"

    \nA software application used for transacting with the Ethereum Blockchain.\n

    "}, "evm":{"title":"EVM+","text":"

    \nThe paradigm introduced by Stylus in which Arbitrum's EVM compatibility is preserved while new features and improvements are introduced.\n

    "}, +"express-lane":{"title":"Express Lane","text":"

    \nA component of Timeboost, the express lane is a special endpoint on the Sequencer that immediately sequences incoming, valid transactions signed by the current express lane controller. \n

    "}, +"express-lane-controller":{"title":"Express Lane Controller","text":"

    \nAn address, defined in the Auction Contract, that is granted the privilege to use the Express Lane. These privileges are granted after verifying that the incoming transactions were properly signed by the express lane controller, among other checks.\n

    "}, "fair-ordering-algorithm":{"title":"Fair Ordering Algorithm","text":"

    \nBFT algorithm in which a committee comes to consensus on transaction ordering; current single-party Sequencer on Arbitrum may eventually be replaced by a fair-ordering committee.\n

    "}, "fast-exit--liquidity-exit":{"title":"Fast Exit / Liquidity Exit","text":"

    \nA means by which a user can bypass an Arbitrum chain's Challenge Period when withdrawing fungible assets (or more generally, executing some \"fungible\" L2 to L1 operation); for trustless fast exits, a liquidity provider facilitates an atomic swap of the asset on L2 directly to L1.\n

    "}, "fast-inbox":{"title":"Fast Inbox","text":"

    \nContract that holds a sequence of messages sent by clients to an Arbitrum Chain; a message can be put into the fast Inbox directly by the Sequencer or indirectly through the Delayed Inbox.\n

    "}, +"first-come-first-serve-fcfs":{"title":"First Come First Serve (FCFS)","text":"

    \nA type of Transaction Ordering Policy used by the sequencer in Arbitrum chains whereby incoming transactions are sequenced into a block in the order that the transactions arrived.\n

    "}, "forceinclusion":{"title":"Force-Inclusion","text":"

    \nCensorship resistant path for including a message into an Arbitrum chain via the Delayed Inbox on its Parent chain; bypasses any Sequencer involvement.\n

    "}, "fraud-proof":{"title":"Fraud proof","text":"

    \nThe means by which an Active Validator proves to its underlying chain that an invalid state transition has taken place.\n

    "}, "gas-price-floor":{"title":"Gas Price Floor","text":"

    \nProtocol-enforced minimum gas price on an Arbitrum chain; currently 0.1 gwei on Arbitrum One and 0.01 gwei on Arbitrum Nova.\n

    "}, "gateway-router":{"title":"Gateway Router","text":"

    \nContracts in the Arb Token Bridge responsible for mapping tokens to their appropriate Token Gateway.\n

    "}, "genericcustom-gateway":{"title":"Generic-Custom Gateway","text":"

    \nA particular Custom gateway via which an L1 token contract can be registered to a token contract deployed to L2. A useful alternative to the StandardERC20 gateway for projects that wish to control the address of their L2 token contract, maintain L2 token contract upgradability, and for various other use-cases. \n

    "}, "geth":{"title":"Geth","text":"

    \nAn execution-layer client that defines the Ethereum state transition function and handles network-layer logic like transaction memory pooling. Arbitrum Nitro utilizes a fork of Geth to implement Arbitrum's state transition function.\n

    "}, -"gmx":{"title":"GMX","text":"

    \nIf you've seen some blueberries wandering around on crypto Twitter, you might wonder .. where did they come from?\n
    \n\n
    \nThe iconic blueberries come from the community of the decentralized exchange, GMX.\n

    "}, "ink":{"title":"Ink","text":"

    \nThe equivalent of gas in the Stylus vm. Ink is introduced for finer granularity than gas offers since Stylus's operations are considerably cheaper than their EVM analogs. \n

    "}, "l2-block":{"title":"L2 Block","text":"

    \nData structure that represents a group of L2 transactions (analogous to L1 blocks).\n

    "}, "l2-to-l1-message":{"title":"L2 to L1 Message","text":"

    \nA message initiated from within an Arbitrum chain to be eventually executed on Layer 1 (L1) (e.g., token or Ether withdrawals). On Rollup chains like Arbitrum One, the Challenge Period must pass before an L2 to L1 message is executed.\n

    "}, @@ -79,26 +82,21 @@ "sequencer-feed":{"title":"Sequencer Feed","text":"

    \nOff chain data feed published by the Sequencer which clients can subscribe to for Soft Confirmations of transactions before they are posted in Batches.\n

    "}, "shared-sequencing":{"title":"Shared Sequencing","text":"

    \nA protocol design space in which multiple rollups use the same entity as their Sequencer; potential benefits include enhanced interoperability and credible neutrality. \n

    "}, "smart-contract":{"title":"Smart Contract","text":"

    \nA computer program whose operations are defined and executed within a blockchain consensus protocol.\n

    "}, -"smolverse":{"title":"Smolverse","text":"

    \nNear the core of Arbitrum community is Smolverse, a world filled with Smol Brains and Smol Bodies.\n
    \n\n
    \nIf you see any Smol's with giga brains, swole arms or hear the sound of \"EEEE\" in the Arbitrum community, you've encountered the Smol Brains and Smol Bodies. \n

    "}, "soft-confirmation":{"title":"Soft Confirmation","text":"

    \nA semi-trusted promise from the Sequencer to post a user's transaction in the near future; soft-confirmations happen prior to posting on the Parent chain, and thus can be given near-instantaneously (i.e., faster than the parent chain's block times)\n

    "}, "speed-limit":{"title":"Speed Limit","text":"

    \nTarget computation limit for an Arbitrum chain. Arbitrum One and Arbitrum Nova currently target 7,000,000 gas / second. When computation exceeds this limit, fees rise, ala EIP-1559.\n

    "}, "staker":{"title":"Staker","text":"

    \nA Validator who deposits a stake (in Ether on Arbitrum One and Arbitrum Nova ) to vouch for a particular RBlock in an Arbitrum Chain. A validator who stakes on a false RBlock can expect to lose their stake. An honest staker can recover their stake once the RBlock they are staked on has been confirmed.\n

    "}, "standard-arbtoken":{"title":"Standard Arb-Token","text":"

    \nAn token contract on an Arbitrum chain deployed via the StandardERC20 gateway; offers basic ERC20 functionality in addition to deposit / withdrawal affordances.\n

    "}, "standarderc20-gateway":{"title":"StandardERC20 gateway","text":"

    \nToken Gateway via which any underlying chain's ERC20 token can permissionlessly bridge; the StandardERC20 gateway contracts deploy a Standard Arb-Token on the Child chain for each bridged token.\n

    "}, "stylus":{"title":"Stylus","text":"

    \nUpgrade to the Arbitrum Nitro virtual machine that allows smart contract support for languages like Rust and C++ by taking advantage of Nitro's use of WASM. Currently on testnet (read more).\n

    "}, -"tales-of-elleria":{"title":"Tales of Elleria","text":"

    \nThe bow and arrow are commonly associated with the Hero's of Tales of Elleria.\n
    \n\n
    \nJump into the world of Elleria and go on adventures.\n

    "}, -"time-boost":{"title":"Time boost","text":"

    \nA proposed (not currently live) transaction policy in which users can pay a fee to the Sequencer for a small ordering advantage. See [here](https://medium.com/offchainlabs/time-boost-a-new-transaction-ordering-policy-for-arbitrum-5b3066382d62) for more. \n

    "}, -"toadstoolz":{"title":"Toadstoolz","text":"

    \nHidden in the Croakshire, you will find the friendly Toadstoolz. \n
    \n\n
    \nThe iconic Toads of Arbitrum love to hunt BUGZ \n
    \n and collect NFTs. !CROAK\n

    "}, +"timeboost":{"title":"Timeboost","text":"

    \nA transaction ordering policy in which entities can bid for the right to access an express lane on the Sequencer for faster transaction inclusion. See the research specification to learn more. \n

    "}, "token-gateway":{"title":"Token Gateway","text":"

    \nA pair of contracts in the token bridge — one on the Parent chain , one on the Child chain — that provide a particular mechanism for handling the transfer of tokens between layers. Token gateways currently active in the bridge include the StandardERC20 gateway , the Generic-Custom Gateway , and the WETH Gateway.\n

    "}, -"townstory-":{"title":"TownStory ","text":"

    \nIf you see some homes along your road trip in the Arbitrum ecosystem, you've made it to TownStory.\n
    \n\n
    \nBuild a warm and prosperous town with friends in TownStory.\n

    "}, "transaction":{"title":"Transaction","text":"

    \nA user-initiated interaction with a Blockchain. Transactions are typically signed by users via wallets and are paid for via transaction fees. \n

    "}, -"treasure-dao":{"title":"Treasure DAO","text":"

    \nWhile exploring the Arbitrum ecosystem, you may see some shining stars.\n
    \n\n
    \nThe iconic stars symbolize the magic of Treasure DAO. Treasure DAO is the decentralized gaming ecosystem connecting games and players on Arbitrum.\n

    "}, +"transaction-ordering-policy":{"title":"Transaction Ordering Policy","text":"

    \nThe rules and logic employed by a chain to order incoming transactions into a block.\n

    "}, "trustless":{"title":"Trustless","text":"

    \nIn the context of Ethereum, trustless refers to the ability of a system to operate without reliance on a central authority or intermediary. Instead, users place their trust in math and protocols.\n
    \n\n
    \nThis is achieved through the use of cryptographic techniques and decentralized consensus mechanisms that let users verify the integrity of network transactions using open-source software. Trustless systems are considered to be more secure and resistant to fraud or tampering because they don't rely on a single point of failure that can be exploited by attackers.\n

    \n\n

    \n\n

    \n\n"}, "underlying-chain":{"title":"Underlying Chain","text":"

    \nSynonymous with Parent chain.\n

    "}, "validator":{"title":"Validator","text":"

    \nAn Arbitrum Full Node that tracks the status of the chains' Assertions. A validator may be a Watchtower Validator, a Defensive Validator, or an Active Validator. \n

    "}, "wasm":{"title":"WASM","text":"

    \nWidely supported binary code format for executable programs. Used by Arbitrum Nitro for Fraud proofs , and more broadly used by Stylus to support performant smart contracts in a wide variety of languages.\n

    "}, "wasmer":{"title":"WASMer","text":"

    \nA popular WebAssembly runtime for executing WASM binaries. A fork of WASMer is used for executing Stylus programs. WASMer executes considerably faster than Geth executes EVM code, contributing to Stylus's lower fees.\n

    "}, "watchtower-validator":{"title":"Watchtower Validator","text":"

    \nA Validator that never stakes / never takes on chain action, who raises the alarm (by whatever off-chain means it chooses) if it witnesses an invalid assertion.\n

    "}, -"weth-gateway":{"title":"WETH Gateway","text":"

    \nToken Gateway for handing the bridging of wrapped Ether (WETH). WETH is unwrapped on L1 and rewrapped on L1 upon depositing (and vice-versa upon withdrawing), ensuring WETH on L2 always remains collateralized. \n

    "}, -"zeeverse":{"title":"Zeeverse","text":"

    \nAs you're exploring the Arbitrum world, you may bump into a world filled with monsters and Zee's.\n
    \n\n
    \nExplore a mythical Spirit Realm as a young Shaman and take part in strategic turn-based battles to help protect Zeeverse from the looming corrupted forces.\n

    "} +"weth-gateway":{"title":"WETH Gateway","text":"

    \nToken Gateway for handing the bridging of wrapped Ether (WETH). WETH is unwrapped on L1 and rewrapped on L1 upon depositing (and vice-versa upon withdrawing), ensuring WETH on L2 always remains collateralized. \n

    "} } \ No newline at end of file diff --git a/website/static/node-running-faqs.json b/website/static/node-running-faqs.json index 414f98c92..f581d3c83 100644 --- a/website/static/node-running-faqs.json +++ b/website/static/node-running-faqs.json @@ -12,5 +12,5 @@ {"question": "Is there an alternative to Docker when running a node?","answer": "

    \nWe recommend running Nitro nodes via Docker, using the guides provided within our documentation. However, you can try to compile the code directly by following the steps described in this guide. \n

    \n\n

    \n\n

    \n\n","key": "is-there-an-alternative-to-docker-when-running-a-node"}, {"question": "What are the minimum hardware requirements to run a full node?","answer": "

    \nYou can see the minimum hardware configuration in this section.\n

    \n\n

    \n\n

    \n\n","key": "what-are-the-minimum-hardware-requirements-to-run-a-full-node"}, {"question": "How can I migrate the date of one synced node to a new one?","answer": "

    \nFrom a fully synced node, you can copy its database (the .arbitrum directory in a default setup) to the same database folder of the new node, and it will start from the same state.\n

    \n\n

    \nKeep in mind that this must be done after a clean shutdown, while the node is not running.\n

    \n\n

    \n\n

    \n\n","key": "how-can-i-migrate-the-date-of-one-synced-node-to-a-new-one"}, -{"question": "When querying Classic transactions from a Nitro node, I sometimes get incorrect data, like the zero address as the sender. Why is that?","answer": "

    \nSome old Nitro genesis database snapshots didn't properly set the retry sender for Classic blocks and contain said error. If you need to access that information, you can either resync your nitro node with one of the current snapshots, or run a Classic node along with your nitro node and configure a redirection for requests to Classic blocks. Please note that this only happens on Arbitrum One.\n

    \n\n

    \n\n

    \n\n","key": "when-querying-classic-transactions-from-a-nitro-node-i-sometimes-get-incorrect-data-like-the-zero-address-as-the-sender-why-is-that"} +{"question": "When querying Classic transactions from a Nitro node, I sometimes get incorrect data, like the zero address as the sender. Why is that?","answer": "

    \nSome old Nitro genesis database snapshots didn't properly set the retry sender for Classic blocks and contain said error. If you need to access that information, you can either resync your nitro node with one of the current snapshots, or run a Classic node along with your nitro node and configure a redirection for requests to Classic blocks. Please note that this only happens on Arbitrum One.\n

    \n\n

    \n\n

    \n\n","key": "when-querying-classic-transactions-from-a-nitro-node-i-sometimes-get-incorrect-data-like-the-zero-address-as-the-sender-why-is-that"} ] \ No newline at end of file From d82a7920e52c68ec8811409144cc8247da00eb01 Mon Sep 17 00:00:00 2001 From: Jason-Wanxt Date: Wed, 30 Oct 2024 23:08:26 +0800 Subject: [PATCH 90/99] tiny fix on aep page --- .../launch-orbit-chain/aep-fee-router-introduction.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/launch-orbit-chain/aep-fee-router-introduction.mdx b/arbitrum-docs/launch-orbit-chain/aep-fee-router-introduction.mdx index 4e56022f1..a5a40af7b 100644 --- a/arbitrum-docs/launch-orbit-chain/aep-fee-router-introduction.mdx +++ b/arbitrum-docs/launch-orbit-chain/aep-fee-router-introduction.mdx @@ -10,7 +10,7 @@ content_type: get-started ## What is the Arbitrum expansion program? -The [Arbitrum Expansion Program](https://forum.arbitrum.foundation/t/the-arbitrum-expansion-program-and-developer-guild/20722) (AEP) allows Orbit chains to deploy on *any chain*permissionlessly. As part of the [AEP license](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf), Orbit chains deployed outside of Arbitrum One and Arbitrum Nova must pay 10% of their **Net Protocol Revenue** to the Arbitrum DAO. +The [Arbitrum Expansion Program](https://forum.arbitrum.foundation/t/the-arbitrum-expansion-program-and-developer-guild/20722) (AEP) allows Orbit chains to deploy on *any chain* permissionlessly. As part of the [AEP license](https://docs.arbitrum.foundation/assets/files/Arbitrum%20Expansion%20Program%20Jan182024-4f08b0c2cb476a55dc153380fa3e64b0.pdf), Orbit chains deployed outside of Arbitrum One and Arbitrum Nova must pay 10% of their **Net Protocol Revenue** to the Arbitrum DAO. The Arbitrum Expansion Program and Developer Guild are initiatives launched in collaboration with Offchain Labs to promote the development of customized Arbitrum chains using the Orbit framework. The Expansion Program simplifies the process for teams to create Layer 2 (L2) and Layer 3 (L3) chains, offering self-service tools and customization options. Projects benefit from features like: From 3bcdbcda7e159072377ed39f70794dcf43668c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 30 Oct 2024 10:05:52 -0700 Subject: [PATCH 91/99] Update arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José FP <105675159+TucksonDev@users.noreply.github.com> --- arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md b/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md index d1a244ab7..cc1cb520e 100644 --- a/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md +++ b/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md @@ -1,6 +1,6 @@ --- title: 'Inside Arbitrum Nitro' -sidebar_label: 'Get started' +sidebar_label: 'Deep dive: Inside Arbitrum' description: 'Learn the fundamentals of Nitro, Arbitrum stack.' author: dzgoldman sme: dzgoldman From eab44cd31142f397dd28e2f24d427cf59dcebcf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 30 Oct 2024 15:46:33 -0700 Subject: [PATCH 92/99] feat: add warning about Stylus not supporting contract multi-inheritance yet --- .../partials/_stylus-no-multi-inheritance-banner-partial.mdx | 5 +++++ arbitrum-docs/stylus/reference/overview.md | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx diff --git a/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx new file mode 100644 index 000000000..946119ed4 --- /dev/null +++ b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx @@ -0,0 +1,5 @@ +:::info + +Stylus doesn't support contract multi-inheritance yet. + +::: diff --git a/arbitrum-docs/stylus/reference/overview.md b/arbitrum-docs/stylus/reference/overview.md index 04aa51699..99a6da3e6 100644 --- a/arbitrum-docs/stylus/reference/overview.md +++ b/arbitrum-docs/stylus/reference/overview.md @@ -8,9 +8,12 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart --- import PublicPreviewBannerPartial from '../../partials/_public-preview-banner-partial.mdx'; +import StylusNoMultiInheritanceBannerPartial from '../partials/_stylus-no-multi-inheritance-banner-partial.mdx' + + This section provides an in-depth overview of the features provided by the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs). For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../stylus-gentle-introduction.md). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../stylus-quickstart.md). The Stylus Rust SDK is built on top of [Alloy](https://www.paradigm.xyz/2023/06/alloy), a collection of crates empowering the Rust Ethereum ecosystem. Because the SDK uses the same [Rust primitives for Ethereum types](https://docs.rs/alloy-primitives/latest/alloy_primitives/), Stylus is compatible with existing Rust libraries. From e97b3fdacae3d4144463b32b011f4fb94b595563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 30 Oct 2024 15:59:55 -0700 Subject: [PATCH 93/99] fix: remove . --- .../partials/_stylus-no-multi-inheritance-banner-partial.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx index 946119ed4..5c0599c11 100644 --- a/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx +++ b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx @@ -1,5 +1,5 @@ :::info -Stylus doesn't support contract multi-inheritance yet. +Stylus doesn't support contract multi-inheritance yet ::: From f581e103749a9955ab00b1595114133da1eb56a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 30 Oct 2024 16:20:19 -0700 Subject: [PATCH 94/99] fix: re-add . --- .../partials/_stylus-no-multi-inheritance-banner-partial.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx index 5c0599c11..946119ed4 100644 --- a/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx +++ b/arbitrum-docs/stylus/partials/_stylus-no-multi-inheritance-banner-partial.mdx @@ -1,5 +1,5 @@ :::info -Stylus doesn't support contract multi-inheritance yet +Stylus doesn't support contract multi-inheritance yet. ::: From faec8ba47fc6037a58ed4e5ba486551d5b3d6cea Mon Sep 17 00:00:00 2001 From: Cooper Midroni <34783043+Midroni@users.noreply.github.com> Date: Thu, 31 Oct 2024 10:25:16 -0400 Subject: [PATCH 95/99] Update calculate-aep-fees.mdx small change to change "DAO owned" -> "Foundation owned" --- arbitrum-docs/launch-orbit-chain/how-tos/calculate-aep-fees.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/launch-orbit-chain/how-tos/calculate-aep-fees.mdx b/arbitrum-docs/launch-orbit-chain/how-tos/calculate-aep-fees.mdx index 694c0cdf3..43e5769c0 100644 --- a/arbitrum-docs/launch-orbit-chain/how-tos/calculate-aep-fees.mdx +++ b/arbitrum-docs/launch-orbit-chain/how-tos/calculate-aep-fees.mdx @@ -100,7 +100,7 @@ If you are an L3 or higher chain with a custom gas token, your custom gas token ### Non-Ethereum L1 -If your Orbit chain is deployed on a non-Ethereum L1 (e.g., Solana, BNB Chain), your fees must be manually transferred to a DAO-controlled address. +If your Orbit chain is deployed on a non-Ethereum L1 (e.g., Solana, BNB Chain), your fees must be manually transferred to a Foundation-controlled address. ### Novel Fee-Earning Customizations From 8d1864e22f3a51fc6c68ad00977ee049e87fd7c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 31 Oct 2024 07:54:49 -0700 Subject: [PATCH 96/99] fix: rename original admonition to admonitionNotForProduction --- website/src/scripts/stylusByExampleDocsHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/src/scripts/stylusByExampleDocsHandler.ts b/website/src/scripts/stylusByExampleDocsHandler.ts index 80975df2b..c039d46ae 100644 --- a/website/src/scripts/stylusByExampleDocsHandler.ts +++ b/website/src/scripts/stylusByExampleDocsHandler.ts @@ -130,7 +130,7 @@ function copyFiles(source, target) { // Adjust the file path const firstCodeBlock = `\`\`\`rust`; -const admonition = ` +const admonitionNotForProduction = ` import NotForProductionBannerPartial from '../partials/_not-for-production-banner-partial.mdx'; @@ -146,7 +146,7 @@ function addAdmonitionOneLineAboveFirstCodeBlock(content) { // Find the position two lines before firstCodeBlock const lines = content.substring(0, index).split('\n'); const insertLineIndex = lines.length - 2; - lines.splice(insertLineIndex, 0, admonition); + lines.splice(insertLineIndex, 0, admonitionNotForProduction); const newText = lines.join('\n') + content.substring(index); return newText; From b7d9a0f67ad69e425f9850b8e531c84ca1d6d31e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 31 Oct 2024 08:16:32 -0700 Subject: [PATCH 97/99] fix: remove warning from Stylus SDK overview page --- arbitrum-docs/stylus/reference/overview.md | 1 - 1 file changed, 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/overview.md b/arbitrum-docs/stylus/reference/overview.md index 99a6da3e6..0ab2978e6 100644 --- a/arbitrum-docs/stylus/reference/overview.md +++ b/arbitrum-docs/stylus/reference/overview.md @@ -12,7 +12,6 @@ import StylusNoMultiInheritanceBannerPartial from '../partials/_stylus-no-multi- - This section provides an in-depth overview of the features provided by the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs). For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../stylus-gentle-introduction.md). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../stylus-quickstart.md). From 1ca455259c79e2a44e9b2f579108143c12214092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 31 Oct 2024 08:16:59 -0700 Subject: [PATCH 98/99] feat: add warning to Rust SDK guide page --- arbitrum-docs/stylus/reference/rust-sdk-guide.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arbitrum-docs/stylus/reference/rust-sdk-guide.md b/arbitrum-docs/stylus/reference/rust-sdk-guide.md index da5a8b9d9..08d394253 100644 --- a/arbitrum-docs/stylus/reference/rust-sdk-guide.md +++ b/arbitrum-docs/stylus/reference/rust-sdk-guide.md @@ -9,6 +9,8 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart import PublicPreviewBannerPartial from '../../partials/_public-preview-banner-partial.mdx'; +import StylusNoMultiInheritanceBannerPartial from '../partials/_stylus-no-multi-inheritance-banner-partial.mdx' + This document provides information about advanced features included in the [Stylus Rust SDK](https://github.com/OffchainLabs/stylus-sdk-rs), that are not described in the previous pages. For information about deploying Rust smart contracts, see the `cargo stylus` [CLI Tool](https://github.com/OffchainLabs/cargo-stylus). For a conceptual introduction to Stylus, see [Stylus: A Gentle Introduction](../stylus-gentle-introduction.md). To deploy your first Stylus smart contract using Rust, refer to the [Quickstart](../stylus-quickstart.md). @@ -272,6 +274,10 @@ The [`#[entrypoint]`][entrypoint] macro will automatically implement the [`TopLe ### Inheritance, `#[inherit]`, and `#[borrow]`. + + + + Composition in Rust follows that of Solidity. Types that implement [`Router`][Router], the trait that [`#[public]`][public] provides, can be connected via inheritance. ```rust From c8a3d5431ccfa5d2b808885d566f34e8f9393d44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 31 Oct 2024 08:23:16 -0700 Subject: [PATCH 99/99] fix: remove unneeded import --- arbitrum-docs/stylus/reference/overview.md | 1 - 1 file changed, 1 deletion(-) diff --git a/arbitrum-docs/stylus/reference/overview.md b/arbitrum-docs/stylus/reference/overview.md index 0ab2978e6..1b706a3b7 100644 --- a/arbitrum-docs/stylus/reference/overview.md +++ b/arbitrum-docs/stylus/reference/overview.md @@ -8,7 +8,6 @@ target_audience: Developers using the Stylus Rust SDK to write and deploy smart --- import PublicPreviewBannerPartial from '../../partials/_public-preview-banner-partial.mdx'; -import StylusNoMultiInheritanceBannerPartial from '../partials/_stylus-no-multi-inheritance-banner-partial.mdx'

    Z;U=~R>;xr#VZ?z&q~M$H9PcFX`Z)VLk`T( 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 literal 0 HcmV?d00001 From 39c21b1a7ba96baaf4f836810451bb4ec51c4a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 13:32:32 -0700 Subject: [PATCH 03/99] fix: updated version of "economics of disputes" --- .../concepts/bold-economics-of-disputes.md | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md b/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md index 2691bd114..f64850b19 100644 --- a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md +++ b/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md @@ -17,13 +17,13 @@ sidebar_position: 1 [Arbitrum One](https://arbitrum.io/) is currently one of the most widely adopted Ethereum scaling solutions, with [~$18bn USD in total-value-locked](https://l2beat.com/scaling/projects/arbitrum) at the time of writing. Not only do its scaling properties make it popular, such as its 250ms block times, but so do its security properties and its approach to decentralization. Currently, Arbitrum One is governed by the Arbitrum DAO, one of the most active and robust onchain organizations. -However, Arbitrum has not yet achieved its full promise of decentralization. Currently, withdrawals from Arbitrum One back to Ethereum are verified by a permissioned list of validators. These validators can still challenge invalid withdrawals, but the system prevents anyone outside this list from holding them accountable. This limits Arbitrum One to being categorized as a Stage 1 rollup, according to the [L2Beat website](https://l2beat.com/scaling/summary), meaning it still has training wheels preventing it from reaching its full potential. +However, Arbitrum has not yet achieved its full promise of decentralization. Currently, withdrawals from Arbitrum One back to Ethereum are verified by a permissioned list of state proposers. These proposers can still challenge invalid withdrawals, but the system prevents anyone outside this list from holding them accountable. This limits Arbitrum One to being categorized as a Stage 1 rollup, according to the [L2Beat website](https://l2beat.com/scaling/summary), meaning it still has training wheels preventing it from reaching its full potential. The reason why Arbitrum One is called “optimistic” is because claims about its state settle to Ethereum after a period of ~7 days, in which they can be disputed. To make an analogy, a check can be cashed right away, but can be taken to court to dispute if there is a problem within a certain time frame. Because Arbitrum’s state is deterministic, a validator that is running a node and following the chain will always know if a posted claim is invalid. A key decentralization property is allowing **anyone** that knows the correct claim to challenge invalid claims and ***win***. This preserves the correct history of Arbitrum settling to Ethereum and protects the integrity of users’ funds along with their withdrawals using a “single honest party” property. As long as there is a single entity following the chain and willing to dispute a claim, Arbitrum’s security guarantees are maintained. -Today, the security properties of Arbitrum One are defined by the size of the permissioned set of validators it has. Validators could collude, could settle an incorrect history, and users have no recourse aside from the Arbitrum One security council stepping in. To elevate Arbitrum One’s decentralization, it needs a different approach. +Today, the security properties of Arbitrum One are defined by the size of the permissioned set of proposers and challengers it has. These entities could collude, could settle an incorrect history, and users have no recourse aside from the Arbitrum One security council stepping in. To elevate Arbitrum One’s decentralization, it needs a different approach. -In the fall of ‘23, Offchain Labs announced [Arbitrum BOLD](https://medium.com/offchainlabs/bold-permissionless-validation-for-arbitrum-chains-9934eb5328cc), a brand new, dispute resolution protocol built from the ground up that will bring Arbitrum chains to the next level of decentralization. BOLD, standing for Bounded Liquidity Delay, allows for **permissionless **validation of Arbtrum chains. This means the DAO can remove the list of allowed validators and let anyone challenge claims made about Arbitrum states on Ethereum, and win against them if they are incorrect. +In the fall of ‘23, Offchain Labs announced [Arbitrum BOLD](https://medium.com/offchainlabs/bold-permissionless-validation-for-arbitrum-chains-9934eb5328cc), a brand new, dispute resolution protocol built from the ground up that will bring Arbitrum chains to the next level of decentralization. BOLD, standing for Bounded Liquidity Delay, allows for **permissionless **validation of Arbitrum chains. This means the DAO can remove the list of allowed validators and let anyone challenge claims made about Arbitrum states on Ethereum, and win against them if they are incorrect. In this document we’ll go deep into understanding the economics and tradeoffs that Arbitrum must make in order to enable permissionless validation. @@ -31,13 +31,13 @@ In this document we’ll go deep into understanding the economics and tradeoffs We frequently state that “Arbitrum settles its state to Ethereum”, and we’ll elaborate on what that exactly means. All Arbitrum One transactions can be recreated by reading data from Ethereum L1, as compressed batches of all L2 txs are frequently posted to Ethereum. Once a batch transaction is included in a finalized block on Ethereum, its history will never get reverted on Arbitrum. Ethereum, however, does not know if a batch posted to it refers to a correct Arbitrum history. For verifying batch integrity, there is a separate process that actually confirms batch correctness on Ethereum. -Separately, entities known as validators are checking the correctness of batches by following the Arbitrum chain. Approximately every hour, they post something called an “assertion” which attests to the validity of a batch, saying “I have verified this batch”. As Ethereum has no knowledge of what is actually correct on Arbitrum, it allows ~7 days for anyone to come in and dispute one of these assertions. +Separately, entities known as proposers are checking the correctness of batches by following the Arbitrum chain and approximately every hour, they post something called an “assertion” which attests to the validity of a batch, saying “I have verified this batch”. As Ethereum has no knowledge of what is actually correct on Arbitrum, it allows ~7 days for anyone to come in and dispute one of these assertions. ### Withdrawing Assets Back to Ethereum from Arbitrum -Users of Arbitrum One that have bridged assets from Ethereum can withdraw said assets at any time. However, for this withdrawal to be fully executed, a withdrawal claim has to correspond to a confirmed assertion on Ethereum. For instance, Alice starts a withdrawal transaction on Arbitrum One, which gets posted in a batch on Ethereum. Then, a validator will post an assertion about that batch on Ethereum 1 hour later. The assertion has a ~7 day window in which anyone can dispute it, otherwise, it will get confirmed. After that window passes, Alice will receive her withdrawn assets on Ethereum and is free to use them as she pleases. +Users of Arbitrum One that have bridged assets from Ethereum can withdraw said assets at any time. However, for this withdrawal to be fully executed, a withdrawal claim has to correspond to a confirmed assertion on Ethereum. For instance, Alice starts a withdrawal transaction on Arbitrum One, which gets posted in a batch on Ethereum. Then, a proposer will post an assertion about that batch on Ethereum 1 hour later. The assertion has a ~7 day window in which anyone can dispute it, otherwise, it will get confirmed. After that window passes, Alice will receive her withdrawn assets on Ethereum and is free to use them as she pleases. -“Settling states'' and having a ~7 day dispute window is crucial to ensuring assets can be withdrawn safely. Allowing anyone to dispute invalid claims and wins helps keep withdrawals protected by strong security guarantees, without needing to trust a group of validators. It is this “permissionless validation” what separates Optimistic Rollups from side chains. +“Settling states'' and having a ~7 day dispute window is crucial to ensuring assets can be withdrawn safely. Allowing anyone to dispute invalid claims and wins helps keep withdrawals protected by strong security guarantees, without needing to trust a group of permissioned entities. It is this “permissionless validation” what separates Optimistic Rollups from side chains. ### The Dispute Period @@ -47,6 +47,7 @@ The reason there is a dispute window for assertions about Arbitrum One on Ethere An actual dispute occurs once a party disagrees with an assertion on Ethereum, and posts their own assertion they know to be correct. This creates a “fork” in the chain of assertions, requiring a resolution process. We’ll get into the high-level details of how disputes are resolved soon. +![](assets/9Pr_Image_1.png) Once an actual dispute is ongoing, it will also take time to resolve, as, once again, Ethereum has no knowledge of the correctness of Arbitrum states. Ethereum must then give sufficient time for parties to provide their burden of proof and declare a winner. The new, Arbitrum BOLD protocol **guarantees that a dispute will be resolved within 7 days** so long as there is an honest party present to defend against invalid claims. As assertions have a dispute window of 7 days, and disputes require an additional 7 days to resolve, a dispute made at the last second would** delay assertion confirmation to a maximum of 14 days**, or 2 weeks. BOLD is the only dispute protocol we are aware of that guarantees this bound. @@ -55,23 +56,25 @@ As assertions have a dispute window of 7 days, and disputes require an additiona Delaying withdrawals incurs opportunity cost and a worse user experience for users that want to withdraw their assets. In the happy case, where no disputes exist, withdrawals already have a baked-in, 7 day delay. A dispute incurs an additional 7 days on top of that maximum. The problem is that disputes delay *all *pending withdrawals from Arbitrum One back to Ethereum, not just a single claim. As such, **disputing a claim must have a cost for the initiator** proportional to the opportunity cost they impose on Arbitrum users. -#### Requiring a Bond to Become a Validator +#### Requiring a Bond to Become a Proposer -The entities responsible for posting assertions about Arbitrum state to Ethereum are called validators. If posting assertions were free, anyone could create conflicting assertions to always delay withdrawals by 14 days instead of 7. As such, Arbitrum requires validators to put in a “security deposit”, known as a **bond**, to be allowed to post assertions. Validators can withdraw their bond as soon as their latest posted assertion has been confirmed, and end their responsibilities. +The entities responsible for posting assertions about Arbitrum state to Ethereum are called proposers. If posting assertions were free, anyone could create conflicting assertions to always delay withdrawals by 14 days instead of 7. As such, Arbitrum requires proposers to put in a “security deposit”, known as a **bond**, to be allowed to post assertions. Proposers can withdraw their bond as soon as their latest posted assertion has been confirmed, and end their responsibilities. #### Pricing Bonds -Ensuring assertions are frequently posted is a requirement for Arbitrum, but at the same time, it should not be a privilege that is easily obtained. In terms of pricing this “security deposit” for Arbitrum validators, we choose to do so based on opportunity cost. +Ensuring assertions are frequently posted is a requirement for Arbitrum, but at the same time, it should not be a privilege that is easily obtained. In terms of pricing this “security deposit” for Arbitrum proposers, we choose to do so based on opportunity cost. To be extremely conservative, in a bank-run scenario, the [Arbitrum One bridge](https://etherscan.io/address/0x8315177ab297ba92a06054ce80a67ed4dbd7ed3a) contains approximately $5.4bn worth of assets at the time of writing on April 15th, 2024. Assuming funds could earn a 5% APY if invested, the opportunity cost of 1 extra week of delay is approximately $5,200,000 USD. Given this scenario, we recommend a bond for assertion posters somewhere in the range of ~$2.5M - $5M. -Honest parties can always withdraw their bond once their assertions are confirmed. However, adversaries stand to lose the entirety of their bond if they post invalid claims. A large bond size drastically improves the economic security of the system based on these two axes. +Honest parties can always withdraw their bond once their assertions are confirmed. **However, adversaries will entirety of their bond if they post invalid claims** once a challenge is complete**.** A large bond size drastically improves the economic security of the system based on these two axes. #### Centralization Concerns -Requiring a high bond to post assertions about Arbitrum seems centralizing, as we are replacing a whitelist of validators with instead a system that requires a lot of money to participate in. However, **BOLD ships with a trustless bonding pool** for assertion posting. That is, any group of honest parties can pool funds into a simple contract that will post an assertion to Ethereum without needing to trust each other. We believe that making it easy to pool the funds to become an assertion poster, without needing trust to dispute invalid claims, does not fundamentally affect the safety or decentralization of BOLD. +Requiring a high bond to post assertions about Arbitrum seems centralizing, as we are replacing a whitelist of proposers with instead a system that requires a lot of money to participate in. However, **BOLD ships with a trustless bonding pool** for assertion posting. That is, any group of honest parties can pool funds into a simple contract that will post an assertion to Ethereum without needing to trust each other. We believe that making it easy to pool the funds to become an assertion poster, without needing trust to dispute invalid claims, does not fundamentally affect the safety or decentralization of BOLD. What’s most important is that any entity can challenge a proposer of Arbitrum states. -We claim optimizing for the unhappy case is more important than the happy case. As there only needs to be one honest assertion poster, we believe it falls into the security budget of the chain to price in a $2M bond to become a validator. It* should* be expensive to delay Arbitrum One withdrawals, and it should also have a high barrier to entry to perform a key responsibility. As long as disputes can be made in a trustless manner, and trustless pools are available in production, we claim the security properties of assertion posting hold equally. +We believe optimizing for the unhappy case is more important than the happy case. As there only needs to be one honest assertion poster, we believe it falls into the security budget of the chain to price in a bond to become a proposer. It* should* be expensive to delay Arbitrum One withdrawals, and it should also have a high barrier to entry to perform a key responsibility. As long as disputes can be made in a trustless manner, and trustless pools are available in production, we claim the security properties of assertion posting hold equally. + +In production, we expect there to be very few, if not just one proposer. ## Resolving Disputes @@ -98,7 +101,7 @@ Because evil parties can submit junk that makes honest parties do work, there ha When thinking about how to price the bonds required to make claims within disputes, we essentially consider the marginal costs that the honest party incurs for each claim an evil party makes. In the BOLD research paper, this comes out to include information such as the number of adversary moves, multiplied by the gas cost of making bisections, making claims, and some estimates of the offchain computational costs. We deem this the **marginal cost** of a party in a dispute. -In BOLD, the space of disagreements between parties is of max size 2^43. As such, the dispute game has to be played at different levels of granularity to make it computationally feasible. +![](assets/csI_Image_2.png) For instance, say we have two, 1 meter sticks that seem identical, and we want to figure out where they differ. It turns out that they seem identical at the centimeter level, so we need to go down to the millimeter level, then the micrometer level, and then figure out where they differ at the *nanometer* level. @@ -108,37 +111,46 @@ This is what BOLD does over the space of disputes. Parties play the same game at Given Ethereum knows nothing about which claims are honest or evil until a one step proof is reached, then how can the protocol detect spam and discourage it? A key insight is that honest parties only need to make one honest claim. Honest parties will never spam and create thousands of conflicting claims with themselves. Given this, we can put a price tag on making moves by looking at something called the “resource ratio” between honest and evil parties, as defined in the BOLD research paper +![](assets/BnF_Image_3.png) This ratio is essentially the gas + staking (or bonding) marginal costs of the adversary to the honest party. This means that certain values input into the equations can lead to **different ratios**. For instance, we can say the adversary has to pay **10x **the marginal costs of the honest party. However, aiming to increase this ratio significantly by plugging in different values leads to higher costs for all parties. -#### Dispute Mini-Bonds +#### Dispute Challenge Bonds -We require parties to lock up some capital called a “mini-bond” when making big claims in a dispute. These bonds are not needed when making bisection moves, but are critical for posting an initial claim. Pricing these mini-bonds helps us achieve a high resource ratio of evil parties to honest parties. +BOLD also requires parties to lock up some capital called a challenge bond when making certain moves within a dispute. Pricing these challenge bonds helps us achieve a high resource ratio of evil parties to honest parties. -It is clear that if we can make the cost to the evil party some multiplier of the honest party, we get significant security benefits. For instance, imagine if a $1 billion dollar attack can be defended by simply pooling together $10 million dollars. Is it possible to achieve such a ratio? +It is clear that if we can make the cost to the evil party some multiplier of the honest party, we get significant security benefits. For instance, imagine if a $1 billion dollar attack can be defended by simply pooling together $10 million dollars. Is it possible to achieve such a ratio? Recall that more important than this ratio is the fact that the evil party stands to lose their entire bond compared to honest parties, which will get their bonds refunded. Let’s explore the limitations of making the cost to evil parties high vs. that of the honest parties. -That is, if we aim to have a constant resource ratio > 1, we have to do the following: if the adversary makes N stakes at any level, they can force the honest party to make N stakes at the next level down where the adversary can choose not to place any stakes at all. In terms of resource ratio, to make the adversary always pay 10x in staking, we need to make the bond amount at one level 10x more than the next. As there are multiple levels, the equations for the bond size include an exponential factor on the desired, constant resource ratio > 1. +That is, if we aim to have a constant resource ratio > 1, we have to do the following: if the adversary makes N stakes at any level, they can force the honest party to make N stakes at the next level down where the adversary can choose not to place any bonds at all. In terms of resource ratio, to make the adversary always pay 10x in bonding, we need to make the bond amount at one level 10x more than the next. As there are multiple levels, the equations for the bond size include an exponential factor on the desired, constant resource ratio > 1. Below, we plot the bond size vs. the resource ratio of evil to honest costs. The source for these equations is both in the research paper and plotted [here](https://www.desmos.com/calculator/digjlq4vly). +![](assets/CRA_Image_4.png) If we desire a constant resource ratio of evil to honest costs > 1, the required bond size in ETH increases as a polynomial at a particular challenge level. #### Trade Offs -Having a 1000x resource ratio would be nice in theory, but would unfortunately require a bond of 1M ETH ($3.5bn) to open a challenge in the first place, which is unreasonable. Instead, we can explore a more feasible ratio of 10x. +Having a 1000x resource ratio would be nice in theory, but would unfortunately require a bond of 1M ETH ($3.5bn) to open a dispute in the first place, which is unreasonable. Instead, we can explore a more feasible ratio of 10x. The tradeoff here is the higher the resource ratio we want, the more expensive it is for both honest and evil parties to make claims in disputes. However, claims can **always be made** through a **trustless pool**. Honest parties can pool together funds to participate in disputes. #### The Sweet Spot -We estimate that at a resource ratio of 10x, the cost of resolving a single adversarial claim in a dispute would be approximately $16M USD for the honest parties. Honest parties will always be refunded, and possibly rewarded, while evil parties always stand to lose 100% of their bond. The DAO could then consider the cost of incentivizing a single honest staker in the happy case to be the **security budget of the chain**. This means defending against a $1 billion attack would require $100M total to defend, with the entire amount being refunded while the attacker losing all $1bn. +We estimate that at a resource ratio of 10x, the bond required to resolve a single adversarial claim in a dispute would be approximately 1110 ETH for the honest parties. The DAO could then consider the cost of incentivizing a single honest staker in the happy case to be the **security budget of the chain**. This means defending against a $1 billion attack would require $100M total to defend, which would all be refunded while the attacker would lose all $1bn. + +## Arbitrum Nova + +Arbitrum Nova has a much smaller total-value-locked than Arbitrum One at the time of writing, with Arbitrum One having more than 381x the value of Nova. Large bond prices for Nova are hard to rationalize, given the amount that is held by the chain is much smaller than Arbitrum One. + +Instead, we recommend that Arbitrum Nova remain with permissioned validation, as it already uses a data-availability committee that has a 2 of N trust assumption. Moreover, this committee can also run validators which enables features such as fast confirmations on the chain. ## Thinking About Incentives Although we have made claims with hard numbers about how to price disputes and withdrawal delays in Arbitrum BOLD, we also take a step back and think about the game theoretical assumptions we are making. Arbitrum One is a complex protocol used by many groups of people, with many different incentives. The research team at Offchain Labs, has spent considerable effort studying the game theory of validators in Optimistic Rollup. Honest parties represent everyone that has funds onchain, and they have a huge amount to gain by winning the challenge - as they can prevent the loss of their assets rather than losing them. -A more complex model is proposed which considers all parties staking and their associated costs created by [Akaki Mamageishvili](mailto:amamageishvili@offchainlabs.com)and Ed Felten in their paper [“Incentive Schemes for Rollup Validators”](https://arxiv.org/abs/2308.02880). The paper looks at what incentives are needed to get parties to check whether assertions are correct. It finds that there is no pure strategy Nash equilibrium, and only a mixed equilibrium if there is no incentive for honest validators. However, the research showed a pure strategy equilibrium can be reached if honest parties are incentivized to **check** results. The problem of honest validators “freeriding” and not checking is well-documented as the [verifier’s dilemma](https://www.smithandcrown.com/glossary/verifiers-dilemma). We believe future iterations of BOLD could include “attention challenges” that reward honest validators for also doing their job. +A more complex model is proposed which considers all parties staking and their associated costs created by +and Ed Felten in their paper [“Incentive Schemes for Rollup Validators”](https://arxiv.org/abs/2308.02880). The paper looks at what incentives are needed to get parties to check whether assertions are correct. It finds that there is no pure strategy Nash equilibrium, and only a mixed equilibrium if there is no incentive for honest validators. However, the research showed a pure strategy equilibrium can be reached if honest parties are incentivized to **check** results. The problem of honest validators “freeriding” and not checking is well-documented as the [verifier’s dilemma](https://www.smithandcrown.com/glossary/verifiers-dilemma). We believe future iterations of BOLD could include “attention challenges” that reward honest validators for also doing their job. ## Conclusion From 25b50eddb7286611ca911d47f354829868fcfa44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 14:19:30 -0700 Subject: [PATCH 04/99] feat: added img asset attribute selectors --- website/src/css/partials/_content-body.scss | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/website/src/css/partials/_content-body.scss b/website/src/css/partials/_content-body.scss index c7d23b9d0..7acd901a8 100644 --- a/website/src/css/partials/_content-body.scss +++ b/website/src/css/partials/_content-body.scss @@ -49,6 +49,16 @@ article { font-weight: 600; } + img[alt='diag1'] { + width: 200px; + } + img[alt='diag2'] { + width: 400px; + } + img[alt='diag3'] { + width: 600px; + } + .theme-admonition { margin-bottom: 2em; From a8b66d3e97c60805e85277bda490403604bfae6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 14:31:54 -0700 Subject: [PATCH 05/99] fix: math formula image cropping --- arbitrum-docs/bold/assets/BnF_Image_3.png | Bin 5932 -> 11525 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/arbitrum-docs/bold/assets/BnF_Image_3.png b/arbitrum-docs/bold/assets/BnF_Image_3.png index 9b499f2eee765c8ad5f26d574bafa436abec7684..06eb4a697597b16c6c116cdf7cbe13b277abfd61 100644 GIT binary patch literal 11525 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 N)@41l$12xv{y+P1Iw1f6 literal 5932 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 vJrjqOCT|mMCt@^m6@d!=|GI` Date: Mon, 29 Apr 2024 14:32:20 -0700 Subject: [PATCH 06/99] fix: imgs > proper linking and formatting --- .../bold/concepts/bold-economics-of-disputes.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md b/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md index f64850b19..f543bf0a4 100644 --- a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md +++ b/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md @@ -47,7 +47,8 @@ The reason there is a dispute window for assertions about Arbitrum One on Ethere An actual dispute occurs once a party disagrees with an assertion on Ethereum, and posts their own assertion they know to be correct. This creates a “fork” in the chain of assertions, requiring a resolution process. We’ll get into the high-level details of how disputes are resolved soon. -![](assets/9Pr_Image_1.png) +![diag2](../assets/9Pr_Image_1.png) + Once an actual dispute is ongoing, it will also take time to resolve, as, once again, Ethereum has no knowledge of the correctness of Arbitrum states. Ethereum must then give sufficient time for parties to provide their burden of proof and declare a winner. The new, Arbitrum BOLD protocol **guarantees that a dispute will be resolved within 7 days** so long as there is an honest party present to defend against invalid claims. As assertions have a dispute window of 7 days, and disputes require an additional 7 days to resolve, a dispute made at the last second would** delay assertion confirmation to a maximum of 14 days**, or 2 weeks. BOLD is the only dispute protocol we are aware of that guarantees this bound. @@ -101,7 +102,7 @@ Because evil parties can submit junk that makes honest parties do work, there ha When thinking about how to price the bonds required to make claims within disputes, we essentially consider the marginal costs that the honest party incurs for each claim an evil party makes. In the BOLD research paper, this comes out to include information such as the number of adversary moves, multiplied by the gas cost of making bisections, making claims, and some estimates of the offchain computational costs. We deem this the **marginal cost** of a party in a dispute. -![](assets/csI_Image_2.png) +![diag2](../assets/csI_Image_2.png) For instance, say we have two, 1 meter sticks that seem identical, and we want to figure out where they differ. It turns out that they seem identical at the centimeter level, so we need to go down to the millimeter level, then the micrometer level, and then figure out where they differ at the *nanometer* level. @@ -111,7 +112,8 @@ This is what BOLD does over the space of disputes. Parties play the same game at Given Ethereum knows nothing about which claims are honest or evil until a one step proof is reached, then how can the protocol detect spam and discourage it? A key insight is that honest parties only need to make one honest claim. Honest parties will never spam and create thousands of conflicting claims with themselves. Given this, we can put a price tag on making moves by looking at something called the “resource ratio” between honest and evil parties, as defined in the BOLD research paper -![](assets/BnF_Image_3.png) +![](../assets/BnF_Image_3.png) + This ratio is essentially the gas + staking (or bonding) marginal costs of the adversary to the honest party. This means that certain values input into the equations can lead to **different ratios**. For instance, we can say the adversary has to pay **10x **the marginal costs of the honest party. However, aiming to increase this ratio significantly by plugging in different values leads to higher costs for all parties. #### Dispute Challenge Bonds @@ -126,7 +128,8 @@ That is, if we aim to have a constant resource ratio > 1, we have to do the foll Below, we plot the bond size vs. the resource ratio of evil to honest costs. The source for these equations is both in the research paper and plotted [here](https://www.desmos.com/calculator/digjlq4vly). -![](assets/CRA_Image_4.png) +![diag2](../assets/CRA_Image_4.png) + If we desire a constant resource ratio of evil to honest costs > 1, the required bond size in ETH increases as a polynomial at a particular challenge level. #### Trade Offs From 9ba4f259282c1faa8f0727d84ad8fa8245e4231f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 14:49:04 -0700 Subject: [PATCH 07/99] feat: added attribute selector for 900px imgs --- website/src/css/partials/_content-body.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/src/css/partials/_content-body.scss b/website/src/css/partials/_content-body.scss index 7acd901a8..0bd0fa0ee 100644 --- a/website/src/css/partials/_content-body.scss +++ b/website/src/css/partials/_content-body.scss @@ -58,6 +58,9 @@ article { img[alt='diag3'] { width: 600px; } + img[alt='diag4'] { + width: 900px; + } .theme-admonition { margin-bottom: 2em; From 1f99d17999b7a0e0cd8e768f32c80b89ede2e97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 29 Apr 2024 14:50:51 -0700 Subject: [PATCH 08/99] fix: updated BoLD technical deep dive content --- .../bold/concepts/bold-technical-deep-dive.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 45d56ace5..2639e774e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -16,11 +16,11 @@ Under the hood, a reason why BOLD can offer time-bounded, permissionless validat To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BOLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. -Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. +Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it *can* help prove their correctness. *Anyone* in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. The assertions being disputed over are about block hashes of an Arbitrum chain at a given batch / inbox position. Given Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of a one-step-proof, Ethereum can check if someone is making a fraudulent assertion or not. -If a claim is honest, it can be confirmed on Ethereum after a 6.4 day period (although this period can be changed by the DAO). If a claim is malicious, anyone that knows the correct Arbitrum state can successfully challenge it within that 6.4 day window _and always win_ within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4 day period (although this period can be changed by the DAO). If a claim is malicious, anyone that knows the correct Arbitrum state can successfully challenge it within that 6.4 day window *and always win* within a challenge period. The current implementation of BOLD involves both on-chain and off-chain components: @@ -58,11 +58,11 @@ The current implementation of BOLD involves both on-chain and off-chain componen When it comes to implementing the protocol, BOLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain where the full protocol can be deployed to, with challenge moves performed as transactions to the protocol’s smart contracts. -A helpful mental model to understand the system is that it uses Ethereum itself as the ultimate _referee_ for deciding results of assertions. Participants in the challenge protocol can disagree over _results of L2 state transitions_, and they can provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. +A helpful mental model to understand the system is that it uses Ethereum itself as the ultimate *referee* for deciding results of assertions. Participants in the challenge protocol can disagree over *results of L2 state transitions*, and they can provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. -![Enter image alt description](../assets/KSf_Image_1.png) +![diag4](../assets/KSf_Image_1.png) -_From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each in which anyone can challenge their validity on Ethereum._ +*From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each in which anyone can challenge their validity on Ethereum.* In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, and this is why this mini-VM is built to handle “one-step proofs” which consist of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM . @@ -71,7 +71,7 @@ All actors in the protocol have a local state of which they can produce valid pr ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BOLD requires several changes to how assertions work in this contract and it now contains a reference to another contract called a ChallengeManager, new in BOLD +- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BOLD requires several changes to how assertions work in this contract and it now contains a reference to another contract called a ChallengeManager, new in BOLD - **ChallengeManager:** this is a contract that allows for initiating challenge on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entrypoints for making challenge moves, opening leaves, creating subchallenges, and confirming challenges @@ -183,7 +183,7 @@ The number of steps of execution at which validators could disagree within a sin First, validators disagree over Arbitrum blocks in between two assertions. They make “edges” containing history commitments to all the blocks in between those two assertions, and play the bisection game. Once they narrow down to a single block of disagreement, they now need to find where they disagree in the actual WASM execution of the block through the Arbitrum state transition function. This is what we call the first “subchallenge”. -The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. +The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in *ranges* of steps. First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “mini-bond”. The magnitudes of mini-bonds are different at each subchallenge level. @@ -193,7 +193,7 @@ Once validators reach a single, individual step of disagreement after reaching t #### Timers -Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge’s timer stops ticking the moment it has a rival edge created onchain. +Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge’s timer stops ticking the moment it has a rival edge created onchain. Edges also have something called an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge’s children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, the assertion it claims can also be confirmed as its associated challenge has completed. A minor, but important detail is that edges also inherit the time their claimed assertion was unrivaled. From 1a7bb662367b473df00d6af687562fdde83fd601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 30 Apr 2024 09:34:04 -0700 Subject: [PATCH 09/99] Fix: grammar/spelling --- .../bold/concepts/bold-technical-deep-dive.md | 137 +++++++++--------- 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 2639e774e..1c6914515 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -1,5 +1,5 @@ --- -title: 'BOLD: a technical deep dive' +title: 'BoLD: a technical deep dive' sidebar_label: 'Technical deep dive' description: 'A technical deep dive into the BoLD protocol.' user_story: 'As a user or researcher of the Arbitrum product suite, I want to understand the technical implementation of the BoLD protocol.' @@ -12,86 +12,85 @@ sidebar_position: 1 ## Overview -Under the hood, a reason why BOLD can offer time-bounded, permissionless validation is because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond on the correct state and, through interactive fraud proofs, can prove their claim is correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. +Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond on the correct state and, through interactive fraud proofs, prove their claim is correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. -To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BOLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. +To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BoLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it *can* help prove their correctness. *Anyone* in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. -The assertions being disputed over are about block hashes of an Arbitrum chain at a given batch / inbox position. Given Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of a one-step-proof, Ethereum can check if someone is making a fraudulent assertion or not. +The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. -If a claim is honest, it can be confirmed on Ethereum after a 6.4 day period (although this period can be changed by the DAO). If a claim is malicious, anyone that knows the correct Arbitrum state can successfully challenge it within that 6.4 day window *and always win* within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window *and always win* within a challenge period. -The current implementation of BOLD involves both on-chain and off-chain components: +The current implementation of BoLD involves both on-chain and off-chain components: 1. Rollup contracts to be deployed on Ethereum -2. New, challenge management contracts to be deployed on Ethereum +2. New challenge management contracts to be deployed on Ethereum -3. [Honest validator software](https://github.com/offchainlabs/bold) equipped to submit assertions and perform challenge moves on any assertions it disagrees with. The honest validator is robust enough to win against malicious entities and always ensure honest assertions are the only ones confirmed on-chain +3. [Honest validator software](https://github.com/offchainlabs/bold) equipped to submit assertions and perform challenge moves on any assertions it disagrees with. The honest validator is robust enough to win against malicious entities and always ensures honest assertions are the only ones confirmed on-chain ### Key terminology - **Arbitrum Rollup Contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made -- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and it can get challenged by anyone during that period. A BOLD challenge will add an additional upper bound of 6.4 days to the confirmation of an assertion. That is, if an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed for the challenge to complete. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller, “mini-bonds” each time. +- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “mini-bonds” each time. - **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed -- **Fraud Proofs:** Proofs of a single step of WAVM execution of Arbitrum's state transition function which are submitted to Ethereum and verified in the EVM via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a WASM instruction on a pre-state. +- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the EVM via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a WASM instruction on a pre-state. -- **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one step proofs of deterministic computation that can confirm a winner of a challenge in Arbitrum's rollup contracts. +- **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's rollup contracts. -- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond, in the form of WETH. Subsequent assertions posted by the same party do not require more bonds, instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another, competing assertion becomes confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn +- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn -- **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain, and will participate in confirming assertions and challenging invalid assertions if they exist +- **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist - **Challenge Period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. -- **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BOLD has a proven, constant upper-bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BOLD validators don’t need to play 1-vs-1 challenges, and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation +- **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation -- **Permissionless Validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BOLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. +- **Permissionless Validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. -- **Validator Software:** Software that has knowledge of the correct, Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so, but will warn in case invalid assertions are detected onchain. +- **Validator Software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. -### How BOLD Uses Ethereum +### How BoLD Uses Ethereum -When it comes to implementing the protocol, BOLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain where the full protocol can be deployed to, with challenge moves performed as transactions to the protocol’s smart contracts. +When it comes to implementing the protocol, BoLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain to which the full protocol can be deployed, with challenge moves performed as transactions to the protocol’s smart contracts. -A helpful mental model to understand the system is that it uses Ethereum itself as the ultimate *referee* for deciding results of assertions. Participants in the challenge protocol can disagree over *results of L2 state transitions*, and they can provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. +A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the *results of L2 state transitions* and provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. ![diag4](../assets/KSf_Image_1.png) -*From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each in which anyone can challenge their validity on Ethereum.* +*From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum.* -In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, and this is why this mini-VM is built to handle “one-step proofs” which consist of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM -. +In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM. -All actors in the protocol have a local state of which they can produce valid proofs over, and all honest parties will have the same local state as each other. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth +All actors in the protocol have a local state from which they can produce valid proofs, and all honest parties will have the same local state. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth. ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BOLD requires several changes to how assertions work in this contract and it now contains a reference to another contract called a ChallengeManager, new in BOLD +- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a ChallengeManager, new in BoLD. -- **ChallengeManager:** this is a contract that allows for initiating challenge on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entrypoints for making challenge moves, opening leaves, creating subchallenges, and confirming challenges +- **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. -- **OneStepProver:** A set of contracts that implement a miniature WASM VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the OSP contracts are needed for BOLD. +- **OneStepProver:** A set of contracts that implement a miniature WASM VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the OSP contracts are needed for BoLD. -- **Bonding (also referred to as Staking):** Participants in the protocol need to bond a certain amount of ETH (WETH is used in the BOLD testnet) to gain the privilege of posting assertions to the rollup contracts. by locking up an ETH bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a mini-bond in their challenge. bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. +**Bonding (also referred to as Staking):** Participants in the protocol need to bond a certain amount of ETH (WETH is used in the BoLD testnet) to gain the privilege of posting assertions to the rollup contracts by locking up an ETH bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a mini-bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. ### Off-chain components - **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the onchain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers -- **State manager backend:** Software that can retrieve L2 chain states and produce commitments to WAVM histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. +- **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. -- **Validator Client:** A validator client is software that knows the correct history of the Arbitrum L2 chain, via a state manager backend, and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participate in challenging those it disagrees with. In BOLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. +- **Validator Client:** A validator client is software that knows the correct history of the Arbitrum L2 chain via a state manager backend and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participating in challenging those it disagrees with. In BoLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. -- **Challenge Manager Client:** Software that can manage the life cycles of challenges a validator is participating in. Validators need to participate in multiple challenges at once, and they need to manage individual challenge vertices correctly in order to act upon, confirm, or reject them. This and the validator responsibilities can be coupled into a single binary. +- **Challenge Manager Client:** Software that can manage the life cycles of challenges a validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. This and the validator's responsibilities can be coupled into a single binary. ### Assertions -A key responsibility for Arbitrum validators is to post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions and they contain the following information, along with some metadata not critical for this document: +A key responsibility for Arbitrum validators is to post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions, and they contain the following information, along with some metadata not critical for this document: 1. The L2 block hash being claimed @@ -99,59 +98,59 @@ A key responsibility for Arbitrum validators is to post claims about the Arbitru 3. The number of messages in the Arbitrum inbox at the time the assertion was posted onchain -The next assertion to be posted onchain must consume, at least, the specified number of inbox messages from its parent. There is a required delay, in L1 blocks, for assertion posting. Currently, this value is set to 1 hour for BOLD. +The following assertion to be posted onchain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to 1 hour for BoLD. -Assertions can be confirmed by anyone after a period of 6.4 days if they have not been challenged. In particular, assertions are used to facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion onchain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. +Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion onchain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. -To start posting assertions, a validator must become a bondr in the rollup contract. To do this, they must place a one-time bond of size N WETH that is locked in the contract until they choose to unbond. Validators can only unbond if their latest posted assertion has been confirmed. Each assertion a validator posts will become their latest bondd assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” validators’ bonds to their latest posted assertion. +Validators must first become bonders in the rollup contract before starting to post assertions. This involves placing a one-time bond of size N WETH that is locked in the contract until they choose to unbond. Validators can only unbond if their latest posted assertion has been confirmed. Each assertion a validator posts will become their latest bond assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” validators’ bonds to their latest posted assertion. -Assertions form a chain, in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted onchain. However, if a node is configured as a validator, it will have the responsibility to post the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and some other data to the ChallengeManager, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted onchain. However, if a node is configured as a validator, it will be responsible for posting the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and other data to the ChallengeManager, signaling it is disputing an assertion. #### Overflow assertions -Given there is a mandatory delay of 1 hour between assertions posted onchain, and each assertion is a claim to a certain Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up, overflow assertion needs to be posted to consume the rest of blocks above the maximum. This overflow assertion will not be subject to the mandatory 1 hour delay between assertions. +Given the mandatory delay of one hour between assertions posted onchain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up overflow assertion needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. #### Trustles Bonding Pools -A large upfront assertion bond is critical for discouraging malicious actors from attacking Arbitrum and spamming the network (e.g. delay attacks) - especially when considering the fact that malicious actors will always lose challenges and their entire bond. On the other hand, requiring such a high upfront assertion bond may be prohibitively high for a single honest entity to put up - especially since the cost to defend Arbitrum is proportional to the number of malicious entities and on-going challenges at any given point in time. +A large upfront assertion bond is critical for discouraging malicious actors from attacking Arbitrum and spamming the network (e.g., delay attacks), especially because malicious actors will always lose challenges and their entire bond. On the other hand, requiring such a high upfront assertion bond may be prohibitive for a single honest entity to put up—especially since the cost to defend Arbitrum is proportional to the number of malicious entities and ongoing challenges at any given point in time. -To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob/main/contracts/src/assertionStakingPool/AssertionStakingPoolCreator.sol) that anyone can use to deploy a trustless, bonding (or staking) pool as a way of crowdsourcing funds from others who wish to help defend Arbitrum, but who may otherwise not individually be able to put up the large upfront bond itself. +To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob/main/contracts/src/assertionStakingPool/AssertionStakingPoolCreator.sol) that anyone can use to deploy a trustless, bonding (or staking) pool as a way of crowdsourcing funds from others who wish to help defend Arbitrum, but who may otherwise not individually be able to put up the sizeable upfront bond itself. -Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion that they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (STF). If other parties agree on the assertion being correct, then they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the honest parties' assertion is confirmed by the dispute protocol, all involved entities will get their funds reimbursed and can withdraw. +Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (STF). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. -Trustless bonding pools can also be created for opening challenges and making moves on challenges, without sacrificing decentralization. +Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. ### Opening Challenges -To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, the actual start of a challenge involves creating a claim called an edge and posting it to the ChallengeManager contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a mini-bond to it, denominated in WETH for the BOLD testnet. This bond is much lower than the one required to become an assertion poster. +To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a mini-bond to it, denominated in WETH for the BoLD testnet. This bond is much lower than the one required to become an assertion poster. Anyone can open a challenge on an assertion without needing to be a bondr in the rollup contract, so long as they post a mini-bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate.t -Recall that a challenge is about a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BOLD protocol allows them to interactively narrow down their disagreement via cryptographic proofs such that Ethereum can be the final referee and claim a winner. +Recall that a challenge is a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BoLD protocol allows them to interactively narrow down their disagreement via cryptographic proofs such that Ethereum can be the final referee and claim a winner. At its core, the disagreement between validators looks something like this: -Common parent assertion: batch 5, blockhash 0xabc +- Common parent assertion: batch 5, blockhash 0xabc -Alice’s assertion: batch 10, blockhash 0x123 +- Alice’s assertion: batch 10, blockhash 0x123 -Bob’s assertion: batch 10, blockhash 0x456 +- Bob’s assertion: batch 10, blockhash 0x456 -That is, their disagreement is about an Arbitrum block somewhere between batch 5 and batch 10. Here’s how the actual challenge begins in this example: +Their disagreement is about an Arbitrum block somewhere between batch 5 and batch 10. Here’s how the actual challenge begins in this example: -Validators have to fetch all blocks in between batch 5 and batch 10 and create a Merkle commitment out of them, as a Merkle tree with 2^26 leaves. If there are fewer than 2^26 blocks in between the assertions, the last block is repeated to pad the leaves of the tree to that value. Validators then create an “edge” data structure, which contains the following fields: +Validators have to fetch all blocks between batch 5 and batch 10 and create a Merkle commitment out of them as a Merkle tree with 2^26 leaves. If there are fewer than 2^26 blocks in between the assertions, the last block is repeated to pad the leaves of the tree to that value. Validators then create an “edge” data structure, which contains the following fields: - **start_hash:** the start hash of the block from the common parent assertion -- **end_hash: **the end hash of the block at the claimed, child assertion +- **end_hash: **the end hash of the block at the claimed child assertion - **merkle_root:** the Merkle root that results from committing to a Merkle tree from the start block hash to the end block hash - **inclusion_proofs:** Merkle proofs that the start and end hashes are indeed leaves of the Merkle tree committing to a root -At the core of challenges and BOLD itself is the concept of a history commitment. +The concept of a history commitment is at the core of challenges and BoLD itself. -The validators above provide a Merkle proof of their commitment to some history, in this case, all the Arbitrum block hashes from batch 5 to batch 10. Using this tree, validators can narrow down their disagreement to a single block using Merkle proofs. +The validators above provide a Merkle proof of their commitment to some history. In this case, all the Arbitrum block hashes from batch 5 to batch 10. Using this tree, validators can narrow their disagreement to a single block using Merkle proofs. ### Challenge resolution @@ -163,9 +162,9 @@ The first validator to create an edge initiates a challenge. The smart contracts #### Bisections -When an edge is created, it claims some history from some point A to B in which validators can agree or disagree. Other validators can claim some history from point A to B’, where B’ is a different end state. A history commitment is a Merkle commitment to a list of hashes. +When an edge is created, it claims some history from point A to B, with which validators can agree or disagree. Other validators can claim some history from point A to B’, where B’ is a different end state. A history commitment is a Merkle commitment to a list of hashes. -To narrow down a disagreement, validators have to figure out what exact hash they disagree with. To do this, the game essentially takes turns between validators playing binary search. Each move here is known as a “bisection”, because each move splits a history commitment in half. +To narrow down a disagreement, validators have to figure out what exact hash they disagree with. To do this, the game essentially takes turns between validators playing binary search. Each move here is known as a “bisection” because each move splits a history commitment in half. For instance: @@ -173,15 +172,15 @@ Alice commits to 32 hashes with start = A, end = B Bob commits to 32 hashes with start = A, end = B’ -Either of them can perform a “bisection” move on their edge. For instance, if Alice “bisects” her edge E, the bisection transaction will produce two children E_1 and E_2. E_1 commits to 16 hashes from height A to B/2 and E_2 commits to 16 hashes from height B/2 to B. +Either of them can perform a “bisection” move on their edge. For instance, if Alice “bisects” her edge E, the bisection transaction will produce two children, E_1 and E_2. E_1 commits to 16 hashes from height A to B/2, and E_2 commits to 16 hashes from height B/2 to B. -A validator can make a move on an edge as long as that edge is “rivaled”. That is, the children that were just created as a result of Alice’s bisection will have increasing timers until Bob also bisects and possibly creates rivals for Alice’s edges. +A validator can make a move on an edge as long as that edge is “rivaled”. That is, the children just created due to Alice’s bisection will have increasing timers until Bob also bisects and possibly creates rivals for Alice’s edges. #### Subchallenges -The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^43. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 8.7Tb worth of hashes. Instead, BOLD plays the bisection game over different levels of granularity of this space of 2^43 hashes. +The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^43. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 8.7Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^43 hashes. -First, validators disagree over Arbitrum blocks in between two assertions. They make “edges” containing history commitments to all the blocks in between those two assertions, and play the bisection game. Once they narrow down to a single block of disagreement, they now need to find where they disagree in the actual WASM execution of the block through the Arbitrum state transition function. This is what we call the first “subchallenge”. +The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual WASM execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in *ranges* of steps. @@ -189,42 +188,42 @@ First, validators disagree over **Gigasteps** of WASM execution. That is, over r #### One step proof -Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they then need to provide something called a **one step proof**, or OSP for short. This is a proof of WASM execution showing that executing the Arbitrum state transition function at hash A leads to hash B. Ethereum then actually runs a WASM emulator using a smart contract for this step, and will declare a winner. An evil party cannot forge a one-step-proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one step proven edge will be confirmed and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one step proven edge will have an ever increasing timer until the top edge can be confirmed by time. +Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or OSP for short. This is proof of WASM execution showing that executing the Arbitrum state transition function at hash A leads to hash B. Ethereum then actually runs a WASM emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. #### Timers -Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge’s timer stops ticking the moment it has a rival edge created onchain. +Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge's timer stops ticking when a rival edge is created onchain. -Edges also have something called an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge’s children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, the assertion it claims can also be confirmed as its associated challenge has completed. A minor, but important detail is that edges also inherit the time their claimed assertion was unrivaled. +Edges also have an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge's children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, its assertion can also be confirmed as its associated challenge has completed. A minor but important detail is that edges also inherit the time their claimed assertion was unrivaled. -We believe timer inheritance from ancestor edges is fundamentally broken, as honest edges could have evil ancestors, or vice-versa and edges could steal / claim timer credit from others they should not be entitled to. The research specification goes in-depth into proven lemmas of timer inheritance and why children inheritance solves critical attack vectors. +We believe timer inheritance from ancestor edges is fundamentally broken. Honest edges could have evil ancestors or vice versa, and edges could steal/claim timer credit from others to which they should not be entitled. The research specification goes in-depth into the proven lemmas of timer inheritance and why children's inheritance solves critical attack vectors. #### Cached timer updates -The “inherited timer” value of an edge exists onchain and can be updated via a transaction. Given it is a recursive definition, it can be updated via multiple transactions. First, the lowermost edges have their timers updated, then, their parents, etc. up to the top. Validators can track information locally to avoid sending wasteful transactions and only propagate updates once they are confident their edge is confirmable by time. +An edge's "inherited timer" value exists onchain and can be updated via a transaction. Given it is a recursive definition, it can be updated via multiple transactions. First, the lowermost edges have their timers updated, then their parents, etc., up to the top. Validators can track information locally to avoid sending wasteful transactions and only propagate updates once they are confident their edge is confirmable by time. #### Confirmation -Once an edge has a total, onchain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed onchain, as simply the top-level, block challenge edge is enough to then confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one step proof. It is only complete once the claimed assertion of a challenge is confirmed. +Once an edge has a total onchain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed onchain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed. ### Bonding in Challenges -In order to create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct, and to do so, they need to put up some value called a “mini-bond”. +To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a “mini-bond.” -Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster, but still large enough such that they discourage spam attacks. The full mechanism of how mini-bond economics are decided are contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BOLD. In short, the actual cost of a bond encompasses information such as offchain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. +Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster but still large enough that they discourage spam attacks. The mechanism of how mini-bond economics are decided is contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as offchain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. Each subchallenge that is created requires placing a “mini-bond”. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the DAO treasury. Once a challenge is complete, a reimbursement process can be done for honest party bonds, while the DAO keeps evil bonds. It is important to not offer evil bonds to honest parties to prevent perverse incentives such as griefing attacks or to discourage needless competition between honest parties. ### Reimbursements of Bonds -It is important to emphasize that the reimbursement of assertion bonds for honest parties will be handled “in-band” by the protocol itself. While reimbursing honest parties for mini-bond costs and gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum DAO. There will be a procedure, published at a later date, that can be followed to calculate the reimbursements to be made for mini-bond and gas costs to honest parties. +It is important to emphasize that the reimbursement of assertion bonds for honest parties will be handled “in-band” by the protocol. While reimbursing honest parties for mini-bond costs and gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum DAO. There will be a procedure, to be published later, that can be followed to calculate the reimbursements for mini-bond and gas costs to honest parties. -Lastly, reimbursement will not be made for off-chain compute costs as we view these to be costs borne by the operator, alongside the maintenance and infra costs that regularly arise from running a node. It is also difficult to attribute computation, as honest validators that are not necessarily posting claims would still be performing similar computations if they are following a challenge. However, the costs of the on-chain bonds to participate in challenges far exceed the cost of compute required to resolve these challenges. +Lastly, reimbursement will not be made for off-chain compute costs as we view these as costs borne by the operator, alongside the maintenance and infra costs that regularly arise from running a node. It is also difficult to attribute computation, as honest validators that are not necessarily posting claims would still perform similar computations if they are following a challenge. However, the costs of the on-chain bonds to participate in challenges far exceed the cost of compute required to resolve these challenges. ### Upgrade Mechanism -For BOLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an UpgradeExecutor pattern. This is a smart contract that executes actions as the rollup owner. At the upgrade, the RollupCore.sol contract will be updated to a new BOLD one, and additional contracts needed for BOLD challenges will also be deployed such as an EdgeChallengeManager.sol. +For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an UpgradeExecutor pattern. This is a smart contract that executes actions as the rollup owner. At the upgrade, the RollupCore.sol contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed. -Assertions will then be posted to the new rollup contract. It is possible that during the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BOLD assertions support the concept of an **overflow**, allowing us to handle this situation with ease. +Assertions will then be posted to the new rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. -The upgrade pattern for an existing Arbitrum rollup to a BOLD-enabled one is tested extensively and run as part of each of our pull requests in the BOLD repository [here](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). +The upgrade pattern for an existing Arbitrum rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [here](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). From 36ea090722485d8ed352b9c9552a0e5a58d8697e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 30 Apr 2024 09:58:05 -0700 Subject: [PATCH 10/99] fix: code flags and typos --- .../bold/concepts/bold-technical-deep-dive.md | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 1c6914515..8aecd9cc9 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -34,25 +34,25 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Arbitrum Rollup Contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made -- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “mini-bonds” each time. +- **Assertions:** A claim posted to the Arbitrum Rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum Rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “mini-bonds” each time. - **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed -- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the EVM via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a WASM instruction on a pre-state. +- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the EVM via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a WASM instruction on a pre-state. -- **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's rollup contracts. +- **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's Rollup contracts. -- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn +- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn - **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist - **Challenge Period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. -- **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation +- **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the Rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation -- **Permissionless Validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. +- **Permissionless Validation:** The ability for anyone to interact with the Arbitrum Rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the Rollup contracts on Arbitrum will no longer have a permissioned list of validators. -- **Validator Software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. +- **Validator Software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain Rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. ### How BoLD Uses Ethereum @@ -70,17 +70,17 @@ All actors in the protocol have a local state from which they can produce valid ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a ChallengeManager, new in BoLD. +- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. - **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. - **OneStepProver:** A set of contracts that implement a miniature WASM VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the OSP contracts are needed for BoLD. -**Bonding (also referred to as Staking):** Participants in the protocol need to bond a certain amount of ETH (WETH is used in the BoLD testnet) to gain the privilege of posting assertions to the rollup contracts by locking up an ETH bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a mini-bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. +**Bonding (also referred to as Staking):** Participants in the protocol need to bond a certain amount of ETH (WETH is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an ETH bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a mini-bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. ### Off-chain components -- **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the onchain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers +- **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the on-chain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers - **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. @@ -96,19 +96,19 @@ A key responsibility for Arbitrum validators is to post claims about the Arbitru 2. The batch number it corresponds to for the Arbitrum chain -3. The number of messages in the Arbitrum inbox at the time the assertion was posted onchain +3. The number of messages in the Arbitrum inbox at the time the assertion was posted on-chain -The following assertion to be posted onchain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to 1 hour for BoLD. +The following assertion to be posted on-chain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to 1 hour for BoLD. -Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion onchain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. +Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion on-chain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. -Validators must first become bonders in the rollup contract before starting to post assertions. This involves placing a one-time bond of size N WETH that is locked in the contract until they choose to unbond. Validators can only unbond if their latest posted assertion has been confirmed. Each assertion a validator posts will become their latest bond assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” validators’ bonds to their latest posted assertion. +Validators must first become bondrs in the Rollup contract before starting to post assertions. This involves placing a one-time bond of size N `WETH` that is locked in the contract until they choose to unbond. Validators can only unbond if their latest posted assertion has been confirmed. Each assertion a validator posts will become their latest bond assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” validators’ bonds to their latest posted assertion. -Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted onchain. However, if a node is configured as a validator, it will be responsible for posting the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and other data to the ChallengeManager, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator, it will be responsible for posting the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. #### Overflow assertions -Given the mandatory delay of one hour between assertions posted onchain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up overflow assertion needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. +Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up overflow assertion needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. #### Trustles Bonding Pools @@ -122,9 +122,9 @@ Trustless bonding pools can also be created to open challenges and make moves on ### Opening Challenges -To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a mini-bond to it, denominated in WETH for the BoLD testnet. This bond is much lower than the one required to become an assertion poster. +To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a mini-bond to it, denominated in `WETH` for the BoLD testnet. This bond is much lower than the one required to become an assertion poster. -Anyone can open a challenge on an assertion without needing to be a bondr in the rollup contract, so long as they post a mini-bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate.t +Anyone can open a challenge on an assertion without needing to be a bondr in the Rollup contract, so long as they post a mini-bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate.t Recall that a challenge is a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BoLD protocol allows them to interactively narrow down their disagreement via cryptographic proofs such that Ethereum can be the final referee and claim a winner. @@ -158,7 +158,7 @@ The fundamental unit in a challenge is an edge data structure. #### Initiation -The first validator to create an edge initiates a challenge. The smart contracts validate the Merkle inclusion proofs and hashes provided to prove this challenge is about a specific fork in the assertion chain in the rollup contract. +The first validator to create an edge initiates a challenge. The smart contracts validate the Merkle inclusion proofs and hashes provided to prove this challenge is about a specific fork in the assertion chain in the Rollup contract. #### Bisections @@ -192,7 +192,7 @@ Once validators reach a single, individual step of disagreement after reaching t #### Timers -Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge's timer stops ticking when a rival edge is created onchain. +Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. Edges also have an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge's children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, its assertion can also be confirmed as its associated challenge has completed. A minor but important detail is that edges also inherit the time their claimed assertion was unrivaled. @@ -200,17 +200,17 @@ We believe timer inheritance from ancestor edges is fundamentally broken. Honest #### Cached timer updates -An edge's "inherited timer" value exists onchain and can be updated via a transaction. Given it is a recursive definition, it can be updated via multiple transactions. First, the lowermost edges have their timers updated, then their parents, etc., up to the top. Validators can track information locally to avoid sending wasteful transactions and only propagate updates once they are confident their edge is confirmable by time. +An edge's "inherited timer" value exists on-chain and can be updated via a transaction. Given it is a recursive definition, it can be updated via multiple transactions. First, the lowermost edges have their timers updated, then their parents, etc., up to the top. Validators can track information locally to avoid sending wasteful transactions and only propagate updates once they are confident their edge is confirmable by time. #### Confirmation -Once an edge has a total onchain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed onchain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed. +Once an edge has a total on-chain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed on-chain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed. ### Bonding in Challenges To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a “mini-bond.” -Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster but still large enough that they discourage spam attacks. The mechanism of how mini-bond economics are decided is contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as offchain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. +Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster but still large enough that they discourage spam attacks. The mechanism of how mini-bond economics are decided is contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. Each subchallenge that is created requires placing a “mini-bond”. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the DAO treasury. Once a challenge is complete, a reimbursement process can be done for honest party bonds, while the DAO keeps evil bonds. It is important to not offer evil bonds to honest parties to prevent perverse incentives such as griefing attacks or to discourage needless competition between honest parties. @@ -222,8 +222,8 @@ Lastly, reimbursement will not be made for off-chain compute costs as we view th ### Upgrade Mechanism -For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an UpgradeExecutor pattern. This is a smart contract that executes actions as the rollup owner. At the upgrade, the RollupCore.sol contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed. +For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an `UpgradeExecutor` pattern. This is a smart contract that executes actions as the Rollup owner. At the upgrade, the `RollupCore.sol` contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed. -Assertions will then be posted to the new rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. +Assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. -The upgrade pattern for an existing Arbitrum rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [here](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). +The upgrade pattern for an existing Arbitrum Rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [here](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). From 176c5003ceee1199f10608034fba3bc55d2880dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Tue, 30 Apr 2024 09:59:36 -0700 Subject: [PATCH 11/99] fix: more accurate fontmatter --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 8aecd9cc9..f0d4b5b0c 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -2,10 +2,10 @@ title: 'BoLD: a technical deep dive' sidebar_label: 'Technical deep dive' description: 'A technical deep dive into the BoLD protocol.' -user_story: 'As a user or researcher of the Arbitrum product suite, I want to understand the technical implementation of the BoLD protocol.' +user_story: 'As a user or researcher of the Arbitrum product suite, I want to understand the technical choices behind the BoLD protocol.' content_type: concept author: leeederek -target_audience: 'Developers, users and researchers interested in the Arbitrum product suite.' +target_audience: 'Developers, users and researchers interested in the Arbitrum BoLD protocol.' sme: leeederek sidebar_position: 1 --- From 32ed5f4b4bd24335e2f9dc88f2f234b50000467c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 1 May 2024 09:42:46 -0700 Subject: [PATCH 12/99] fix: yarn format --- .../bold/concepts/bold-technical-deep-dive.md | 14 +++++++------- website/sidebars.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index f0d4b5b0c..8aece4944 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -16,11 +16,11 @@ Under the hood, BoLD can offer time-bounded, permissionless validation because a To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BoLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. -Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it *can* help prove their correctness. *Anyone* in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. +Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. -If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window *and always win* within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. The current implementation of BoLD involves both on-chain and off-chain components: @@ -58,11 +58,11 @@ The current implementation of BoLD involves both on-chain and off-chain componen When it comes to implementing the protocol, BoLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain to which the full protocol can be deployed, with challenge moves performed as transactions to the protocol’s smart contracts. -A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the *results of L2 state transitions* and provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. +A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the _results of L2 state transitions_ and provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. ![diag4](../assets/KSf_Image_1.png) -*From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum.* +_From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM. @@ -70,7 +70,7 @@ All actors in the protocol have a local state from which they can produce valid ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. +- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. - **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. @@ -182,7 +182,7 @@ The number of steps of execution at which validators could disagree within a sin The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual WASM execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. -The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in *ranges* of steps. +The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “mini-bond”. The magnitudes of mini-bonds are different at each subchallenge level. @@ -192,7 +192,7 @@ Once validators reach a single, individual step of disagreement after reaching t #### Timers -Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. +Once a validator creates an edge, and if it does not have any rival edge contesting it, that edge will have a timer that ticks up called its **unrivaled timer**. Time in the protocol is measured in L1 blocks, and block numbers are used. An edge's timer stops ticking when a rival edge is created on-chain. Edges also have an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge's children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, its assertion can also be confirmed as its associated challenge has completed. A minor but important detail is that edges also inherit the time their claimed assertion was unrivaled. diff --git a/website/sidebars.js b/website/sidebars.js index 831076ac9..d72f2c3fe 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -528,7 +528,7 @@ const sidebars = { id: 'run-arbitrum-node/run-local-dev-node', label: 'Run a local dev node', }, - { + { type: 'html', value: 'Run a full Orbit node ', From 11effb135af890bf3d2defdf5d1fe2698cef12a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 1 May 2024 09:48:08 -0700 Subject: [PATCH 13/99] fix: temp removal of "Economics of dispute" to simplify PR review --- .../concepts/bold-economics-of-disputes.md | 160 ------------------ website/sidebars.js | 5 - 2 files changed, 165 deletions(-) delete mode 100644 arbitrum-docs/bold/concepts/bold-economics-of-disputes.md diff --git a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md b/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md deleted file mode 100644 index f543bf0a4..000000000 --- a/arbitrum-docs/bold/concepts/bold-economics-of-disputes.md +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: 'Economics of Disputes in Arbitrum BOLD' -sidebar_label: 'Economics of Disputes' -description: 'An in-depth explanation on BoLD economic mechanisms.' -user_story: 'As a user or researcher of the Arbitrum product suite, I want to understand how the BoLD protocol operates from an economic standpoint.' -content_type: concept -author: leeederek -target_audience: 'Developers, users and researchers interested in the Arbitrum product suite.' -sme: leeederek -sidebar_position: 1 - ---- - -*The following document explains the economics and denial-of-service mechanisms built into Arbitrum BoLD. It covers trade-offs Arbitrum has to make to enable permissionless validation, explaining the key problems in an accessible way.* - -## Background - -[Arbitrum One](https://arbitrum.io/) is currently one of the most widely adopted Ethereum scaling solutions, with [~$18bn USD in total-value-locked](https://l2beat.com/scaling/projects/arbitrum) at the time of writing. Not only do its scaling properties make it popular, such as its 250ms block times, but so do its security properties and its approach to decentralization. Currently, Arbitrum One is governed by the Arbitrum DAO, one of the most active and robust onchain organizations. - -However, Arbitrum has not yet achieved its full promise of decentralization. Currently, withdrawals from Arbitrum One back to Ethereum are verified by a permissioned list of state proposers. These proposers can still challenge invalid withdrawals, but the system prevents anyone outside this list from holding them accountable. This limits Arbitrum One to being categorized as a Stage 1 rollup, according to the [L2Beat website](https://l2beat.com/scaling/summary), meaning it still has training wheels preventing it from reaching its full potential. - -The reason why Arbitrum One is called “optimistic” is because claims about its state settle to Ethereum after a period of ~7 days, in which they can be disputed. To make an analogy, a check can be cashed right away, but can be taken to court to dispute if there is a problem within a certain time frame. Because Arbitrum’s state is deterministic, a validator that is running a node and following the chain will always know if a posted claim is invalid. A key decentralization property is allowing **anyone** that knows the correct claim to challenge invalid claims and ***win***. This preserves the correct history of Arbitrum settling to Ethereum and protects the integrity of users’ funds along with their withdrawals using a “single honest party” property. As long as there is a single entity following the chain and willing to dispute a claim, Arbitrum’s security guarantees are maintained. - -Today, the security properties of Arbitrum One are defined by the size of the permissioned set of proposers and challengers it has. These entities could collude, could settle an incorrect history, and users have no recourse aside from the Arbitrum One security council stepping in. To elevate Arbitrum One’s decentralization, it needs a different approach. - -In the fall of ‘23, Offchain Labs announced [Arbitrum BOLD](https://medium.com/offchainlabs/bold-permissionless-validation-for-arbitrum-chains-9934eb5328cc), a brand new, dispute resolution protocol built from the ground up that will bring Arbitrum chains to the next level of decentralization. BOLD, standing for Bounded Liquidity Delay, allows for **permissionless **validation of Arbitrum chains. This means the DAO can remove the list of allowed validators and let anyone challenge claims made about Arbitrum states on Ethereum, and win against them if they are incorrect. - -In this document we’ll go deep into understanding the economics and tradeoffs that Arbitrum must make in order to enable permissionless validation. - -## Settling Arbitrum States to Ethereum - -We frequently state that “Arbitrum settles its state to Ethereum”, and we’ll elaborate on what that exactly means. All Arbitrum One transactions can be recreated by reading data from Ethereum L1, as compressed batches of all L2 txs are frequently posted to Ethereum. Once a batch transaction is included in a finalized block on Ethereum, its history will never get reverted on Arbitrum. Ethereum, however, does not know if a batch posted to it refers to a correct Arbitrum history. For verifying batch integrity, there is a separate process that actually confirms batch correctness on Ethereum. - -Separately, entities known as proposers are checking the correctness of batches by following the Arbitrum chain and approximately every hour, they post something called an “assertion” which attests to the validity of a batch, saying “I have verified this batch”. As Ethereum has no knowledge of what is actually correct on Arbitrum, it allows ~7 days for anyone to come in and dispute one of these assertions. - -### Withdrawing Assets Back to Ethereum from Arbitrum - -Users of Arbitrum One that have bridged assets from Ethereum can withdraw said assets at any time. However, for this withdrawal to be fully executed, a withdrawal claim has to correspond to a confirmed assertion on Ethereum. For instance, Alice starts a withdrawal transaction on Arbitrum One, which gets posted in a batch on Ethereum. Then, a proposer will post an assertion about that batch on Ethereum 1 hour later. The assertion has a ~7 day window in which anyone can dispute it, otherwise, it will get confirmed. After that window passes, Alice will receive her withdrawn assets on Ethereum and is free to use them as she pleases. - -“Settling states'' and having a ~7 day dispute window is crucial to ensuring assets can be withdrawn safely. Allowing anyone to dispute invalid claims and wins helps keep withdrawals protected by strong security guarantees, without needing to trust a group of permissioned entities. It is this “permissionless validation” what separates Optimistic Rollups from side chains. - -### The Dispute Period - -The reason there is a dispute window for assertions about Arbitrum One on Ethereum is because Ethereum itself **has no knowledge about what is actually correct** on Arbitrum One. The two blockchains are different domains with different states. Ethereum, however, can be used as a neutral referee for parties to dispute claims about Arbitrum One. The reason why the dispute period is ~7 days is because it is seen as the maximum period of time an adversary could possibly delay Ethereum before social intervention, originally proposed by Vitalik Buterin. This window gives enough time for parties to catch invalid claims and challenge them accordingly. - -### Dispute Resolution Times - -An actual dispute occurs once a party disagrees with an assertion on Ethereum, and posts their own assertion they know to be correct. This creates a “fork” in the chain of assertions, requiring a resolution process. We’ll get into the high-level details of how disputes are resolved soon. - -![diag2](../assets/9Pr_Image_1.png) - -Once an actual dispute is ongoing, it will also take time to resolve, as, once again, Ethereum has no knowledge of the correctness of Arbitrum states. Ethereum must then give sufficient time for parties to provide their burden of proof and declare a winner. The new, Arbitrum BOLD protocol **guarantees that a dispute will be resolved within 7 days** so long as there is an honest party present to defend against invalid claims. - -As assertions have a dispute window of 7 days, and disputes require an additional 7 days to resolve, a dispute made at the last second would** delay assertion confirmation to a maximum of 14 days**, or 2 weeks. BOLD is the only dispute protocol we are aware of that guarantees this bound. - -### The Cost of Delaying Withdrawals - -Delaying withdrawals incurs opportunity cost and a worse user experience for users that want to withdraw their assets. In the happy case, where no disputes exist, withdrawals already have a baked-in, 7 day delay. A dispute incurs an additional 7 days on top of that maximum. The problem is that disputes delay *all *pending withdrawals from Arbitrum One back to Ethereum, not just a single claim. As such, **disputing a claim must have a cost for the initiator** proportional to the opportunity cost they impose on Arbitrum users. - -#### Requiring a Bond to Become a Proposer - -The entities responsible for posting assertions about Arbitrum state to Ethereum are called proposers. If posting assertions were free, anyone could create conflicting assertions to always delay withdrawals by 14 days instead of 7. As such, Arbitrum requires proposers to put in a “security deposit”, known as a **bond**, to be allowed to post assertions. Proposers can withdraw their bond as soon as their latest posted assertion has been confirmed, and end their responsibilities. - -#### Pricing Bonds - -Ensuring assertions are frequently posted is a requirement for Arbitrum, but at the same time, it should not be a privilege that is easily obtained. In terms of pricing this “security deposit” for Arbitrum proposers, we choose to do so based on opportunity cost. - -To be extremely conservative, in a bank-run scenario, the [Arbitrum One bridge](https://etherscan.io/address/0x8315177ab297ba92a06054ce80a67ed4dbd7ed3a) contains approximately $5.4bn worth of assets at the time of writing on April 15th, 2024. Assuming funds could earn a 5% APY if invested, the opportunity cost of 1 extra week of delay is approximately $5,200,000 USD. Given this scenario, we recommend a bond for assertion posters somewhere in the range of ~$2.5M - $5M. - -Honest parties can always withdraw their bond once their assertions are confirmed. **However, adversaries will entirety of their bond if they post invalid claims** once a challenge is complete**.** A large bond size drastically improves the economic security of the system based on these two axes. - -#### Centralization Concerns - -Requiring a high bond to post assertions about Arbitrum seems centralizing, as we are replacing a whitelist of proposers with instead a system that requires a lot of money to participate in. However, **BOLD ships with a trustless bonding pool** for assertion posting. That is, any group of honest parties can pool funds into a simple contract that will post an assertion to Ethereum without needing to trust each other. We believe that making it easy to pool the funds to become an assertion poster, without needing trust to dispute invalid claims, does not fundamentally affect the safety or decentralization of BOLD. What’s most important is that any entity can challenge a proposer of Arbitrum states. - -We believe optimizing for the unhappy case is more important than the happy case. As there only needs to be one honest assertion poster, we believe it falls into the security budget of the chain to price in a bond to become a proposer. It* should* be expensive to delay Arbitrum One withdrawals, and it should also have a high barrier to entry to perform a key responsibility. As long as disputes can be made in a trustless manner, and trustless pools are available in production, we claim the security properties of assertion posting hold equally. - -In production, we expect there to be very few, if not just one proposer. - -## Resolving Disputes - -One of the core properties BOLD achieves is providing a fixed, upper-bound for dispute resolution times. This section will discuss the constraints required to achieve this from first principles. - -### Dispute Game Overview - -Every game between adversarial parties needs a referee – that is, a neutral party that can enforce the rules to declare a fair winner. Arbitrum BOLD relies on Ethereum as its referee, for its properties as the most decentralized, censorship resistant smart contract chain in the world. - -When a dispute happens about Arbitrum One assertions on Ethereum, there is a protocol for resolving them. A dispute, at its core, is about the blockhash of an Arbitrum One block at a given height. Ethereum does not know which claim is correct, and instead, relies on a dispute game to be played out. The game involves different parties making claims with proof to eventually narrow down their disagreement to a single step of execution within the execution of a block, called a one step proof (OSP). Ethereum can then verify this OSP by itself and declare a winner as the neutral referee -. - -The “rules” of the dispute involve parties making claims with proofs to reach the single point of disagreement. Parties “narrow down” their claims via moves called bisections. After a party has made a bisection, it has nothing else left to do until another party comes in and counters it. The core of the system is that an honest party winning a one step proof leaves the evil party with no other moves to make. Once the honest party has accumulated enough time not-countered, it will be declared the winner. - -Compared to other dispute protocols, however, BOLD is **not** a dispute between two specific Ethereum addresses, such as Alice and Bob. Instead, it is a dispute between an absolute, correct history vs. an incorrect one. Claims in BOLD are not attached to a particular address or validator, but instead to Merkle commitments of an Arbitrum chain’s history. If Alice and Charlie are both honest, and Bob is malicious, Alice and Charlie can play the game as part of a single “team”. If Alice goes offline in the middle of a dispute game, for instance, Charlie can continue resolving the game in the honest team’s favor at any time, because Charlie and Alice being honest means they will claim and make moves on the correct history. This is why we say BOLD enables “trustless cooperation”, as there is no need for communication between parties that are honest. We believe committing a set of chain history hashes instead of a specific hash at a moment in time is crucial for securing dispute protocols. - -### Spamming the Dispute Game - -BOLD is a dispute game in which the party that has accumulated ~7 days “not-countered” wins. That is, parties are incentivized to counter any new claims as soon as they appear to “block” their rivals from increasing their timers. For honest parties, responding to claims may sometimes require offchain computational work, which needs access to computational resources such as CPUs. However, evil parties can just make claims that are eventually found to be junk while making honest parties do actual work. - -Because evil parties can submit junk that makes honest parties do work, there has to be an economic cost associated with making moves in the dispute game. That is, we need a way to prevent **spam attacks **in dispute games. - -#### The Cost of Moves - -When thinking about how to price the bonds required to make claims within disputes, we essentially consider the marginal costs that the honest party incurs for each claim an evil party makes. In the BOLD research paper, this comes out to include information such as the number of adversary moves, multiplied by the gas cost of making bisections, making claims, and some estimates of the offchain computational costs. We deem this the **marginal cost** of a party in a dispute. - -![diag2](../assets/csI_Image_2.png) - -For instance, say we have two, 1 meter sticks that seem identical, and we want to figure out where they differ. It turns out that they seem identical at the centimeter level, so we need to go down to the millimeter level, then the micrometer level, and then figure out where they differ at the *nanometer* level. - -This is what BOLD does over the space of disputes. Parties play the same game at different levels of granularity. At the centimeter level, each centimeter could trigger a millimeter dispute, and each millimeter dispute could have many micrometer disputes, etc. This fans out to a large number of potential dispute games unless spam is discouraged. - -#### Preventing Spam - -Given Ethereum knows nothing about which claims are honest or evil until a one step proof is reached, then how can the protocol detect spam and discourage it? A key insight is that honest parties only need to make one honest claim. Honest parties will never spam and create thousands of conflicting claims with themselves. Given this, we can put a price tag on making moves by looking at something called the “resource ratio” between honest and evil parties, as defined in the BOLD research paper - -![](../assets/BnF_Image_3.png) - -This ratio is essentially the gas + staking (or bonding) marginal costs of the adversary to the honest party. This means that certain values input into the equations can lead to **different ratios**. For instance, we can say the adversary has to pay **10x **the marginal costs of the honest party. However, aiming to increase this ratio significantly by plugging in different values leads to higher costs for all parties. - -#### Dispute Challenge Bonds - -BOLD also requires parties to lock up some capital called a challenge bond when making certain moves within a dispute. Pricing these challenge bonds helps us achieve a high resource ratio of evil parties to honest parties. - -It is clear that if we can make the cost to the evil party some multiplier of the honest party, we get significant security benefits. For instance, imagine if a $1 billion dollar attack can be defended by simply pooling together $10 million dollars. Is it possible to achieve such a ratio? Recall that more important than this ratio is the fact that the evil party stands to lose their entire bond compared to honest parties, which will get their bonds refunded. - -Let’s explore the limitations of making the cost to evil parties high vs. that of the honest parties. - -That is, if we aim to have a constant resource ratio > 1, we have to do the following: if the adversary makes N stakes at any level, they can force the honest party to make N stakes at the next level down where the adversary can choose not to place any bonds at all. In terms of resource ratio, to make the adversary always pay 10x in bonding, we need to make the bond amount at one level 10x more than the next. As there are multiple levels, the equations for the bond size include an exponential factor on the desired, constant resource ratio > 1. - -Below, we plot the bond size vs. the resource ratio of evil to honest costs. The source for these equations is both in the research paper and plotted [here](https://www.desmos.com/calculator/digjlq4vly). - -![diag2](../assets/CRA_Image_4.png) - -If we desire a constant resource ratio of evil to honest costs > 1, the required bond size in ETH increases as a polynomial at a particular challenge level. - -#### Trade Offs - -Having a 1000x resource ratio would be nice in theory, but would unfortunately require a bond of 1M ETH ($3.5bn) to open a dispute in the first place, which is unreasonable. Instead, we can explore a more feasible ratio of 10x. - -The tradeoff here is the higher the resource ratio we want, the more expensive it is for both honest and evil parties to make claims in disputes. However, claims can **always be made** through a **trustless pool**. Honest parties can pool together funds to participate in disputes. - -#### The Sweet Spot - -We estimate that at a resource ratio of 10x, the bond required to resolve a single adversarial claim in a dispute would be approximately 1110 ETH for the honest parties. The DAO could then consider the cost of incentivizing a single honest staker in the happy case to be the **security budget of the chain**. This means defending against a $1 billion attack would require $100M total to defend, which would all be refunded while the attacker would lose all $1bn. - -## Arbitrum Nova - -Arbitrum Nova has a much smaller total-value-locked than Arbitrum One at the time of writing, with Arbitrum One having more than 381x the value of Nova. Large bond prices for Nova are hard to rationalize, given the amount that is held by the chain is much smaller than Arbitrum One. - -Instead, we recommend that Arbitrum Nova remain with permissioned validation, as it already uses a data-availability committee that has a 2 of N trust assumption. Moreover, this committee can also run validators which enables features such as fast confirmations on the chain. - -## Thinking About Incentives - -Although we have made claims with hard numbers about how to price disputes and withdrawal delays in Arbitrum BOLD, we also take a step back and think about the game theoretical assumptions we are making. Arbitrum One is a complex protocol used by many groups of people, with many different incentives. The research team at Offchain Labs, has spent considerable effort studying the game theory of validators in Optimistic Rollup. Honest parties represent everyone that has funds onchain, and they have a huge amount to gain by winning the challenge - as they can prevent the loss of their assets rather than losing them. - -A more complex model is proposed which considers all parties staking and their associated costs created by -and Ed Felten in their paper [“Incentive Schemes for Rollup Validators”](https://arxiv.org/abs/2308.02880). The paper looks at what incentives are needed to get parties to check whether assertions are correct. It finds that there is no pure strategy Nash equilibrium, and only a mixed equilibrium if there is no incentive for honest validators. However, the research showed a pure strategy equilibrium can be reached if honest parties are incentivized to **check** results. The problem of honest validators “freeriding” and not checking is well-documented as the [verifier’s dilemma](https://www.smithandcrown.com/glossary/verifiers-dilemma). We believe future iterations of BOLD could include “attention challenges” that reward honest validators for also doing their job. - -## Conclusion - -This paper summarizes the rationale behind choosing bond sizes and the cost of spam prevention in Optimistic Rollup dispute protocols. We recommend that bond sizes be high enough to discourage challenges from ever being opened at all, as evil parties will always stand to lose when playing the game. As Arbitrum BOLD does not tie disputes to specific addresses, honest parties can have trustless cooperation to resolve disputes if desired. We posit that making the cost of the evil parties be 10x that of the honest party leads to nice economic properties that help us reason about how to price bonds. Finally, we look at a high-level game theory discussion of Optimistic Rollups and argue that solving the verifier’s dilemma by incentives to honest validators is an important addition to work towards. diff --git a/website/sidebars.js b/website/sidebars.js index d72f2c3fe..e14618a5f 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -844,11 +844,6 @@ const sidebars = { id: 'bold/concepts/bold-technical-deep-dive', label: 'Technical deep dive', }, - { - type: 'doc', - id: 'bold/concepts/bold-economics-of-disputes', - label: 'Economics of disputes', - }, { type: 'link', href: 'https://github.com/OffchainLabs/bold', From cc23e27b4af0512c00dd88fff05989a440f47319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 1 May 2024 09:57:44 -0700 Subject: [PATCH 14/99] fixed: more explicit names for css img attributes --- website/src/css/partials/_content-body.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/src/css/partials/_content-body.scss b/website/src/css/partials/_content-body.scss index 0bd0fa0ee..9cfdc1442 100644 --- a/website/src/css/partials/_content-body.scss +++ b/website/src/css/partials/_content-body.scss @@ -49,16 +49,16 @@ article { font-weight: 600; } - img[alt='diag1'] { + img[alt='200px-img'] { width: 200px; } - img[alt='diag2'] { + img[alt='400px-img'] { width: 400px; } - img[alt='diag3'] { + img[alt='600px-img'] { width: 600px; } - img[alt='diag4'] { + img[alt='900px-img'] { width: 900px; } From 5c7c015675f169a92f3b8e1a8405f46de44f522d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 1 May 2024 09:58:32 -0700 Subject: [PATCH 15/99] fix: public preview banner + new img css attribute name --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 8aece4944..499254b69 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -10,6 +10,11 @@ sme: leeederek sidebar_position: 1 --- +import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md'; + + + + ## Overview Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond on the correct state and, through interactive fraud proofs, prove their claim is correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. @@ -60,7 +65,7 @@ When it comes to implementing the protocol, BoLD needs to be deployed on a credi A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the _results of L2 state transitions_ and provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. -![diag4](../assets/KSf_Image_1.png) +![900px-img](../assets/KSf_Image_1.png) _From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ From 118da84bbb65ec52756dbea4552a78008f8ea6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 1 May 2024 12:53:57 -0700 Subject: [PATCH 16/99] fix: format --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 499254b69..e07c52cc9 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -29,11 +29,11 @@ If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (al The current implementation of BoLD involves both on-chain and off-chain components: -1. Rollup contracts to be deployed on Ethereum +1. Rollup contracts to be deployed on Ethereum. -2. New challenge management contracts to be deployed on Ethereum +2. New challenge management contracts to be deployed on Ethereum. -3. [Honest validator software](https://github.com/offchainlabs/bold) equipped to submit assertions and perform challenge moves on any assertions it disagrees with. The honest validator is robust enough to win against malicious entities and always ensures honest assertions are the only ones confirmed on-chain +3. [Honest validator software](https://github.com/offchainlabs/bold) equipped to submit assertions and perform challenge moves on any assertions it disagrees with. The honest validator is robust enough to win against malicious entities and always ensures honest assertions are the only ones confirmed on-chain. ### Key terminology From 6c4a4adad83aac034b58b9bf88f1e485f03f2506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:12:17 -0700 Subject: [PATCH 17/99] fix: preview banner: BOLD > BoLD --- .../bold/partials/_bold-public-preview-banner-partial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arbitrum-docs/how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md b/arbitrum-docs/how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md index 1a0df3c76..2d8bc28c6 100644 --- a/arbitrum-docs/how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md +++ b/arbitrum-docs/how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md @@ -1,7 +1,7 @@ :::caution ALPHA RELEASE, PUBLIC PREVIEW DOCS -The BOLD dispute protocol is currently deployed on a public testnet and tagged as an `alpha` release. The code has not been audited and **should not be used in production scenarios**. -Please note that the public testnet is intended for Arbitrum users and researchers to test and experiment with the BOLD dispute protocol for the purposes of education and hardening the protocol via the surfacing of bugs. The public testnet may be paused and its parameters updated at any time in response to scenarios that impact the network and its ability to fulfill its function as a working, reliable test environment. This documentation is currently in [public preview](../public-preview-expectations.md). +The BoLD dispute protocol is currently deployed on a public testnet and tagged as an `alpha` release. The code has not been audited and **should not be used in production scenarios**. +Please note that the public testnet is intended for Arbitrum users and researchers to test and experiment with the BoLD dispute protocol for the purposes of education and hardening the protocol via the surfacing of bugs. The public testnet may be paused and its parameters updated at any time in response to scenarios that impact the network and its ability to fulfill its function as a working, reliable test environment. This documentation is currently in [public preview](../public-preview-expectations.md). To provide feedback, click the _Request an update_ button at the top of this document, [join the Arbitrum Discord](https://discord.gg/arbitrum), or reach out to our team directly by completing [this form](http://bit.ly/3yy6EUK). From 605de80f536d114cf1913f9e2c56e2c37efdfe55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:19:49 -0700 Subject: [PATCH 18/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index e07c52cc9..9237747d0 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -17,7 +17,7 @@ import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_ ## Overview -Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond on the correct state and, through interactive fraud proofs, prove their claim is correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. +Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond capital to the correct state and, through interactive fraud proofs, have their claim proven correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BoLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. From 8835d7729c4ebd1a79f3e715541d018ffbb0b1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:20:45 -0700 Subject: [PATCH 19/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 9237747d0..e2a4d0cae 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -39,7 +39,7 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Arbitrum Rollup Contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made -- **Assertions:** A claim posted to the Arbitrum Rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum Rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “mini-bonds” each time. +- **Assertions:** A claim posted to the Arbitrum Rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum Rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “challenge-bonds” each time. - **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed From c1a3d6e26ebed2180e3e62eac68c4c4510d5ee04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:21:41 -0700 Subject: [PATCH 20/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index e2a4d0cae..21e770e5f 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -85,7 +85,7 @@ All actors in the protocol have a local state from which they can produce valid ### Off-chain components -- **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the on-chain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers +- **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the on-chain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers. - **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. From ec61ce21c1262fc75383b7066691692eccf02609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:22:21 -0700 Subject: [PATCH 21/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 21e770e5f..fd7615387 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -95,7 +95,7 @@ All actors in the protocol have a local state from which they can produce valid ### Assertions -A key responsibility for Arbitrum validators is to post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions, and they contain the following information, along with some metadata not critical for this document: +A key responsibility for Arbitrum validators is to post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions. Assertions contain information, most critically: 1. The L2 block hash being claimed From 3e5a0603ea252baf10cc2c3ffdb42a5a38c8a322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:23:39 -0700 Subject: [PATCH 22/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index fd7615387..46a189d15 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -107,7 +107,7 @@ The following assertion to be posted on-chain must consume, at least, the specif Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion on-chain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. -Validators must first become bondrs in the Rollup contract before starting to post assertions. This involves placing a one-time bond of size N `WETH` that is locked in the contract until they choose to unbond. Validators can only unbond if their latest posted assertion has been confirmed. Each assertion a validator posts will become their latest bond assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” validators’ bonds to their latest posted assertion. +Validators must become proposers in the Rollup contract before being allowed to post assertions. This involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator, it will be responsible for posting the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. From bde19f2bc022090402a868a56b766ac741998376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:24:58 -0700 Subject: [PATCH 23/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 46a189d15..d3883e2f2 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -109,7 +109,7 @@ Anyone can confirm assertions after a period of 6.4 days if they have not been c Validators must become proposers in the Rollup contract before being allowed to post assertions. This involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. -Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator, it will be responsible for posting the correct, rival assertion to any invalid one it just observed. The validator will also initiate a challenge by posting a mini-bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. #### Overflow assertions From 35fa686e3c8119bd645f692a694ece9f5dd53502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:25:54 -0700 Subject: [PATCH 24/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index d3883e2f2..102c64288 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -221,7 +221,7 @@ Each subchallenge that is created requires placing a “mini-bond”. The first, ### Reimbursements of Bonds -It is important to emphasize that the reimbursement of assertion bonds for honest parties will be handled “in-band” by the protocol. While reimbursing honest parties for mini-bond costs and gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum DAO. There will be a procedure, to be published later, that can be followed to calculate the reimbursements for mini-bond and gas costs to honest parties. +It is important to emphasize that the reimbursement of assertion bonds and challenge bonds for honest parties will be handled “in-band” by the protocol. While reimbursing honest parties for gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum Foundation. There will be a procedure, to be published later, that can be followed to calculate the reimbursements for gas costs to honest parties. Lastly, reimbursement will not be made for off-chain compute costs as we view these as costs borne by the operator, alongside the maintenance and infra costs that regularly arise from running a node. It is also difficult to attribute computation, as honest validators that are not necessarily posting claims would still perform similar computations if they are following a challenge. However, the costs of the on-chain bonds to participate in challenges far exceed the cost of compute required to resolve these challenges. From e82de61e300af79f3472d2012ccf6bcfd59a5297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:26:11 -0700 Subject: [PATCH 25/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 102c64288..7b0a1f078 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -53,6 +53,8 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Challenge Period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. +- **Edge**: Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. + - **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the Rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation - **Permissionless Validation:** The ability for anyone to interact with the Arbitrum Rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the Rollup contracts on Arbitrum will no longer have a permissioned list of validators. From 667eb2cb87a2e338254dd67532013fee06a514ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:26:30 -0700 Subject: [PATCH 26/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 7b0a1f078..0576373f5 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -129,7 +129,7 @@ Trustless bonding pools can also be created to open challenges and make moves on ### Opening Challenges -To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a mini-bond to it, denominated in `WETH` for the BoLD testnet. This bond is much lower than the one required to become an assertion poster. +To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet). This bond is much lower than the one required to become an assertion poster. Anyone can open a challenge on an assertion without needing to be a bondr in the Rollup contract, so long as they post a mini-bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate.t From 684094643caa081923eb3b94ba689bf26c2f7ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:26:43 -0700 Subject: [PATCH 27/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 0576373f5..aec8e8c41 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -131,7 +131,7 @@ Trustless bonding pools can also be created to open challenges and make moves on To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet). This bond is much lower than the one required to become an assertion poster. -Anyone can open a challenge on an assertion without needing to be a bondr in the Rollup contract, so long as they post a mini-bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate.t +Anyone can open a challenge on an assertion without needing to be a bonder in the Rollup contract, so long as they post a challenge bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate. Recall that a challenge is a fundamental disagreement about an assertion posted to the Arbitrum chain. At its core, validators disagree about the blockhash at a certain block number, essentially, and the BoLD protocol allows them to interactively narrow down their disagreement via cryptographic proofs such that Ethereum can be the final referee and claim a winner. From ea125b5cff6953518c5f29bfbfa4779844167b81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:26:56 -0700 Subject: [PATCH 28/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index aec8e8c41..c7190e59d 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -139,7 +139,7 @@ At its core, the disagreement between validators looks something like this: - Common parent assertion: batch 5, blockhash 0xabc -- Alice’s assertion: batch 10, blockhash 0x123 +- Alice’s assertion: `batch 10, blockhash 0x123` - Bob’s assertion: batch 10, blockhash 0x456 From 0512d29b16805bd8194eed69e12755363574d9f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:27:04 -0700 Subject: [PATCH 29/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index c7190e59d..66707b0ae 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -141,7 +141,7 @@ At its core, the disagreement between validators looks something like this: - Alice’s assertion: `batch 10, blockhash 0x123` -- Bob’s assertion: batch 10, blockhash 0x456 +- Bob’s assertion: `batch 10, blockhash 0x456` Their disagreement is about an Arbitrum block somewhere between batch 5 and batch 10. Here’s how the actual challenge begins in this example: From 9c03b6f40ecc95782c715c94676e3c059d9888fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:27:22 -0700 Subject: [PATCH 30/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 66707b0ae..e9522b4e0 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -191,7 +191,7 @@ The bisection game is an iterative process. Initially, validators disagree over The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. -First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “mini-bond”. The magnitudes of mini-bonds are different at each subchallenge level. +First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. #### One step proof From 34e4e5be4d04bf64d33ffefb3898862339be56bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:27:46 -0700 Subject: [PATCH 31/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index e9522b4e0..eb27212c0 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -203,7 +203,7 @@ Once a validator creates an edge, and if it does not have any rival edge contest Edges also have an **inherited timer**, which is the sum of its unrivaled timer + the minimum inherited timer of an edge's children (recursive definition). Once one of the top-level edges that initiated a challenge has achieved an inherited timer >= a CHALLENGE_PERIOD (6.4 days), it can be confirmed. At this point, its assertion can also be confirmed as its associated challenge has completed. A minor but important detail is that edges also inherit the time their claimed assertion was unrivaled. -We believe timer inheritance from ancestor edges is fundamentally broken. Honest edges could have evil ancestors or vice versa, and edges could steal/claim timer credit from others to which they should not be entitled. The research specification goes in-depth into the proven lemmas of timer inheritance and why children's inheritance solves critical attack vectors. +We believe timer inheritance from ancestor edges is fundamentally broken. Honest edges could have evil ancestors or vice versa, and edges could steal/claim timer credit from others to which they should not be entitled. The [research specification](https://arxiv.org/abs/2404.10491) goes in-depth into the proven lemmas of timer inheritance and why children's inheritance solves critical attack vectors. #### Cached timer updates From 1499f4a51118dd6fdbc31b77858ac33bacc7362a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:28:02 -0700 Subject: [PATCH 32/99] Update website/sidebars.js Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- website/sidebars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/sidebars.js b/website/sidebars.js index e14618a5f..0d86f73a2 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -837,7 +837,7 @@ const sidebars = { { type: 'link', href: 'https://arxiv.org/abs/2404.10491', - label: 'BOLD Whitepaper', + label: 'BoLD Whitepaper', }, { type: 'doc', From fce305e30b54ab0f5e014fb9dbedfc265f73d57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:28:20 -0700 Subject: [PATCH 33/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index eb27212c0..c0f7c20c1 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -215,7 +215,7 @@ Once an edge has a total on-chain timer greater than or equal to a challenge per ### Bonding in Challenges -To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a “mini-bond.” +To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster but still large enough that they discourage spam attacks. The mechanism of how mini-bond economics are decided is contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. From 47ac383d13232431759358923509219c3c0f036b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:28:39 -0700 Subject: [PATCH 34/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index c0f7c20c1..3935bf657 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -217,7 +217,7 @@ Once an edge has a total on-chain timer greater than or equal to a challenge per To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. -Mini-bonds are named as such because they are a lot smaller than the base bond required to become an assertion poster but still large enough that they discourage spam attacks. The mechanism of how mini-bond economics are decided is contained in the economics deep dive in this directory, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + griefing ratios between honest and evil parties to discourage spam. +Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. Each subchallenge that is created requires placing a “mini-bond”. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the DAO treasury. Once a challenge is complete, a reimbursement process can be done for honest party bonds, while the DAO keeps evil bonds. It is important to not offer evil bonds to honest parties to prevent perverse incentives such as griefing attacks or to discourage needless competition between honest parties. From 516a7e974126eac1b07096db5ab774f6d53383ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:28:54 -0700 Subject: [PATCH 35/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 3935bf657..da30d02dc 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -219,7 +219,7 @@ To create a challenge, there must be a fork in the Arbitrum assertion chain smar Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. -Each subchallenge that is created requires placing a “mini-bond”. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the DAO treasury. Once a challenge is complete, a reimbursement process can be done for honest party bonds, while the DAO keeps evil bonds. It is important to not offer evil bonds to honest parties to prevent perverse incentives such as griefing attacks or to discourage needless competition between honest parties. +Each subchallenge that is created requires depositing a challenge bond. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the ArbitrumDAO treasury. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol. It is important to not offer bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks or to discourage needless competition between honest parties. ### Reimbursements of Bonds From d9a39ebcd2a2f27b62d181f90d2f472f5b7941a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:29:09 -0700 Subject: [PATCH 36/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index da30d02dc..b8cd15a72 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -137,7 +137,7 @@ Recall that a challenge is a fundamental disagreement about an assertion posted At its core, the disagreement between validators looks something like this: -- Common parent assertion: batch 5, blockhash 0xabc +- Common parent assertion: `batch 5, blockhash 0xabc` - Alice’s assertion: `batch 10, blockhash 0x123` From 80aedad1798dba043679277aa768db64bb7eee18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 8 May 2024 15:29:54 -0700 Subject: [PATCH 37/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index b8cd15a72..965e9cb66 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -83,7 +83,7 @@ All actors in the protocol have a local state from which they can produce valid - **OneStepProver:** A set of contracts that implement a miniature WASM VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the OSP contracts are needed for BoLD. -**Bonding (also referred to as Staking):** Participants in the protocol need to bond a certain amount of ETH (WETH is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an ETH bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a mini-bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. +**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. ### Off-chain components From 26d9aa74f0c0ea704316fc19395da1e8f69ca593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 13 May 2024 09:33:14 -0700 Subject: [PATCH 38/99] feat: added quicklooks --- .../bold/concepts/bold-technical-deep-dive.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 965e9cb66..28c82ba50 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -17,13 +17,13 @@ import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_ ## Overview -Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond capital to the correct state and, through interactive fraud proofs, have their claim proven correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. +Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond capital to the correct state and, through interactive fraud proofs, have their claim proven correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BoLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. -The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. +The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. @@ -71,7 +71,7 @@ A helpful mental model for understanding the system is that it uses Ethereum its _From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ -In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM. +In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM. All actors in the protocol have a local state from which they can produce valid proofs, and all honest parties will have the same local state. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth. @@ -111,7 +111,7 @@ Anyone can confirm assertions after a period of 6.4 days if they have not been c Validators must become proposers in the Rollup contract before being allowed to post assertions. This involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. -Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. #### Overflow assertions @@ -125,7 +125,7 @@ To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (STF). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. -Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. +Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. ### Opening Challenges @@ -215,9 +215,9 @@ Once an edge has a total on-chain timer greater than or equal to a challenge per ### Bonding in Challenges -To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. +To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. -Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. +Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. Each subchallenge that is created requires depositing a challenge bond. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the ArbitrumDAO treasury. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol. It is important to not offer bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks or to discourage needless competition between honest parties. From b5bba50841c34a553338dd8a26fc833e2ec46296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Mon, 20 May 2024 10:26:18 -0700 Subject: [PATCH 39/99] fix: reformat: code fences --- .../bold/concepts/bold-technical-deep-dive.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 28c82ba50..b35237c38 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -43,11 +43,11 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed -- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the EVM via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a WASM instruction on a pre-state. +- **Fraud Proofs:** Proofs of a single step of ``WAVM`` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. - **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's Rollup contracts. -- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn +- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of ``WETH``. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn - **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist @@ -71,7 +71,7 @@ A helpful mental model for understanding the system is that it uses Ethereum its _From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ -In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called WASM and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to WASM. +In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. All actors in the protocol have a local state from which they can produce valid proofs, and all honest parties will have the same local state. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth. @@ -81,7 +81,7 @@ All actors in the protocol have a local state from which they can produce valid - **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. -- **OneStepProver:** A set of contracts that implement a miniature WASM VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the OSP contracts are needed for BoLD. +- **OneStepProver:** A set of contracts that implement a miniature `WASM` VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the `OSP` contracts are needed for BoLD. **Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. @@ -123,7 +123,7 @@ A large upfront assertion bond is critical for discouraging malicious actors fro To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob/main/contracts/src/assertionStakingPool/AssertionStakingPoolCreator.sol) that anyone can use to deploy a trustless, bonding (or staking) pool as a way of crowdsourcing funds from others who wish to help defend Arbitrum, but who may otherwise not individually be able to put up the sizeable upfront bond itself. -Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (STF). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. +Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (`STF`). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. @@ -187,15 +187,15 @@ A validator can make a move on an edge as long as that edge is “rivaled”. Th The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^43. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 8.7Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^43 hashes. -The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual WASM execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. +The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual `WASM` execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. -First, validators disagree over **Gigasteps** of WASM execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. +First, validators disagree over **Gigasteps** of `WASM` execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. #### One step proof -Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or OSP for short. This is proof of WASM execution showing that executing the Arbitrum state transition function at hash A leads to hash B. Ethereum then actually runs a WASM emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. +Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is proof of `WASM` execution showing that executing the Arbitrum state transition function at hash A leads to hash B. Ethereum then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. #### Timers From f10854026deda73b63159aa4a33175e66ac0229f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 22 May 2024 16:03:01 -0700 Subject: [PATCH 40/99] fix: faulty code fences --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index b35237c38..0dddab729 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -43,11 +43,11 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed -- **Fraud Proofs:** Proofs of a single step of ``WAVM`` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. +- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. - **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's Rollup contracts. -- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of ``WETH``. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn +- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn - **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist From d2f314ac79d95774ed065de7bee8ed860f68bc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 22 May 2024 18:39:05 -0700 Subject: [PATCH 41/99] fix: sentence-casing --- .../bold/concepts/bold-technical-deep-dive.md | 62 +++++++------------ 1 file changed, 24 insertions(+), 38 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 0dddab729..c3b5c018e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -37,31 +37,20 @@ The current implementation of BoLD involves both on-chain and off-chain componen ### Key terminology -- **Arbitrum Rollup Contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made - -- **Assertions:** A claim posted to the Arbitrum Rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum Rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “challenge-bonds” each time. - -- **Validating Bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed - -- **Fraud Proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the Rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. - -- **Challenge Protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's Rollup contracts. - -- **Bonding of funds:** Creating an assertion in the Rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn - -- **Honest Validator**: An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist - -- **Challenge Period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. - -- **Edge**: Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. - -- **Delay Attacks:** In a delay attack, a malicious party (or group of parties) acts within the Rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation - -- **Permissionless Validation:** The ability for anyone to interact with the Arbitrum Rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the Rollup contracts on Arbitrum will no longer have a permissioned list of validators. - -- **Validator Software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain Rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. - -### How BoLD Uses Ethereum +- **Arbitrum rollup contracts:** The set of smart contracts on Ethereum L1 that serve as both the data availability layer for Arbitrum and for confirming the rollup's state assertions after a challenge period has passed for each assertion made. +- **Assertions:** A claim posted to the Arbitrum rollup contracts on Ethereum L1 about the Arbitrum L2 execution state. Each claim consumes messages from the Arbitrum rollup inbox contract. Each assertion can be confirmed after a period of 6.4 days, and anyone can challenge it during that period. A BoLD challenge will add an additional upper bound of 6.4 days to confirm an assertion. If an assertion is challenged near the end of 6.4 days, an additional 6.4 days will be needed to complete the challenge. Gaining the right to post assertions requires placing a large, one-time bond, which can get taken away in the case of losing a challenge to a competing assertion. Opening challenges requires opening smaller “challenge-bonds” each time. +- **Validating bridge:** The smart contract that leverages Ethereum's security and censorship-resistance to unlock bridged assets from L2 back to L1. Assets can be unlocked after an assertion has been posted and confirmed after a challenge period has passed. +- **Fraud proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. +- **Challenge protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's rollup contracts. +- **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn. +- **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist. +- **Challenge period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. +- **Edge:** Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. +- **Delay attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation. +- **Permissionless validation:** The ability for anyone to interact with the Arbitrum rollup contracts on Ethereum to both post assertions and challenge others' assertions without needing permission. With the release of BoLD, the rollup contracts on Arbitrum will no longer have a permissioned list of validators. +- **Validator software:** Software that has knowledge of the correct Arbitrum L2 state at any point. It tracks the on-chain rollup contracts for assertions posted and will automatically initiate challenges on malicious assertions if configured to do so by the user. It will participate in new and existing challenges and make moves as required by the protocol to win against any number of malicious entities. Its goal is to ensure only honest assertions about Arbitrum's state are confirmed on Ethereum. All Arbitrum full nodes are watchtower validators by default. This means they do not post claims or assertions unless configured to do so but will warn in case invalid assertions are detected on-chain. + +### How BoLD uses Ethereum When it comes to implementing the protocol, BoLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain to which the full protocol can be deployed, with challenge moves performed as transactions to the protocol’s smart contracts. @@ -71,29 +60,26 @@ A helpful mental model for understanding the system is that it uses Ethereum its _From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ -In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contrac](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)t to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. +In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contract](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol) to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. All actors in the protocol have a local state from which they can produce valid proofs, and all honest parties will have the same local state. Malicious entities, however, can deviate from the honest parties in attempts to confirm invalid states through the protocol. Both the protocol and the honest validator client’s job is then to allow honest parties to always win against any number of malicious participants by always claiming the absolute truth. ### On-chain components -- **Rollup Contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. - +- **Rollup contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. - **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. - **OneStepProver:** A set of contracts that implement a miniature `WASM` VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the `OSP` contracts are needed for BoLD. -**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the Specifications section. +**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the specifications section. ### Off-chain components - **Chain bindings:** Software that can interact with an Ethereum node in order to make calls and transactions to the on-chain contracts needed for participating in the protocol. We utilize go-ethereum’s abigen utilities to create Go bindings to interact with the contracts above, with a few more developer-friendly wrappers. - **State manager backend:** Software that can retrieve L2 chain states and produce commitments to `WAVM` histories for Arbitrum based on an execution server. The validator client, described below, will have access to a state manager backend in order to make moves on challenge vertices. - -- **Validator Client:** A validator client is software that knows the correct history of the Arbitrum L2 chain via a state manager backend and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participating in challenging those it disagrees with. In BoLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. - -- **Challenge Manager Client:** Software that can manage the life cycles of challenges a validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. This and the validator's responsibilities can be coupled into a single binary. +- **Validator client:** A validator client is software that knows the correct history of the Arbitrum L2 chain via a state manager backend and can create assertions on L1 about them by bonding a claim. A validator is also active in ensuring honest assertions get confirmed and participating in challenging those it disagrees with. In BoLD, an honest validator will also participate in challenges other validators are a part of to support other honest participants. It interacts with the on-chain components via chain bindings described above. +- **Challenge manager client:** Software that can manage the life cycles of challenges a validator participates in. Validators need to participate in multiple challenges at once and manage individual challenge vertices correctly to act upon, confirm, or reject them. This and the validator's responsibilities can be coupled into a single binary. ### Assertions @@ -117,7 +103,7 @@ Assertions form a chain in which there can be forks. For instance, a validator m Given the mandatory delay of one hour between assertions posted on-chain, and each assertion is a claim to a specific Arbitrum batch, there could be a very large number of blocks in between assertions. However, a single assertion only supports a maximum of 2^26 Arbitrum blocks since its parent. If this value is overflowed, a follow-up overflow assertion needs to be posted to consume the rest of the blocks above the maximum. This overflow assertion will not be subject to the mandatory 1-hour delay between assertions. -#### Trustles Bonding Pools +#### Trustless bonding pools A large upfront assertion bond is critical for discouraging malicious actors from attacking Arbitrum and spamming the network (e.g., delay attacks), especially because malicious actors will always lose challenges and their entire bond. On the other hand, requiring such a high upfront assertion bond may be prohibitive for a single honest entity to put up—especially since the cost to defend Arbitrum is proportional to the number of malicious entities and ongoing challenges at any given point in time. @@ -127,7 +113,7 @@ Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreat Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. -### Opening Challenges +### Opening challenges To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet). This bond is much lower than the one required to become an assertion poster. @@ -213,7 +199,7 @@ An edge's "inherited timer" value exists on-chain and can be updated via a trans Once an edge has a total on-chain timer greater than or equal to a challenge period, it can be confirmed via a transaction. Not all edges need to be confirmed on-chain, as simply the top-level block challenge edge is enough to confirm the claimed assertion and resolve a dispute. A challenge is not complete at the one-step proof. It is only complete once the claimed assertion of a challenge is confirmed. -### Bonding in Challenges +### Bonding in challenges To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. @@ -221,13 +207,13 @@ To create a challenge, there must be a fork in the Arbitrum assertion chain smar Each subchallenge that is created requires depositing a challenge bond. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the ArbitrumDAO treasury. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol. It is important to not offer bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks or to discourage needless competition between honest parties. -### Reimbursements of Bonds +### Reimbursements of bonds It is important to emphasize that the reimbursement of assertion bonds and challenge bonds for honest parties will be handled “in-band” by the protocol. While reimbursing honest parties for gas costs will not be handled “in-band” on L1 and will instead be handled by the Arbitrum Foundation. There will be a procedure, to be published later, that can be followed to calculate the reimbursements for gas costs to honest parties. Lastly, reimbursement will not be made for off-chain compute costs as we view these as costs borne by the operator, alongside the maintenance and infra costs that regularly arise from running a node. It is also difficult to attribute computation, as honest validators that are not necessarily posting claims would still perform similar computations if they are following a challenge. However, the costs of the on-chain bonds to participate in challenges far exceed the cost of compute required to resolve these challenges. -### Upgrade Mechanism +### Upgrade mechanism For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an `UpgradeExecutor` pattern. This is a smart contract that executes actions as the Rollup owner. At the upgrade, the `RollupCore.sol` contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed. From 690360a159271c83d629e8fece76b36b8036a3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 22 May 2024 20:03:54 -0700 Subject: [PATCH 42/99] fix: OCL Terminology style guide --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index c3b5c018e..6ff84ad2d 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -71,7 +71,7 @@ All actors in the protocol have a local state from which they can produce valid - **OneStepProver:** A set of contracts that implement a miniature `WASM` VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the `OSP` contracts are needed for BoLD. -**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the specifications section. +**Bonding:** Participants in the protocol need to bond a certain amount of `ETH` (`WETH` is used in the BoLD testnet) to gain the privilege of posting assertions to the Rollup contracts by locking up an `ETH` bond in the protocol contracts. Whenever someone wants to challenge an assertion, they must also place a smaller bond called a challenge bond in their challenge. Bonds, their rationale, and magnitude will be covered in greater detail in the specifications section. ### Off-chain components @@ -97,7 +97,7 @@ Anyone can confirm assertions after a period of 6.4 days if they have not been c Validators must become proposers in the Rollup contract before being allowed to post assertions. This involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. -Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. +Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the Rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. #### Overflow assertions @@ -135,7 +135,7 @@ Validators have to fetch all blocks between batch 5 and batch 10 and create a Me - **start_hash:** the start hash of the block from the common parent assertion -- **end_hash: **the end hash of the block at the claimed child assertion +- **end_hash:** the end hash of the block at the claimed child assertion - **merkle_root:** the Merkle root that results from committing to a Merkle tree from the start block hash to the end block hash From 55864ba0cb83c2838d333117199d52b048b6cb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 23 May 2024 15:21:45 -0700 Subject: [PATCH 43/99] fix: url text must be informative --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 6ff84ad2d..359899d1e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -219,4 +219,4 @@ For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs Assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. -The upgrade pattern for an existing Arbitrum Rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [here](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). +The upgrade pattern for an existing Arbitrum Rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [upgrade workflow on GitHub](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). From dd90213dadf5761c16f81f382029fcc8a30ad57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 30 May 2024 11:38:04 -0700 Subject: [PATCH 44/99] fix: yarn format --- .../bold/concepts/bold-technical-deep-dive.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 359899d1e..9cedb8404 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -12,7 +12,6 @@ sidebar_position: 1 import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_bold-public-preview-banner-partial.md'; - ## Overview @@ -111,7 +110,8 @@ To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (`STF`). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. -Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. +Trustless bonding pools can also be created to open challenges +and make moves on challenges without sacrificing decentralization. ### Opening challenges @@ -203,7 +203,11 @@ Once an edge has a total on-chain timer greater than or equal to a challenge per To create a challenge, there must be a fork in the Arbitrum assertion chain smart contract. A validator that wishes to initiate a challenge must then post an “edge” claiming a history of block hashes from the parent assertion to the claimed assertion they believe is correct. To do so, they need to put up some value called a "challenge bond". Note that to open a new assertion-level challenge, the challenge bond is equal to the assertion bond for Arbitrum One. -Challenge bonds are named as such because they are bonds required for opening challenges. The mechanism of how challenge bond economics are decided is contained in the economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. +Challenge bonds are named as such because they are bonds required +for opening challenges. The mechanism of how challenge bond economics are decided is contained in the +economics deep dive, which also explains the cost profile and spam prevention in BoLD. In short, the +actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between +honest and evil parties to discourage spam. Each subchallenge that is created requires depositing a challenge bond. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the ArbitrumDAO treasury. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol. It is important to not offer bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks or to discourage needless competition between honest parties. From d0445122b89437f110f88f725fe02a991d9f347b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:12:47 -0700 Subject: [PATCH 45/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 9cedb8404..9e729ae9c 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -82,7 +82,7 @@ All actors in the protocol have a local state from which they can produce valid ### Assertions -A key responsibility for Arbitrum validators is to post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions. Assertions contain information, most critically: +A key responsibility for Arbitrum proposers is to regularly post claims about the Arbitrum chains’ state to Ethereum at certain checkpoints. These are known as assertions (and are sometimes called L2 state roots). Assertions contain information, most critically: 1. The L2 block hash being claimed From d3a0e3f0a2c2159d8406e08c941b7d32f4a81a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:12:57 -0700 Subject: [PATCH 46/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 9e729ae9c..89d4a7bd1 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -90,7 +90,7 @@ A key responsibility for Arbitrum proposers is to regularly post claims about th 3. The number of messages in the Arbitrum inbox at the time the assertion was posted on-chain -The following assertion to be posted on-chain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to 1 hour for BoLD. +The following assertion to be posted on-chain must consume, at least, the specified number of inbox messages from its parent. There is a required delay in L1 blocks for assertion posting. Currently, this value is set to equal 1 hour for BoLD. Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion on-chain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. From 4942432d41b7879a468d2daa3b7185b8d45d62cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:13:48 -0700 Subject: [PATCH 47/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 89d4a7bd1..9638c2e9e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -94,7 +94,7 @@ The following assertion to be posted on-chain must consume, at least, the specif Anyone can confirm assertions after a period of 6.4 days if they have not been challenged. In particular, assertions facilitate the process of withdrawing from Arbitrum back to Ethereum. Arbitrum withdrawals require specifying a blockhash, which must be confirmed as an assertion on-chain. This is why withdrawals have a delay of 6.4 days if they are not actively challenged. -Validators must become proposers in the Rollup contract before being allowed to post assertions. This involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. +Validators must become proposers in the Rollup contract before being allowed to post assertions. For Arbitrum One and Arbitrum Nova, this involves placing a one-time bond of 3600 `WETH` that is locked in the contract until they choose to withdraw. Validators can only withdraw their bond if their latest posted assertion gets confirmed. Every assertion a validator posts will become their latest bonded assertion. Subsequent bonds are not needed to post more assertions, instead, the protocol “moves” a validator’s bonds to their latest posted assertion. Assertions form a chain in which there can be forks. For instance, a validator might disagree with the L2 blockhash of an assertion at a given batch. All Arbitrum Nitro nodes are configured to warn users if they observe an assertion they disagree with posted on-chain. However, if a node is configured as a validator and has deposited a bond to the Rollup contract, then that validator post the correct, rival assertion to any invalid one it just observed. The validator will also be able to initiate a challenge by posting a challenge bond and other data to the `ChallengeManager`, signaling it is disputing an assertion. From b3a8fe9093b13731b873709f61441f0d4086bd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:14:03 -0700 Subject: [PATCH 48/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 9638c2e9e..d2379d523 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -181,7 +181,7 @@ First, validators disagree over **Gigasteps** of `WASM` execution. That is, over #### One step proof -Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is proof of `WASM` execution showing that executing the Arbitrum state transition function at hash A leads to hash B. Ethereum then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. +Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is a proof of `WASM` execution showing that executing the Arbitrum state transition function at hash A leads to hash B. The parent chain, like Ethereum is for Arbitrum One, then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. #### Timers From 5d4ec99946fa84619adaccbc16e7d1eeb97696de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:14:16 -0700 Subject: [PATCH 49/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index d2379d523..000e2d186 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -219,7 +219,7 @@ Lastly, reimbursement will not be made for off-chain compute costs as we view th ### Upgrade mechanism -For BoLD to be deployed on Arbitrum One and Nova, an upgrade admin action needs to be taken using an `UpgradeExecutor` pattern. This is a smart contract that executes actions as the Rollup owner. At the upgrade, the `RollupCore.sol` contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed. +For BoLD to be deployed on an Arbitrum chain, an upgrade admin action needs to be taken using an `UpgradeExecutor` pattern. This is a smart contract that executes actions as the Rollup owner. At the upgrade, the `RollupCore.sol` contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed to the parent chain. Assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. From 7a499b2f3269cd46f410e74284aef03e06023074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:14:25 -0700 Subject: [PATCH 50/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 000e2d186..32b4bfee3 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -221,6 +221,12 @@ Lastly, reimbursement will not be made for off-chain compute costs as we view th For BoLD to be deployed on an Arbitrum chain, an upgrade admin action needs to be taken using an `UpgradeExecutor` pattern. This is a smart contract that executes actions as the Rollup owner. At the upgrade, the `RollupCore.sol` contract will be updated to a new BoLD one, and additional contracts needed for BoLD challenges, such as an `EdgeChallengeManager.sol`, will also be deployed to the parent chain. -Assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. +Next, assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. + +:::caution The confirmation timing on any withdrawal that is in-flight when the BoLD upgrade is activated will be delayed until the first BoLD assertion is confirmed. This means that for any Arbitrum chain that upgrades to use BoLD, including Arbitrum One and Arbitrum Nova, all pending withdrawals to L1 Ethereum that were initiated _before_ the upgrade will be delayed by 1 challenge period, plus the time between the withdrawal was initiated and the time that the BOLD upgrade takes place. This is because the upgrade effectively "resets" the challenge period for that are not yet finalized. + +For example, if the upgrade happened at time _t_, then a withdrawal initiated at a time _t-2_ days will need to wait an additional _6.4_ days for their withdrawal to be finalized, totaling 8.4 days of maximum delay. Withdrawals that finalize before the upgrade takes place at time _t_ will be unaffected. In other words, the maximum delay a withdrawal will experience leading up to the upgrade is 12.8 days (two challenge periods). +::: + The upgrade pattern for an existing Arbitrum Rollup to a BoLD-enabled one is tested extensively and run as part of each of our pull requests in the BoLD repository [upgrade workflow on GitHub](https://github.com/OffchainLabs/bold/blob/c4e068b568ff662f49ed191c5c3188ea7b6138b2/.github/workflows/go.yml#L209). From 5352d7f263b49caa59b3d4ee42564a91570ca228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:14:37 -0700 Subject: [PATCH 51/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 32b4bfee3..884427e4a 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -209,7 +209,7 @@ economics deep dive, which also explains the cost profile and spam prevention in actual cost of a bond encompasses information such as off-chain costs + gas costs + grieving ratios between honest and evil parties to discourage spam. -Each subchallenge that is created requires depositing a challenge bond. The first, unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address, which can be set to the ArbitrumDAO treasury. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol. It is important to not offer bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks or to discourage needless competition between honest parties. +Each subchallenge that is created requires depositing a challenge bond. For Arbitrum One, the first unrivaled edge’s bond is kept in the challenge manager contract on Ethereum, while any subsequent rival bonds are kept in an excess bond receiver address. Once a challenge is complete, all bonds for an honest party are automatically refunded in-protocol while all confiscated bonds are sent to the ArbitrumDAO treasury. It is important to not offer the majority of the bonds confiscated from dishonest parties to honest parties to avoid perverse incentives, such as grieving attacks in self-challenges or to discourage needless competition between honest parties. ### Reimbursements of bonds From 403bf066fa1a2f366b06807fab07bfde578991a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:25:10 -0700 Subject: [PATCH 52/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 884427e4a..2c753bd23 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -53,7 +53,7 @@ The current implementation of BoLD involves both on-chain and off-chain componen When it comes to implementing the protocol, BoLD needs to be deployed on a credibly-neutral, censorship-resistant backend to be fair to all participants. As such, Ethereum was chosen as the perfect candidate. Ethereum is currently the most decentralized, secure, smart contract blockchain to which the full protocol can be deployed, with challenge moves performed as transactions to the protocol’s smart contracts. -A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the _results of L2 state transitions_ and provide proofs to the protocol smart contracts that show which result is correct. Because computation is deterministic, there will always be a single correct result. +A helpful mental model for understanding the system is that it uses Ethereum itself as the ultimate referee for deciding assertion results. Participants in the challenge protocol can disagree over the _results of L2 state transitions_ and provide proofs to the protocol's smart contracts on Ethereum to determine which result is correct. Because computation is deterministic, there will always be a single correct result. ![900px-img](../assets/KSf_Image_1.png) From 706298d431c359706039d2bb004bc4c28357bbf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:28:22 -0700 Subject: [PATCH 53/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 2c753bd23..58432d764 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -66,7 +66,7 @@ All actors in the protocol have a local state from which they can produce valid ### On-chain components - **Rollup contract:** This is a smart contract that lives on Ethereum and allows validators to bond on state assertions about Arbitrum. This contract, known as `RollupCore.sol`, is already used by Arbitrum chains to post assertions. BoLD requires several changes to how assertions work in this contract, and it now contains a reference to another contract called a `ChallengeManager`, new in BoLD. -- **ChallengeManager:** This is a contract that allows for initiating challenges on assertions within the `AssertionChain` and provides methods for anyone to participate in challenges in a permissionless fashion. This new challenge protocol will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. +- **ChallengeManager:** This is a contract that allows for initiating challenges on assertions and provides methods for anyone to participate in challenges in a permissionless fashion. BoLD will require a new `ChallengeManager` written in Solidity and deployed to Ethereum. The challenge manager contains entry points for making challenge moves, opening leaves, creating subchallenges, and confirming challenges. - **OneStepProver:** A set of contracts that implement a miniature `WASM` VM capable of executing one-step-proofs of computation of the L2 state transition function. This is implemented in Solidity and already exists on Ethereum. No changes to the `OSP` contracts are needed for BoLD. From 2304af8e8575a470ac35057933614c9e39df87ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:30:07 -0700 Subject: [PATCH 54/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 58432d764..dd689f56b 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -110,6 +110,9 @@ To address this, there is a [contract](https://github.com/OffchainLabs/bold/blob Anyone can deploy an assertion bonding pool using the `AssertionStakingPoolCreator.sol` contract as a means to crowdsource funds for bonding funds to an assertion. To defend Arbitrum using one of these pools, an entity would first deploy this pool with the assertion they believe is correct and wish to bond on to challenge an adversary's assertion. Then, anyone can verify that the claimed assertion is correct by running the inputs through their node's State Transition Function (`STF`). If other parties agree that the assertion is correct, they can deposit their funds into the contract. When enough funds have been deposited, anyone can trigger the creation of the assertion on-chain to start the challenge in a trustless manner. Finally, once the dispute protocol confirms the honest parties' assertion, all involved entities will get their funds reimbursed and can withdraw. +Note that with bonding pools, there is no minimum `WETH` requirement and once the entire bond amount is raised (either 3600, 555, or 79 ETH for Arbitrum One), then the assertion can be posted by anyone trustlessly. Additionally, there is an optional feature in the Nitro node validator software that enables both the automatic deployment of a bonding pool contract and depositing of funds to challenge an observed invalid assertion. + + Trustless bonding pools can also be created to open challenges and make moves on challenges without sacrificing decentralization. From c22b8b25a76923fdbd4afb51428cda98f781ea74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 10:31:08 -0700 Subject: [PATCH 55/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index dd689f56b..27758cbad 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -118,7 +118,7 @@ and make moves on challenges without sacrificing decentralization. ### Opening challenges -To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on Ethereum. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet). This bond is much lower than the one required to become an assertion poster. +To initiate a challenge, there must first be a fork in the assertion chain within the Arbitrum Rollup contracts. However, a challenge's actual start involves creating an edge claim and posting it to the `ChallengeManager` contract on the parent chain. Additionally, the validator posting the edge must attach a bond called a challenge bond to it (denominated in `WETH` for the BoLD testnet and for Arbitrum One and Arbitrum Nova). This bond is much lower than the one required to become an assertion poster. Anyone can open a challenge on an assertion without needing to be a bonder in the Rollup contract, so long as they post a challenge bond and an edge claiming intent to start the challenge. Challenges are not tied to specific addresses or parties – instead, anyone can participate. From de7ce43ee298d4b069a1832b69f1cc6043bb99fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 11:17:41 -0700 Subject: [PATCH 56/99] fix: rephrase confusing intro paragraph --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 27758cbad..7f786e892 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -16,9 +16,8 @@ import PublicPreviewBannerPartial from '../../how-arbitrum-works/bold/partials/_ ## Overview -Under the hood, BoLD can offer time-bounded, permissionless validation because a correct Arbitrum state assertion is not tied to a single validator or entity. Instead, claims are tied to deterministic Merkle proofs and hashes that will be proven on Ethereum. Any party can bond capital to the correct state and, through interactive fraud proofs, have their claim proven correct. This means that a single honest party bonding on the correct state assertion will always win disputes, guaranteed. - -To put it simply, Arbitrum’s current dispute protocol assumes that any assertion that gets challenged must be defended against by each unique challenger. It is similar to a 1-vs-1 tournament, where the honest party may participate in one or more concurrent tournaments at any time. BoLD, on the other hand, enables an all-vs-all battle royal between two categories: Good vs Evil, where there must and will always be a single winner in the end. +Arbitrum's current dispute protocol involves defending against challengers individually in a 1-vs-1 tournament setting. In contrast, BoLD enables an all-vs-all battle royale between Good and Evil categories, with a single winner always determined. +This dynamic is made possible by BoLD's time-bounded, permissionless validation using deterministic Merkle proofs and hashes. This allows any party to bond in the correct state and prove their claim through interactive fraud proofs, ensuring that a single honest party bonding in the correct state will always prevail in disputes. Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. From 949a43aee7ba1e5238d2936e5e1954f09e309b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Thu, 20 Jun 2024 12:10:30 -0700 Subject: [PATCH 57/99] Add quicklook > challenge period --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 7f786e892..85f2830fd 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -23,7 +23,7 @@ Validators on Arbitrum can post their claim on the validity of state roots, know The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. -If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. The current implementation of BoLD involves both on-chain and off-chain components: From f9e044dbe77ad414cc1e6d38a6736a3f650a85a9 Mon Sep 17 00:00:00 2001 From: Derek <103802618+leeederek@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:00:17 -0400 Subject: [PATCH 58/99] fix caution warning title --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 85f2830fd..afcbb9dcb 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -225,7 +225,9 @@ For BoLD to be deployed on an Arbitrum chain, an upgrade admin action needs to b Next, assertions will then be posted to the new Rollup contract. During the upgrade period, there could have been a very large number of blocks posted in Arbitrum batches. For this purpose, BoLD assertions support the concept of an **overflow**, allowing us to efficiently handle this situation. -:::caution The confirmation timing on any withdrawal that is in-flight when the BoLD upgrade is activated will be delayed until the first BoLD assertion is confirmed. This means that for any Arbitrum chain that upgrades to use BoLD, including Arbitrum One and Arbitrum Nova, all pending withdrawals to L1 Ethereum that were initiated _before_ the upgrade will be delayed by 1 challenge period, plus the time between the withdrawal was initiated and the time that the BOLD upgrade takes place. This is because the upgrade effectively "resets" the challenge period for that are not yet finalized. +:::caution Withdrawals leading up to a BoLD upgrade + +The confirmation timing on any withdrawal that is in-flight when the BoLD upgrade is activated will be delayed until the first BoLD assertion is confirmed. This means that for any Arbitrum chain that upgrades to use BoLD, including Arbitrum One and Arbitrum Nova, all pending withdrawals to L1 Ethereum that were initiated _before_ the upgrade will be delayed by 1 challenge period, plus the time between the withdrawal was initiated and the time that the BOLD upgrade takes place. This is because the upgrade effectively "resets" the challenge period for that are not yet finalized. For example, if the upgrade happened at time _t_, then a withdrawal initiated at a time _t-2_ days will need to wait an additional _6.4_ days for their withdrawal to be finalized, totaling 8.4 days of maximum delay. Withdrawals that finalize before the upgrade takes place at time _t_ will be unaffected. In other words, the maximum delay a withdrawal will experience leading up to the upgrade is 12.8 days (two challenge periods). ::: From bd778e0a3c0810e545814e6bfe7e695fa64ac5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 26 Jun 2024 17:53:38 -0700 Subject: [PATCH 59/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index afcbb9dcb..d39a91d8e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -56,7 +56,7 @@ A helpful mental model for understanding the system is that it uses Ethereum its ![900px-img](../assets/KSf_Image_1.png) -_From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period for each, during which anyone can challenge their validity on Ethereum._ +_From the **[Nitro whitepaper](https://github.com/OffchainLabs/nitro/blob/master/docs/Nitro-whitepaper.pdf)**. L2 blocks are “settled to L1” after a 6.4 day period has elapsed and nobody has challenged their validity on Ethereum._ In effect, there is a miniature Arbitrum state-transition VM[ ](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol)[deployed as an Ethereum smart contract](https://sourcegraph.com/github.com/OffchainLabs/nitro/-/blob/contracts/src/osp/OneStepProofEntry.sol) to prove which assertions are correct. However, computation on Ethereum is expensive, which is why this mini-VM is built to handle “one-step proofs” consisting of a single step of WebAssembly code. The Arbitrum state transition logic, written in Golang, is also compiled to an assembly language called `WASM` and will therefore obtain the same results as the VM found in the on-chain smart contract. The soundness of the protocol depends on the assumptions that computation is deterministic and equivalent between the on-chain VM and the Golang state transition compiled to `WASM`. From 09449eba653ee9770051cf814ee21f400a96de87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Jul 2024 12:26:31 -0700 Subject: [PATCH 60/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Raul Jordan --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index d39a91d8e..67290abc5 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -21,7 +21,7 @@ This dynamic is made possible by BoLD's time-bounded, permissionless validation Validators on Arbitrum can post their claim on the validity of state roots, known as **assertions**. Ethereum, of course, does not know anything about the validity of these Arbitrum state roots, but it _can_ help prove their correctness. _Anyone_ in the world can then initiate a challenge over any unconfirmed assertion to start the protocol’s game. -The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion. +The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion after an interactive game is played to narrow down a dispute. If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. From 24f505a79c711d559c170fe9bac021ca75c9cf16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 3 Jul 2024 12:27:09 -0700 Subject: [PATCH 61/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Raul Jordan --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 67290abc5..417d64257 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -23,7 +23,7 @@ Validators on Arbitrum can post their claim on the validity of state roots, know The assertions being disputed concern block hashes of an Arbitrum chain at a given batch/inbox position. Given that Arbitrum chains are deterministic, there is only one correct history for all parties running the standard Nitro software. Using the notion of one-step proof, Ethereum can check whether someone is making a fraudulent assertion after an interactive game is played to narrow down a dispute. -If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period. +If a claim is honest, it can be confirmed on Ethereum after a 6.4-day period (although the DAO can change this period). If a claim is malicious, anyone who knows the correct Arbitrum state can successfully challenge it within that 6.4-day window _and always win_ within a challenge period plus some small delta. The current implementation of BoLD involves both on-chain and off-chain components: From 40b6d87128a226db0ed03daf54c771e132c73fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Wed, 11 Sep 2024 09:22:34 -0700 Subject: [PATCH 62/99] fix: add fontmatter --- arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md b/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md index 1de87fdb6..d1a244ab7 100644 --- a/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md +++ b/arbitrum-docs/how-arbitrum-works/inside-arbitrum-nitro.md @@ -1,11 +1,15 @@ --- +title: 'Inside Arbitrum Nitro' +sidebar_label: 'Get started' +description: 'Learn the fundamentals of Nitro, Arbitrum stack.' author: dzgoldman +sme: dzgoldman +user_story: As a current or prospective Arbitrum user, I need learn more about Nitros design. +content_type: get-started --- import ImageWithCaption from '@site/src/components/ImageCaptions/'; -# Inside Arbitrum Nitro - This document is a deep-dive explanation of Arbitrum Nitro’s design and the rationale for it. This isn’t API documentation, nor is it a guided tour of the code--look elsewhere for those. “Inside Arbitrum Nitro” is for people who want to understand Nitro's design. The body of this document will describe Arbitrum Rollup, the primary use case of the Nitro technology and the one used on the Arbitrum One chain. There is a variant use case, called AnyTrust, which is used by the Arbitrum Nova chain. AnyTrust is covered by a section at the end of this document. From 093136efd06c087a64b5192e6f2d7dd30573c586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Blanchemain?= Date: Fri, 20 Sep 2024 10:15:43 -0700 Subject: [PATCH 63/99] Update arbitrum-docs/bold/concepts/bold-technical-deep-dive.md Co-authored-by: Derek <103802618+leeederek@users.noreply.github.com> --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 417d64257..abfc9341f 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -41,7 +41,7 @@ The current implementation of BoLD involves both on-chain and off-chain componen - **Fraud proofs:** Proofs of a single step of `WAVM` execution of Arbitrum's state transition function, which are submitted to Ethereum and verified in the `EVM` via a smart contract. These proofs allow Ethereum to be the final arbiter of disagreements over assertions in the rollup contracts, which cannot be falsified by any parties as there is only a single, correct result of executing a `WASM` instruction on a pre-state. - **Challenge protocol:** A set of rules through which a disagreement on an assertion is resolved using Ethereum as the final arbiter. Ethereum's VM can verify one-step proofs of deterministic computation that can confirm a challenge winner in Arbitrum's rollup contracts. - **Bonding of funds:** Creating an assertion in the rollup contracts requires the submitter to join the validator set by putting up a large bond in the form of `WETH`. Subsequent assertions posted by the same party do not require more bonds. Instead, the protocol always considers validators to be bonded to their latest posted assertion. The bonded funds are taken away if another competing assertion is confirmed. In the case of confirming an assertion, the associated bonded funds can be withdrawn. -- **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and will participate in confirming assertions and challenging invalid assertions if they exist. +- **Honest validator:** An entity that knows the correct state of the Arbitrum L2 chain and who may want to participate in creating assertions, confirming assertions, and/or challenging invalid assertions if they exist. More specifically, this entity must run an Arbitrum full node in `MakeNodes`, `Defensive`, `StakeLatest`, or `ResolveNodes` mode as described in the [How to run a validator](https://docs.arbitrum.io/run-arbitrum-node/more-types/run-validator-node). Note that there must always be an active proposer to advance the chain and who will need to run a validator in `MakeNodes` mode. - **Challenge period:** Window of time ([~6.4 days on Arbitrum One](https://docs.arbitrum.io/build-decentralized-apps/reference/chain-params)) over which an assertion can be challenged, after which the assertion can be confirmed. This is configurable by the DAO. - **Edge:** Edges are a portion of a claim made by a validator about the history of the chain from some end state all the way back to some initial state. Edges are the fundamental unit in a challenge. - **Delay attacks:** In a delay attack, a malicious party (or group of parties) acts within the rollup protocol, forcing the honest party to play 1-vs-1 games against them to delay the confirmation of results back to the L1 chain. BoLD has a proven, constant upper bound on confirmation times for assertions in Arbitrum, addressing the biggest flaw of the current challenge mechanism. BoLD validators don’t need to play 1-vs-1 challenges and instead can defend a single challenge against many malicious claims. With delay attacks solved, Arbitrum will be able to allow permissionless validation. From 8fba5ec2209ea39a716a7ee85ec618e614416eb2 Mon Sep 17 00:00:00 2001 From: Derek Lee <103802618+leeederek@users.noreply.github.com> Date: Tue, 8 Oct 2024 06:32:01 -0400 Subject: [PATCH 64/99] address henry feedback --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index abfc9341f..79652aa99 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -173,13 +173,13 @@ A validator can make a move on an edge as long as that edge is “rivaled”. Th #### Subchallenges -The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^43. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 8.7Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^43 hashes. +The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^42. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 4.35Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^42 hashes. The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual `WASM` execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. -The subchallenge is over a max of 2^43 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. +The first subchallenge is over a max of 2^26 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. Each hash represents a max of 2^26 blocks, with each block containing a max of 2^42 WASM steps of execution -First, validators disagree over **Gigasteps** of `WASM` execution. That is, over ranges of 2^30 steps. Then, they open another subchallenge once they reach a single gigastep of disagreement. They then play games over ranges of **Megasteps**, then **Kilosteps**, until they reach a subchallenge over individual steps. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. +First, validators disagree over execution of up to 2^26 L2 Blocks. Then, they open another subchallenge once they reach a single block of disagreement. They then play a subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over up to 2^23 SmallSteps, which are each a single step of WASM execution . The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. #### One step proof From 5b7e78590dcc145a1ac6921ed0c56749053f4ca8 Mon Sep 17 00:00:00 2001 From: Derek Lee Date: Tue, 8 Oct 2024 19:50:19 +0900 Subject: [PATCH 65/99] update subchallenge description once more --- arbitrum-docs/bold/concepts/bold-technical-deep-dive.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md index 79652aa99..f4a41730e 100644 --- a/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md +++ b/arbitrum-docs/bold/concepts/bold-technical-deep-dive.md @@ -173,14 +173,9 @@ A validator can make a move on an edge as long as that edge is “rivaled”. Th #### Subchallenges -The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^42. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 4.35Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^42 hashes. - -The bisection game is an iterative process. Initially, validators disagree over Arbitrum blocks between two assertions. They create “edges” containing history commitments to all the blocks in between those two assertions, and commence the bisection game. As they progressively narrow down to a single block of disagreement, they then focus on identifying the point of disagreement in the actual `WASM` execution of the block through the Arbitrum state transition function. This marks the first “subchallenge”. - -The first subchallenge is over a max of 2^26 hashes where validators need to narrow down their single hash of disagreement. As the space of hashes is too large, we explore this space in _ranges_ of steps. Each hash represents a max of 2^26 blocks, with each block containing a max of 2^42 WASM steps of execution - -First, validators disagree over execution of up to 2^26 L2 Blocks. Then, they open another subchallenge once they reach a single block of disagreement. They then play a subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over up to 2^23 SmallSteps, which are each a single step of WASM execution . The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. +The number of steps of execution at which validators could disagree within a single Arbitrum block has a max of 2^42. To play a game of bisections on this amount of hashes would be unreasonable from a space requirement, as each history commitment would require 4.35Tb worth of hashes. Instead, BoLD plays the bisection game over different levels of granularity of this space of 2^42 hashes that we call "subchallenges" that can be viewed as "phases" of the dispute resolution process. +As a reminder, the bisection game is an iterative process. The first subchallenge is at the block level and is where validators disagree over Arbitrum blocks between two assertions. The disagreeing validators)create “edges” containing history commitments to all the blocks in between those two assertions, which is a max of 2^26 L2 blocks, and commence the bisection game. As they progressively narrow down to a single block of disagreement, the validators then begin the next phase of the challenge process by opening a subchallenge over a maximum subchallenge over up to 2^19 **BigSteps**, which are each 2^23 steps of WASM execution. Once they reach a single disagreement at the BigStep level, they open a final subchallenge over a maximum of 2^23 SmallSteps, which are each a single step of WASM execution. The bisection game is the same at each subchallenge level, and opening a subchallenge requires placing another “challenge bond”. The magnitudes of challenge bonds are different at each subchallenge level. #### One step proof Once validators reach a single, individual step of disagreement after reaching the deepest subchallenge level, they need to provide something called a **one step proof**, or `OSP` for short. This is a proof of `WASM` execution showing that executing the Arbitrum state transition function at hash A leads to hash B. The parent chain, like Ethereum is for Arbitrum One, then actually runs a `WASM` emulator using a smart contract for this step and will declare a winner. An evil party cannot forge a one-step proof, and unless there is a critical bug in the smart contract, the honest party will always win. At this point, the honest party’s one-step proven edge will be confirmed, and the evil party has no more moves to make. Next, the honest party’s “branch” of edges all the way from the top to the one-step proven edge will have an ever-increasing timer until the top edge can be confirmed by time. From 6b6d39c610cfe205d9d99058f31c3536ad3a206a Mon Sep 17 00:00:00 2001 From: Mahsa Moosavi Date: Tue, 22 Oct 2024 14:11:29 -0400 Subject: [PATCH 66/99] Add nitro dev instructions --- .../partials/_contribute-docs-partial.mdx | 2 +- arbitrum-docs/partials/_local-devnet-flags.md | 33 +++---- .../run-arbitrum-node/01-overview.md | 2 +- ...d => 04-run-local-full-node-simulation.md} | 8 +- .../run-arbitrum-node/run-nitro-dev-node.mdx | 99 +++++++++++++++++++ website/sidebars.js | 9 +- 6 files changed, 128 insertions(+), 25 deletions(-) rename arbitrum-docs/run-arbitrum-node/{04-run-local-dev-node.md => 04-run-local-full-node-simulation.md} (91%) create mode 100644 arbitrum-docs/run-arbitrum-node/run-nitro-dev-node.mdx diff --git a/arbitrum-docs/partials/_contribute-docs-partial.mdx b/arbitrum-docs/partials/_contribute-docs-partial.mdx index 190823808..6d3c8dfdc 100644 --- a/arbitrum-docs/partials/_contribute-docs-partial.mdx +++ b/arbitrum-docs/partials/_contribute-docs-partial.mdx @@ -114,7 +114,7 @@ Every document should be a specific _type_ of document. Each type of document ha | ------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Gentle introduction | Onboard a specific reader audience with tailored questions and answers | [A gentle introduction to Orbit](/launch-orbit-chain/orbit-gentle-introduction.md) | | Quickstart | Onboard a specific reader audience with step-by-step "learn by doing" instructions | [Quickstart: Build dApps](/build-decentralized-apps/01-quickstart-solidity-hardhat.md) | -| How-to | Provide task-oriented procedural guidance | [How to run a local dev node](/run-arbitrum-node/04-run-local-dev-node.md) | +| How-to | Provide task-oriented procedural guidance | [How to run a local dev node](/run-arbitrum-node/04-run-local-full-node-simulation.md) | | Concept | Explain what things are and how they work | [Token bridging](/build-decentralized-apps/token-bridging/03-token-bridge-erc20.md)
    [Nodes and networks](https://docs.prylabs.network/docs/concepts/nodes-networks) | | FAQ | Address frequently asked questions | [FAQ: Run a node](../node-running/faq.md) | | Troubleshooting | List common troubleshooting scenarios and solutions | [Troubleshooting: Run a node](/run-arbitrum-node/06-troubleshooting.md) | diff --git a/arbitrum-docs/partials/_local-devnet-flags.md b/arbitrum-docs/partials/_local-devnet-flags.md index 06fce23c6..95e51e6fe 100644 --- a/arbitrum-docs/partials/_local-devnet-flags.md +++ b/arbitrum-docs/partials/_local-devnet-flags.md @@ -1,20 +1,17 @@