Skip to content

Commit

Permalink
chore(chain): base shard script hardening & faucet address loading (W…
Browse files Browse the repository at this point in the history
…ORLD-471, WORLD-469) (#409)
  • Loading branch information
technicallyty authored Nov 9, 2023
1 parent d6401e8 commit 499676c
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 176 deletions.
6 changes: 3 additions & 3 deletions chain/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ EXPOSE 26656 26657 1317 9090 8546 8545 9601

USER 0

COPY scripts/start-rollup.sh start-rollup.sh
RUN chmod +x start-rollup.sh
COPY scripts/start-sequencer.sh start-sequencer.sh
RUN chmod +x start-sequencer.sh

HEALTHCHECK --interval=5s --timeout=80s CMD curl --fail http://localhost:26657 || exit 1

ENTRYPOINT ["./start-rollup.sh"]
ENTRYPOINT ["./start-sequencer.sh"]
261 changes: 135 additions & 126 deletions chain/README.md
Original file line number Diff line number Diff line change
@@ -1,199 +1,185 @@
# Polaris Integrated Cosmos Chain
# World Engine EVM Base Shard (world-evm)

## Installation

### From Binary
### From Source

The easiest way to install a Cosmos-SDK Blockchain running Polaris is to download a pre-built binary. You can find the latest binaries on the [releases](https://github.com/polaris/releases) page.
Clone the repo

### Makefile
`git clone https://github.com/Argus-Labs/world-engine.git`

To install the World Engine blockchain in your bin, making it globally accessable from your terminal, run this command in the `chain` directory:
Run the `install-rollup` makefile command

```bash
make install
```
`make install-rollup`

To verify installation was successful, run:
Verify installation success

```bash
world version
```

### From Prebuilt Docker Image

Pull `chain` prebuild Docker Image:
```bash
docker pull us-docker.pkg.dev/argus-labs/world-engine/chain:<latest/tag_version>
```
`world-evm version`

Run `chain` container, supply the DA_BASE_URL and DA_AUTH_TOKEN environment variables accordingly:
```bash
docker run -it --rm -e DA_BASE_URL=http://celestia-da-layer-url:26658 -e DA_AUTH_TOKEN=celestia-da-later-token us-docker.pkg.dev/argus-labs/world-engine/chain:latest
```
## Running a Test Sequencer Node w/ Docker Compose

See the Docker Compose section below for instructions on running both the `chain` and `Celestia Devnet` stack.
World Engine provides simple scripts to start a testing sequencer node with a local celestia devnet for DA.

### From Source
Assuming you have the repository cloned and are in the root directory, run the following make command:

**Step 1: Install Golang & Foundry**
`make rollup`

Go v1.20+ or higher is required for Polaris
The rollups exposes the default ports that comes with the Cosmos SDK. Head over to the Cosmos SDK documentation to learn more about which ports are exposed: https://docs.cosmos.network/v0.50/learn/advanced/grpc_rest

1. Install [Go 1.20+ from the official site](https://go.dev/dl/) or the method of your choice. Ensure that your `GOPATH` and `GOBIN` environment variables are properly set up by using the following commands:
### From Prebuilt Docker Image

For Ubuntu:
If you want to make your own setup script, but still want to use the world-evm binary, you can grab a docker image of the chain here:

```sh
cd $HOME
sudo apt-get install golang -y
export PATH=$PATH:/usr/local/go/bin
export PATH=$PATH:$(go env GOPATH)/bin
```
Prebuilt Docker Image:
```bash
us-docker.pkg.dev/argus-labs/world-engine/chain:<latest/tag_version>
```

For Mac:
## Features

```sh
cd $HOME
brew install go
export PATH=$PATH:/opt/homebrew/bin/go
export PATH=$PATH:$(go env GOPATH)/bin
```
### Game Shard Transaction Sequencer

2. Confirm your Go installation by checking the version:
The rollup is extended via a special gRPC server that game shards can connect to for the purpose of submitting and storing transactions to the base shard.

```sh
go version
```
This gRPC server runs, by default, at port `9601`, but can be configured by setting the `SHARD_SEQUENCER_PORT` environment variable.

[Foundry](https://book.getfoundry.sh/getting-started/installation) is required for Polaris
### Router

3. Install Foundry:
```sh
curl -L https://foundry.paradigm.xyz | bash
```
The rollup provides an extension to its underlying EVM environment with a specialized precompile that allows messages to be forwarded from smart contracts to game shards that implement the router server.

**Step 2: Get Polaris source code**
In order for the router to communicate with game shards, their namespaces must be mapped to their gRPC address. These are stored through the x/namespace module, and can be updated via an authority address. The authority address is loaded at the start of the application from an environment variable named `NAMESPACE_AUTHORITY_ADDR`. If unset, the authority for the namespace module will be set to the governance module address, allowing for namespaces to be added via governance.

Clone the `polaris` repo from the [official repo](https://github.com/berachain/polaris/) and check
out the `main` branch for the latest stable release.
Build the binary.
When namespace authority is set, you can update the namespaces via the `register` command provided by world-evm.

```bash
cd $HOME
git clone https://github.com/berachain/polaris
cd polaris
git checkout main
world-evm tx namespace register foobar foo.bar.com:9020
```

**Step 3: Build the Node Software**

Run the following command to install `world` to your `GOPATH` and build the node. `world` is the node daemon and CLI for interacting with a polaris node.
#### Using the Router in Solidity

```bash
make install
```
In order to use the precompile, you first need to copy over the precompile contract code. The contract lives at:

**Step 4: Verify your installation**
`chain/precompile/contracts/src/cosmos/precompile/router.sol`

Verify your installation with the following command:
The precompile address will always be `0x356833c4666fFB6bFccbF8D600fa7282290dE073`.

```bash
world version --long
```
Instantiating the precompile:

A successful installation will return the following:
```solidity
// the path of import will change depending on where you copied the
// precompile contract code to.
import {IRouter} from "./precompile/router.sol";
contract SomeGame {
IRouter private immutable router;
constructor () {
router = IRouter(0x356833c4666fFB6bFccbF8D600fa7282290dE073);
}
}
```bash
name: world-engine
server_name: world
version: <x.x.x>
commit: <Commit hash>
build_tags: netgo,ledger
go: go version go1.20.4 darwin/amd64
```

## Running a Local Network
#### Sending Messages

After ensuring dependecies are installed correctly, run the following command to start a local development network.
First, a smart contract needs structs that are mirrors of the EVM enabled message structs found in the game shard.

```bash
mage start
```
For example:

## Running using Docker Compose
Game Shard Foo message:
```go
type Foo struct {
Bar int64
Baz string
}

Start the `chain` and `celestia-devnet` using `chain/docker-compose.yml`, make sure to follow these steps:
- Start local-celestia-devnet
```
docker compose up celestia-devnet -d --wait
```
type FooResult struct {
Success bool
}
```

- Get DA_AUTH_TOKEN (Celestia RPC Authentication token) from celestia_devnet logs.
```
export DA_AUTH_TOKEN=$(docker logs celestia_devnet 2>&1 | grep CELESTIA_NODE_AUTH_TOKEN -A 5 | tail -n 1)
echo "Auth Token >> $DA_AUTH_TOKEN"
```
Solidity Mirror:
```solidity
struct Foo {
int64 Bar;
string Baz;
}
- Start the `chain` / `evm_base_shard`
```
docker compose up chain --build --detach
```
struct FooResult {
bool Success;
}
```

## Features
Then, we simply abi encode an instance of the struct, and pass it along to the router, along with the name of the message we are sending, and the namespace of the game shard instance we want to send the message to:

### Game Shard Tx Sequencer
```solidity
Foo memory fooMsg = Foo(420, "we are so back")
bytes memory encodedFoomsg = abi.encode(fooMsg)
bool ok = router.sendMessage(encodedFooMsg, "foo", "game-shard-1");
```

The rollup is extended via a special gRPC server that game shards can connect to for the purpose of submitting and storing transactions to the base shard.
#### Receiving Message Results

This gRPC server runs, by default, at port `9601`, but can be configured by setting the `SHARD_SEQUENCER_PORT` environment variable.
Receiving message results must be done in a separate transaction, due to World Engine's asynchronous architecture. In order to get the results of a message, we use another precompile method from the router: `messageResult`.

### Router

The rollup provides an extension to it's underlying EVM environment with a specialized precompile that allows messages to be forwarded from smart contracts to game shards that implement the router server.
messageResult takes in the transaction hash of the original EVM transaction that triggered the cross-shard transaction. It returns the abi encoded message result, an error message, and an arbitrary status code.

The router must be informed of the game shard's server address by setting the environment variable `CARDINAL_EVM_LISTENER_ADDR`.
```solidity
(bytes memory txResult, string memory errMsg, uint32 code) = router.messageResult(txHash);
```

#### Using the Router in Solidity
To decode the result, use `abi.decode`

In order to use the precompile, you first need to copy over the precompile contract code. The contract lives at:
```solidity
FooResult memory res = abi.decode(txResult, (FooResult));
```
The following codes may be returned:

`chain/contracts/src/cosmos/precompile/router.sol`
Cardinal Codes:
1: CodeSuccess
2: CodeTxFailed
3: CodeNoResult
4: CodeServerUnresponsive
5: CodeUnauthorized
6: CodeUnsupportedMessage
7: CodeInvalidFormat

The precompile address will always be `0x356833c4666fFB6bFccbF8D600fa7282290dE073`.
EVM Base Shard Codes:
100: CodeConnectionError
101: CodeServerError

Instantiating the precompile is done like so:
### Querying Game Shards

Game shards can be queried using the same contructs as above, however, the precompile will return the results synchronously.
```solidity
// the path of import will change depending on where you copied the
// precompile contract code to.
import {IRouter} from "./precompile/router.sol";
QueryLocation memory q = QueryLocation(name);
bytes memory queryBz = abi.encode(q);
bytes memory bz = router.query(queryBz, queryLocationName, Namespace);
QueryLocationResponse memory res = abi.decode(bz, (QueryLocationResponse));
```

contract SomeGame {
IRouter public immutable router;
# Running the Sequencer

constructor () {
router = IRouter(0x356833c4666fFB6bFccbF8D600fa7282290dE073);
}
}
Below are the following environment variables needed to run the sequencer.

```
## Faucet

## Environment Variables
The following env variables must be set for the following features.
- FAUCET_ADDR
The application is capable of supplying a faucet address with funds. Setting the `FAUCET_ADDR` will keep an account topped up to be used in a faucet.

## x/namespace
- NAMESPACE_AUTHORITY_ADDR=<world engine address>
- the address of the account you want to be able to update namespace mappings with.

### Secure gRPC Connections
For production environments, you'll likely want to setup secure connections between gRPC servers handling system transactions.
To make use of these, set the following environment variables to the path of your SSL certification files:
For production environments, you'll want to setup secure connections between gRPC servers handling cross-shard communication. To make use of these, set the following environment variables to the path of your SSL certification files:
- SERVER_CERT_PATH=<path/to/server/cert>
- SERVER_KEY_PATH=<path/to/server/key>
- CLIENT_CERT_PATH=<path/to/client/cert>

### Celestia DA Layer Connections
### DA Layer
The following variables are used to configure the connection to the Data Availability layer (Celestia).

Required:
Expand All @@ -219,8 +205,31 @@ Optional:

- DA_BASE_URL=(default: `http://celestia-devnet:26658`)

Celestia RPC base URL, default value are based on `docker-compose.yml` services URL.
URL for the base DA client.

- DA_CONFIG=(default: `{"base_url":"'$DA_BASE_URL'","timeout":60000000000,"fee":6000,"gas_limit":6000000,"fee":600000,"auth_token":"'$DA_AUTH_TOKEN'"}`

Configure custom json formatted value for `--rollkit.da_config` arguments, see: `chain/scripts/start-rollup.sh`.
Configuration for the DA.

### Cosmos SDK

The following variables are used to configure the Cosmos SDK node.

- VALIDATOR_NAME
Moniker for the node.
- CHAIN_ID
ChainID of the rollup.
- KEY_NAME
The name of the key to use for the genesis account.
- KEY_MNEMONIC
The mnemonic to use for the genesis account.
- KEY_BACKEND
The backend type to use for the genesis account.
- TOKEN_AMOUNT
The amount of tokens to supply the genesis account with.
- STAKING_AMOUNT
The amount of tokens to use for stake.
- MIN_GAS_PRICE
The minimum gas prices for accounts executing transactions on this node.
- TOKEN_DENOM
The denom of the staking token.
7 changes: 7 additions & 0 deletions chain/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"io"
"math"
"math/big"
"os"
"path/filepath"
evmtypes "pkg.berachain.dev/polaris/cosmos/x/evm/types"
Expand Down Expand Up @@ -120,6 +122,8 @@ type App struct {
Router router.Router
ShardSequencer *shard.Sequencer

faucetAddr sdk.AccAddress

// simulation manager
sm *module.SimulationManager
}
Expand Down Expand Up @@ -293,6 +297,9 @@ func (app *App) FinalizeBlockHook(ctx sdk.Context, _ *types.RequestFinalizeBlock
}
}
}
if app.faucetAddr != nil {
app.EVMKeeper.SetBalance(ctx, app.faucetAddr, big.NewInt(math.MaxInt64))
}
return nil
}

Expand Down
Loading

0 comments on commit 499676c

Please sign in to comment.