Running a Facet Node

Introduction

To run a Facet node you will need two pieces of software: facet-node and facet-geth. This architecture follows the Consensus/Execution split on the Ethereum L1, with facet-node acting as the consensus client and facet-geth as the execution layer.

facet-geth is a fork of Optimism's op-geth. facet-node is modeled after op-node, though it isn't a fork.

How it works

  1. facet-node connects to an L1 Ethereum RPC server and monitors each L1 block for Facet transactions—i.e., transactions whose "to: address is address(0xface7) or event logs whose first topic is bytes32(uint256(0xface7)).

  2. facet-node extracts the Facet transaction information and combines it with other data to form a transaction payload that facet-geth can understand (this is called a "Deposit Transaction").

  3. facet-node constructs a Facet block with these Deposit transactions and sends the block to facet-geth using the engine API. This is the same API Ethereum consensus clients use to tell the execution layer about new blocks.

facet-node is stateless. All data required to operate facet-node is stored in facet-geth.

Facet Genesis State

Facet's genesis block includes state from its initial pre-EVM implementation, [legacy] Facet. This state is deterministically generated by executing the latest Facet logic against historical [legacy] Facet transactions. From the perspective of running a Facet node all you need is the final genesis.json file which is included in the facet-geth repository.

Run a Node with Docker Compose

Ensure you have Docker or Docker Desktop installed.

Clone facet-node:

git clone https://github.com/0xFacet/facet-node
cd facet-node/docker-compose
mv .env.sample .env

Now edit .env. The defaults should be fine but you need to add your own L1_RPC_URL.

Finally, start the node:

docker compose up

And that's it!

Run a Node without Docker

  • Clone facet-node:

    git clone https://github.com/0xFacet/facet-node

    and facet-geth:

    git clone https://github.com/0xFacet/facet-geth
  • Now cd facet-node

  • Install Ruby Version Manager (RVM) if not already installed:

    \curl -sSL https://get.rvm.io | bash -s stable

    If you encounter GPG issues, run:

    gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDBd
  • Install Ruby 3.3.4:

    rvm install 3.3.4

    On macOS, if you encounter OpenSSL issues:

    rvm install 3.3.4 --with-openssl-dir=$(brew --prefix openssl@1.1)
  • Run rvm use 3.3.4

  • Run bundle install

  • Set up Foundry (make sure you install it first):

    cd contracts && forge install && forge build && cd ..
  • Set up environment variables. First copy the .sample.env files to .env.

    cp .sample.env .env 

    Now edit the files. Here's what the variables are for:

Variable
Description
Default/Example
Purpose

L1_NETWORK

Ethereum network to derive blocks from

"sepolia" or "mainnet"

Determines which Ethereum network Facet will sync from

L1_GENESIS_BLOCK

Starting L1 block number

21373000

Block number to start syncing from. Mainnet genesis: 21373000, Sepolia genesis: 7201200

LOCAL_GETH_DIR

Path to local geth directory

"/path/to/geth_dir"

Location where facet-geth is cloned

GETH_RPC_URL

Authenticated RPC endpoint

"http://127.0.0.1:8551"

Used for authenticated connections to facet-geth

NON_AUTH_GETH_RPC_URL

Non-authenticated RPC endpoint

"http://127.0.0.1:8545"

Used for non-authenticated connections to facet-geth

GETH_DISCOVERY_PORT

P2P discovery port

"30303"

Port used by facet-geth for peer discovery

BLOCK_IMPORT_BATCH_SIZE

Number of blocks per batch

"5"

Controls how many simultaneous RPC requests are made

L1_RPC_URL

Ethereum RPC endpoint

"https://eth_rpc_url"

Source of L1 block data

JWT_SECRET

Authentication secret

"0x0101..."

Must match value in /tmp/jwtsecret for auth

MIGRATION_MODE

Enable migration features

"false"

Only needed when creating genesis file

FACET_V1_VM_DATABASE_URL

Legacy database connection

""

Only needed when creating genesis file

  • Put a JWT_SECRET in /tmp/jwtsecret on your local machine:

    openssl rand -hex 32 | awk '{print "0x"$1}' > /tmp/jwtsecret
  • Run the tests to ensure everything works.

    rspec && cd contracts && forge test -vv && cd ..

Using facet-geth

To use facet-geth to process blocks instead of just in a test:

  1. From the facet-node directory, generate the geth initialization command.

    bundle exec rake geth:init_command
  2. Copy the command, cd back into facet-geth, and run it. Note, this command will restart the chain from genesis, deleting any blocks you've already derived. If you want to just restart geth without doing this you should only run the /build/bin/geth command.

  3. Finally, cd back into facet-node and start deriving Facet blocks from L1 blocks:

    bundle exec clockwork config/derive_facet_blocks.rb

You should now have facet-node and facet-geth set up and running!

Accessing Facet Data

You can use the geth's normal RPC API to get information about Facet blocks and transactions. For example eth_getBlockByNumber. You can also query the chain directly from the geth console which the above command launches. For example eth.getBlock(1).

From the perspective of querying data, Facet will behave identically to any other EVM chain.

Last updated