# InfraDAO Overview

## About InfraDAO

InfraDAO is a team of highly skilled infrastructure providers with over 30 years of combined experience. Our team spearheads research and development projects that have a significant impact on both The Graph and the entire web3 space. We continuously develop key enhancements and tooling to accelerate progress.

InfraDAO empowers new and existing infrastructure providers to deliver top-tier services to web3. We are leading exciting innovation alongside core developers in the flourishing Graph Ecosystem.


# Linux and Ethereum Clients

Linux and Ethereum clients are vital components of web3 infrastructure. To understand their importance, it's useful to understand their relationship.

Web3 powers decentralized applications (dapps) on the Ethereum network. Linux is an open-source operating system that is widely used in the development and deployment of web3 infrastructure due to its stability, security, and flexibility. Ethereum clients, on the other hand, are software applications that enable interaction with the Ethereum blockchain. These clients are responsible for validating transactions, executing smart contracts, and maintaining the integrity of the blockchain.

Together, Linux and Ethereum clients form the foundation of web3 infrastructure and support the growth of the decentralized internet.

In this unit, we will cover the fundamentals of Linux and Ethereum clients:

| Lesson                                      | Description                                                                                                       |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| ***Introduction to Linux***                 | Covers basic commands, file system navigation, and permissions                                                    |
| ***Getting Started with Ethereum Clients*** | Provides an overview of commonly used clients                                                                     |
| ***Lab 1: Sync a Gnosis Blockchain Node***  | Allows you to apply their knowledge and practice syncing a blockchain node to the Gnosis network using Nethermind |

By understanding the principles behind Linux and Ethereum clients, you will be equipped with the necessary skills to contribute to the development and maintenance of web3 infrastructure.


# Introduction to Linux

Linux is a free and open-source operating system that is widely used in modern computing systems including servers, supercomputers, mobile devices, and embedded devices. Compared to proprietary alternatives, Linux allows users to modify and optimize the system to match their specific needs. Additionally, its powerful security features make it a popular choice for web servers and other critical infrastructure.

Linux is widely used in web3 applications due to its ability to support decentralized applications (dapps). Its modular and scalable design allows developers to build dapps that can run on a variety of devices and architectures, making it a key component in the web3 technology stack.

This lesson will cover fundamental skills and commands for working with Linux, including creating and manipulating files and directories, managing permissions and security, and using key commands to navigate and manage the system.

## Lesson objectives

* Create and manipulate folders and files
* Create and manage permissions, security, and services
* Learn key commands

## Create and manipulate folders and files

### ls

`ls` is a command used in Unix-like operating systems to list the files and directories in a given directory.

1. To list the contents of the current directory:

   ```bash
   ls
   ```
2. To list the contents of a specific directory:

   ```bash
   ls /path/to/directory
   ```
3. To list the contents of a directory in long format (displays more information about each file):

   ```bash
   ls -l /path/to/directory
   ```
4. To list the contents of a directory including hidden files:

   ```bash
   ls -a /path/to/directory
   ```

### mkdir

`mkdir` is a command used in Unix-like operating systems to create a new directory. It stands for "make directory." You can use it to create a new directory in the current directory or to create a new directory with a specified path.

1. To create a new directory in the current directory:

   ```bash
   mkdir new_directory
   ```
2. To create a new directory with a specified path:

   ```bash
   mkdir /path/to/new_directory
   ```
3. To create a new directory with multiple nested directories:

   ```bash
   mkdir -p /path/to/new_directory/nested_directory/subdirectory
   ```

   > Note: The -p option creates all the directories in the specified path, even if some of the parent directories do not exist.
4. To create multiple directories at once:

   ```bash
   mkdir directory1 directory2 directory3
   ```

   > Note: This will create three directories named "directory1," "directory2," and "directory3" in the current directory.

### cd

`cd` is a command used in Unix-like operating systems to change the current working directory. It stands for "change directory." You can use it to navigate to a different directory in the file system.

1. To change to the home directory:

   ```bash
   cd
   ```
2. To change to a specific directory:

   ```bash
   cd /path/to/directory
   ```
3. To change to the parent directory:

   ```bash
   cd ..
   ```
4. To change to the previous directory:

   ```bash
   cd -
   ```

   > Note: This will switch to the previous directory you were in.
5. To change to a directory using a relative path:

   ```bash
   cd path/to/directory
   ```

   > Note: This will change to a directory relative to the current working directory.

### touch

`touch` is a command used in Unix-like operating systems to create an empty file or update the timestamp of an existing file. It stands for "touch file." You can use it to create a new file or update the modification time of an existing file without changing its content.

1. To create a new empty file:

   ```bash
   touch filename.txt
   ```

   > Note: This will create an empty file named "filename.txt" in the current directory.
2. To create multiple files at once:

   ```bash
   touch file1.txt file2.txt file3.txt
   ```

   > Note: This will create three empty files named "file1.txt," "file2.txt," and "file3.txt" in the current directory.
3. To update the modification time of a file to a specific time:

   ```bash
   touch -t 202201010101.01 filename.txt
   ```

   > Note: This will update the modification time of the file "filename.txt" to January 1, 2022, at 1:01:01.01 AM.

### git

`git` is a command-line tool used for version control in software development. It allows developers to track changes to source code over time, collaborate with others on the same project, and revert to earlier versions of the code if necessary. With Git, you can create branches to experiment with new features, merge changes from different branches, and manage the history of the codebase.

1. To initialize a new Git repository:

   ```bash
   git init
   ```

   > Note: This will create a new Git repository in the current directory.
2. To add files to the staging area:

   ```bash
   git add filename.txt
   ```

   > Note: This will add the file "filename.txt" to the staging area, which is where you prepare changes to be committed.
3. To commit changes to the repository:

   ```bash
   git commit -m "Commit message"
   ```

   > Note: This will commit the changes in the staging area to the repository with a message describing the changes.
4. To create a new branch:

   ```bash
   git branch new-branch
   ```

   > Note: This will create a new branch named "new-branch" based on the current branch.
5. To switch to a different branch:

   ```bash
   git checkout branch-name
   ```

   > Note: This will switch to the branch named "branch-name."
6. To merge changes from one branch into another:

   ```bash
   git merge branch-name
   ```

   > Note: This will merge the changes from the branch named "branch-name" into the current branch.

### nano

`nano` is a command-line text editor for Unix-like operating systems. It allows users to create and edit text files in the terminal. With nano, you can create new files, open existing files, make changes to text, and save the changes. It is a beginner-friendly editor that is easy to use and learn.

1. To create a new file:

   ```bash
   nano filename.txt
   ```

   > Note: This will open a new file named "filename.txt" in the nano editor.
2. This will open a new file named "filename.txt" in the nano editor.

   ```bash
   nano existing_file.txt
   ```

   > Note: This will open the existing file named "existing\_file.txt" in the nano editor.
3. To make changes to the text:

   ```
   Use the arrow keys to move the cursor to the location where you want to make changes. 
   Type in the text that you want to add or delete.
   ```
4. To save changes:

   ```
   Press `Ctrl+O` to save changes to the file. Press `Ctrl+X` to exit nano.
   ```
5. To search for text:

   ```
   Press `Ctrl+W` to search for text within the file. 
   Type in the text you want to search for and press `Enter`.
   ```
6. To cut, copy, and paste text:

   ```bash
   Use the `Alt+6` shortcut to cut text, 
   `Alt+u` to undo, 
   `Alt+0` to copy text, 
   and `Alt+e` to paste text.
   ```

### vim

`vim` is a command-line text editor for Unix-like operating systems. It allows users to create and edit text files in the terminal. With vim, you can create new files, open existing files, make changes to text, and save the changes. It is a powerful and customizable editor that can be used efficiently with keyboard shortcuts. It is widely used by developers and system administrators.

1. To create a new file:

   ```bash
   vim filename.txt
   ```

   > Note: This will open a new file named "filename.txt" in the vim editor.
2. To open an existing file:

   ```bash
   vim existing_file.txt
   ```

   > Note: This will open the existing file named "existing\_file.txt" in the vim editor.
3. To make changes to the text:

   ```
   Use the arrow keys to move the cursor to the location where you want to make changes. 
   Type in the text that you want to add or delete.
   ```
4. To save changes:

   ```
   Press `Esc` to enter command mode, then type `:w` and press `Enter` to save changes to the file.
   Type `:q` and press `Enter` to quit vim.
   ```
5. To search for text:

   ```
   Press `/` to enter search mode. 
   Type in the text you want to search for and press `Enter`. 
   Use `n` to go to the next match, and `N` to go to the previous match.
   ```
6. To cut, copy, and paste text:

   ```
   Use `dd` to cut a line, `yy` to copy a line, and `p` to paste a line.
   ```

### cp

`cp` is a command used in Unix-like operating systems to copy files or directories. It allows users to create a duplicate copy of an existing file or directory. The basic syntax of the `cp` command is `cp source destination`. The `source` parameter is the file or directory that you want to copy, and the `destination` parameter is where you want to copy the file or directory to.

1. To copy a file to another location:

   ```bash
   cp file.txt /path/to/destination/
   ```

   > Note: This will copy the file "file.txt" to the specified destination directory.
2. To copy a file and rename it:

   ```bash
   cp file.txt newfile.txt
   ```

   > Note: This will create a copy of "file.txt" with the new name "newfile.txt" in the same directory.
3. To copy a directory and its contents:

   ```bash
   cp -r directory/ /path/to/destination/
   ```

   > Note: This will copy the directory "directory" and its contents to the specified destination directory.
4. To overwrite an existing file:

   ```bash
   cp -f source_file.txt destination_file.txt
   ```

   > Note: This will copy the file "source\_file.txt" to "destination\_file.txt", overwriting it if it already exists. The -r option is used to copy directories recursively, and the -f option is used to force overwriting of existing files without prompting for confirmation.

### mv

`mv` is a command used in Unix-like operating systems to move or rename files and directories. It allows users to change the location or name of an existing file or directory. The basic syntax of the `mv` command is `mv source destination`. The `source` parameter is the file or directory that you want to move or rename, and the `destination` parameter is where you want to move or rename the file or directory to.

1. To move a file to another location:

   ```bash
   mv file.txt /path/to/destination/
   ```

   > Note: This will move the file "file.txt" to the specified destination directory.
2. To rename a file:

   ```bash
   mv oldname.txt newname.txt
   ```

   > Note: This will rename the file "oldname.txt" to "newname.txt" in the same directory.
3. To move a directory and its contents:

   ```bash
   mv directory/ /path/to/destination/
   ```

   > Note: This will move the directory "directory" and its contents to the specified destination directory.
4. To overwrite an existing file:

   ```bash
   mv -f source_file.txt destination_file.txt
   ```

   Note: This will move the file "source\_file.txt" to "destination\_file.txt", overwriting it if it already exists. The `-f` option is used to force overwriting of existing files without prompting for confirmation.

### cat

`cat` is a command used in Unix-like operating systems to display the contents of a file on the terminal. It allows users to view the content of one or more files in their entirety. The basic syntax of the cat command is cat file1 file2 file3. The file1, file2, and file3 parameters represent the names of the files that you want to view the contents of.

1. To display the contents of a single file:

   ```bash
   cat file.txt
   ```

   Note: This will display the contents of the file "file.txt" on the terminal.
2. To concatenate multiple files into one file:

   ```bash
   cat file1.txt file2.txt > combined.txt
   ```

   Note: This will concatenate the contents of "file1.txt" and "file2.txt" into a new file named "combined.txt".
3. To display the contents of a file with line numbers:

   ```bash
   cat -n file.txt
   ```

   Note: This will display the contents of the file "file.txt" on the terminal with line numbers added to each line.
4. To display the contents of a file and scroll through it:

   ```bash
   cat file.txt | less
   ```

   Note: This will display the contents of the file "file.txt" on the terminal using the less command, which allows for scrolling through the file. The > operator is used to redirect the output of the cat command to a new file, and the | operator is used to pipe the output of one command to another command.

### echo

`echo` is a command used in Unix-like operating systems to print text to the terminal or redirect it to a file. It allows users to output text or variables as text strings. The basic syntax of the `echo` command is `echo [option] [string]`. The `[option]` parameter is optional and can be used to modify the behavior of the `echo` command, while the `[string]` parameter is the text that you want to print or redirect.

1. To display a message on the terminal:

   ```bash
   echo "Hello, World!"
   ```

   > Note: This will print the message "Hello, World!" on the terminal.
2. To redirect text to a file:

   ```bash
   echo "This is a text file." > text.txt
   ```

   > Note: This will create a new file named "text.txt" and write the text "This is a text file." to it.
3. To append text to an existing file:

   ```bash
   echo "This is more text." >> text.txt
   ```

   > Note: This will append the text "This is more text." to the end of the existing "text.txt" file.
4. To use a variable in an echo statement:

   ```bash
   NAME="John"
   echo "My name is $NAME."
   ```

   > Note: This will print the message "My name is John." on the terminal, using the variable $NAME in the text string. The > operator is used to redirect the output of the echo command to a new file, and the >> operator is used to append the output to an existing file.

### >

The `>` operator is used in Unix-like operating systems to redirect the output of a command to a file. It allows users to create a new file or overwrite the contents of an existing file with the output of a command. The basic syntax of the `>` operator is `command > file`. The `command` parameter represents the command whose output you want to redirect, and the `file` parameter represents the file that you want to redirect the output to.

1. To redirect the output of a command to a file instead of displaying it on the terminal:

   ```bash
   ls -la > file_list.txt
   ```

   > Note: This will run the ls command with the -la option, which lists all files in the current directory, including hidden files, and redirects the output to a new file named "file\_list.txt".

### >>

The `>>` operator is used in Unix-like operating systems to append the output of a command to an existing file. It allows users to add new content to the end of a file without overwriting any existing content. The basic syntax of the `>>` operator is `command >> file`. The `command` parameter represents the command whose output you want to append, and the `file` parameter represents the file that you want to append the output to.

1. To append the output of a command to an existing file:

   ```bash
   ls -la >> file_list.txt
   ```

   > Note: This will run the ls command with the -la option, which lists all files in the current directory, including hidden files, and append the output to an existing file named "file\_list.txt".

### |

The `|` (pipe) operator in Unix-like operating systems is used to redirect the output of one command to the input of another command. It allows users to chain together multiple commands to perform more complex operations without having to save intermediate results to files. The basic syntax of the `|` operator is `command1 | command2`. The `command1` parameter represents the command whose output you want to redirect, and the `command2` parameter represents the command that will receive the redirected output as input.

1. To list all files in the current directory and then search for a specific file within that list:

   ```bash
   ls | grep specific_file
   ```

   > Note: This will list all files in the current directory and then search for the string "specific\_file" within that list.
2. To count the number of files in the current directory:

   ```bash
   ls | wc -l
   ```

   > Note: This will list all files in the current directory and then count the number of lines in the output, which is equivalent to the number of files in the directory.
3. To sort the output of a command alphabetically:

   ```bash
   command | sort
   ```

   > Note: This will run the command and sort the output alphabetically. The | operator can be used with any command that produces output to the console. It is a powerful tool for chaining together commands to perform more complex operations.

### rm

The `rm` command in Unix-like operating systems is used to remove or delete files and directories. The basic syntax of the `rm` command is `rm [options] [file(s)]`. The `options` parameter represents any additional options you want to use with the command, and the `file(s)` parameter represents the name(s) of the file(s) you want to remove. By default, `rm` does not prompt for confirmation before deleting files, so it's important to be careful when using this command.

1. To remove a single file:

   ```bash
   rm filename.txt
   ```

   > Note: This will remove the file named "filename.txt" from the current directory.
2. To remove multiple files at once:

   ```bash
   rm file1.txt file2.txt file3.txt
   ```

   > Note: This will remove the files named "file1.txt", "file2.txt", and "file3.txt" from the current directory.
3. To remove a directory and all its contents:

   ```bash
   rm -r directory_name
   ```

   > Note: This will remove the directory named "directory\_name" and all its contents, including any files and subdirectories. The -r option is required to remove directories with rm, as directories are not removable by default. It's important to be careful when using the rm command, as it permanently deletes files and directories without any way to recover them.

### curl

`curl` is a tool used to transfer data to or from a server, using one of several supported protocols, including HTTP, FTP, and SMTP. The basic syntax of the `curl` command is `curl [options] [URL]`. The `options` parameter represents any additional options you want to use with the command, and the `URL` parameter represents the URL of the server you want to communicate with.

1. To retrieve the contents of a web page:

   ```bash
   curl https://example.com
   ```

   > Note: This will retrieve the contents of the web page at <https://example.com> and display it in the terminal.
2. To download a file from a server:

   ```bash
   curl -O https://example.com/file.txt
   ```

   > Note: This will download the file named file.txt from the server at <https://example.com> and save it to the current directory.
3. To upload a file to a server:

   ```bash
   curl -F "file=@/path/to/file.txt" https://example.com/upload.php
   ```

   > Note: This will upload the file located at /path/to/file.txt to the server at <https://example.com/upload.php> using a POST request.

### wget

`wget` is a tool used to download files from the internet. It supports various protocols such as HTTP, HTTPS, and FTP. Its basic syntax is `wget [options] [URL]`. The `options` parameter represents any additional options you want to use with the command, and the `URL` parameter represents the URL of the file you want to download. `wget` is a powerful tool that can be used to download large files, recursively download entire directories, and continue interrupted downloads.

1. Download a file from a URL:

   ```bash
   wget https://example.com/file.zip
   ```
2. Download a file and save it with a different name:

   ```bash
   wget -O newfile.zip https://example.com/file.zip
   ```
3. Download a file and continue the download if it is interrupted:

   ```bash
   wget -c https://example.com/largefile.iso
   ```
4. Download multiple files from a URL:

   ```bash
   wget -i urls.txt
   ```

   > Note: where urls.txt is a text file containing one URL per line.
5. Limit the download speed:

   ```bash
   wget --limit-rate=500k https://example.com/largefile.iso
   ```
6. Download a file over FTP:

   ```bash
   wget ftp://ftp.example.com/file.zip
   ```
7. Download a file using a proxy server:

   ```bash
   wget --proxy=on --proxy-user=user --proxy-password=pass https://example.com/file.zip
   ```

### screen

`screen` is a terminal multiplexer that allows you to create and manage multiple terminal sessions within a single window. With `screen`, you can run multiple shell instances, detach from them and reattach to them later, and share sessions with other users. Once inside a screen session, you can use various keyboard shortcuts to navigate between multiple windows, split screens, and perform other tasks. `screen` is particularly useful for remote server management or for running long-running processes that you want to keep running even if you log out of your shell.

1. Start a new screen session with a specific name:

   ```bash
   screen -S mysession
   ```
2. Detach from a screen session:

   ```
   Press `Ctrl-a` followed by the `d` key.
   ```
3. Reattach to a detached screen session:

   ```bash
   screen -r mysession
   ```
4. Create a new window within a screen session:

   ```
   Press `Ctrl-a` followed by the `c` key.
   ```
5. Switch between windows in a screen session:

   ```
   Press `Ctrl-a` followed by the `n` key to move to the next window
   or `Ctrl-a` followed by the `p` key to move to the previous window.
   ```
6. Split the screen horizontally:

   ```
   Press `Ctrl-a` followed by the `S` key.
   ```
7. Split the screen vertically:

   ```
   Press `Ctrl-a` followed by the `|` key.
   ```
8. List available screen sessions:

   ```bash
   screen -ls
   ```

### tar

The `tar` command is used for archiving and compressing files in a single file, often called a "tarball". It is a command-line utility commonly used in Linux and Unix operating systems.

1. To create a compressed tarball of a directory and its contents:

   ```bash
   tar -czvf myfiles.tar.gz /path/to/my/directory/
   ```
2. To extract a compressed tarball to a specific directory:

   ```bash
   tar -xzvf myfiles.tar.gz -C /path/to/extracted/directory/
   ```
3. To add a file to an existing tarball:

   ```bash
   tar -rvf myfiles.tar /path/to/newfile.txt
   ```
4. To extract a specific file from an existing tarball:

   ```bash
   tar -xvf myfiles.tar /path/to/file.txt
   ```
5. To create an incremental backup of a directory using a dated tarball filename:

   ```bash
   tar -czvf myfiles-$(date +%Y%m%d).tar.gz --listed-incremental=/path/to/backup.snar /path/to/my/directory/
   ```

### unzip

The `unzip` command is used to extract files from a compressed archive in the ZIP format. Here's a short explanation:

1. To extract all files from an archive named archive.zip:

   ```bash
   unzip archive.zip
   ```
2. To extract a specific file named example.txt from an archive named archive.zip:

   ```bash
   unzip archive.zip example.txt
   ```
3. To extract an archive named archive.zip into a directory named extracted\_files:

   ```bash
   unzip archive.zip -d extracted_files/
   ```
4. To list the contents of an archive named archive.zip without extracting them:

   ```bash
   unzip -l archive.zip
   ```

### dtrx

The `dtrx` command is a tool used for extracting various archive file formats. It can automatically detect the archive type and use the appropriate extraction tool. It can also handle nested archives, and can extract files to a specific directory.

1. To extract a single archive file named `archive.tar.gz` to the current directory:

   ```bash
   dtrx archive.tar.gz
   ```
2. To extract a nested archive file named `nested_archive.zip` that is located within another archive file named `archive.tar.gz` to the current directory:

   ```bash
   dtrx archive.tar.gz
   cd archive
   dtrx nested_archive.zip
   ```
3. To extract a single archive file named `archive.tar.bz2` to a specific directory named `my_folder`:

   ```bash
   dtrx -n my_folder archive.tar.bz2
   ```
4. To list the contents of an archive file named archive.tar.gz without extracting them:

   ```bash
   dtrx -l archive.tar.gz
   ```

## Create and manage permissions, security, and services

### chmod

`chmod` is a command used in Linux/Unix to change the permissions of files or directories. It allows the user to grant or revoke read, write, and execute permissions to themselves, their group, or others. The permissions can be set using numerical values or symbols such as u (user), g (group), o (others), and a (all).

1. Set read, write, and execute permissions for the owner, and only read and execute permissions for the group and others:

   ```bash
   chmod 755 filename
   ```
2. Remove write permission for the group and others:

   ```bash
   chmod go-w filename
   ```
3. Add execute permission for the owner and group:

   ```bash
   chmod ug+x filename
   ```
4. Set read and write permissions for the owner and group, but no permissions for others:

   ```bash
   chmod ug=rw,o= filename
   ```
5. Recursively change the permissions for all files and directories in a directory:

   ```bash
   chmod -R 755 directory
   ```

### chown

The `chown` command is used in Linux/Unix to change the owner and/or group ownership of a file or directory. This command is particularly useful when transferring files or granting permissions. It allows the administrator to specify who can read, write, or execute the file/directory.

1. Change the ownership of a file to a specific user and group:

   ```bash
   chown user:group file.txt
   ```

   > Note: This command changes the ownership of file.txt to the user user and the group group.
2. Change the ownership of a directory and all of its contents:

   ```bash
   chown -R user:group /path/to/directory
   ```

   > Note: This command recursively changes the ownership of the directory /path/to/directory and all of its contents to the user user and the group group.
3. Change the ownership of a file to the current user:

   ```bash
   chown $USER file.txt
   ```

   > Note: This command changes the ownership of file.txt to the current user.
4. Change the ownership of a file to the root user:

   ```bash
   sudo chown root file.txt
   ```

   > Note: This command changes the ownership of file.txt to the root user.

### whoami

The `whoami` command in Linux displays the current username of the user who is logged in to the system. It is a simple and useful command that can be used to verify the identity of the current user.

1. To display the current user name:

   ```bash
   whoami
   ```
2. To use the whoami output in a script:

   ```bash
   user=$(whoami)
   echo "Hello, $user!"
   ```

   > Note: This script will output a greeting message that includes the current user name.
3. To check if the current user has sudo privileges:

   ```bash
   if [[ $(whoami) == "root" ]]; then echo "I have sudo privileges"; else echo "I don't have sudo privileges"; fi
   ```

   > Note: This command will check if the current user is "root" and print a message accordingly.

### adduser

The `adduser` command in Linux is used to create a new user account on the system. It prompts for the user's name and password, creates a home directory, and adds the user to the system. The command also allows for additional options such as specifying the user's group or setting a custom home directory.

1. To add a new user account with default settings:

   ```bash
   sudo adduser username
   ```
2. To add a new user account and set the home directory:

   ```bash
   sudo adduser --home /home/newuser username
   ```
3. To add a new user account with a specific user ID (UID):

   ```bash
   sudo adduser --uid 1001 username
   ```
4. To add a new user account with a specific group ID (GID):

   ```bash
   sudo adduser --gid 1001 username
   ```
5. To add a new user account and specify additional groups:

   ```bash
   sudo adduser --groups group1,group2 username
   ```

Note: The adduser command may vary depending on the Linux distribution and version being used. It is recommended to refer to the documentation for the specific system to ensure proper usage.

### usermod

The `usermod` command in Linux is used to modify user account attributes such as username, home directory, login shell, and group membership. It is used to make changes to an existing user account.

1. Change the username of an existing user:

   ```bash
   sudo usermod -l newusername oldusername
   ```
2. Add a user to a secondary group:

   ```bash
   sudo usermod -a -G groupname username
   ```
3. Remove a user from a secondary group:

   ```bash
   sudo usermod -G groupname1,groupname2 username
   ```
4. Lock or unlock a user account:

   ```bash
   sudo usermod -L username
   sudo usermod -U username
   ```
5. Change the default shell for a user:

   ```bash
   sudo usermod -s /bin/zsh username
   ```

### sudo

`sudo` is a command used in Linux to grant temporary root privileges to a normal user account. It allows users to execute commands with elevated privileges without logging in as the root user. The user running the `sudo` command will need to enter their own password to confirm their identity. This helps to improve security by allowing administrators to grant certain privileges to users without giving them full administrative access.

1. Updates the list of available packages and their versions from the server:

   ```bash
   sudo apt-get update
   ```
2. Installs a package with administrative privileges:

   ```bash
   sudo apt-get install <package_name>
   ```
3. Restarts a system service:

   ```bash
   sudo systemctl restart <service_name>
   ```
4. Adds a new user to the system:

   ```bash
   sudo useradd <username>
   ```
5. Changes the file permission to allow read, write, and execute for the owner, and only read and execute for others.

   ```bash
   sudo chmod 755 <file_name>
   ```

### su

The `su` (short for "substitute user") command is used to switch to another user account or to run commands with a different user's privileges. When executed without specifying a username, it will switch to the root user. The `su` command is often used by system administrators to perform administrative tasks that require elevated privileges. It is also commonly used to temporarily switch to another user's account in order to run commands or perform tasks as that user.

1. To switch to the root user:

   ```bash
   su -
   ```
2. To switch to another user, such as "jdoe":

   ```bash
   su - jdoe
   ```
3. To switch to a user without changing the current working directory:

   ```bash
   su jdoe
   ```
4. To switch to a user and run a specific command as that user:

   ```bash
   su - jdoe -c "ls -l"
   ```
5. To switch to a user and start a new shell session as that user:

   ```bash
   su - jdoe -s /bin/bash
   ```

### ssh

The `ssh` command is used to establish a secure shell connection to a remote server. It allows a user to log in to a remote machine and execute commands on it securely. The command uses encryption to protect the communication between the client and the server, preventing unauthorized access to sensitive information.

1. To connect to a remote server with username and IP address:

   ```bash
   ssh username@ip_address
   ```
2. To connect to a remote server with a specific port:

   ```bash
   ssh -p port_number username@ip_address
   ```
3. To specify a private key file for authentication:

   ```bash
   ssh -i /path/to/private_key username@ip_address
   ```
4. To run a command on a remote server:

   ```bash
   ssh username@ip_address command
   ```
5. To copy a file from a remote server to a local machine:

   ```bash
   scp username@ip_address:/path/to/remote/file /path/to/local/file
   ```

### ssh-keygen

The `ssh-keygen` command is used to generate SSH keys for secure authentication between remote systems. It creates a public and private key pair that can be used to authenticate with a remote system without requiring a password. The private key is kept on the local system and the public key is added to the remote system's authorized keys file.

1. Generate a new RSA key pair with the default settings:

   ```bash
   ssh-keygen
   ```
2. Generate a new Ed25519 key pair:

   ```bash
   ssh-keygen -t ed25519
   ```
3. Generate a new RSA key pair with a specific name and location:

   ```bash
   ssh-keygen -t rsa -b 4096 -C "my_key" -f /path/to/my_key
   ```
4. Generate a new key pair and set a passphrase:

   ```bash
   ssh-keygen -t rsa -b 2048 -N "my_passphrase" -f ~/.ssh/my_key
   ```
5. Generate a new key pair and save it to a different directory:

   ```bash
   ssh-keygen -t rsa -b 2048 -f ~/my_key -P "" -m PEM -q -O force-command="echo 'This account can only be used for SFTP'"
   ```

### ufw

`ufw` stands for Uncomplicated Firewall, which is a user-friendly command-line tool for managing firewall rules in Ubuntu and other Linux distributions. It allows users to easily configure rules to block or allow incoming and outgoing network traffic on their system.

1. Enable the UFW firewall:

   ```bash
   sudo ufw enable
   ```
2. Allow incoming SSH traffic:

   ```bash
   sudo ufw allow ssh
   ```
3. Allow incoming traffic on port 80 for HTTP:

   ```bash
   sudo ufw allow 80/tcp
   ```
4. Allow incoming traffic on port 443 for HTTPS:

   ```bash
   sudo ufw allow 443/tcp
   ```
5. Deny incoming traffic on a specific port:

   ```bash
   sudo ufw deny 22/tcp
   ```
6. Allow outgoing traffic to a specific IP address:

   ```bash
   sudo ufw allow out to 203.0.113.0/24
   ```
7. Delete a specific firewall rule:

   ```bash
   sudo ufw delete allow 80/tcp
   ```
8. Disable the UFW firewall:

   ```bash
   sudo ufw disable
   ```

### systemctl

`systemctl` is a command-line tool for controlling the `systemd` system and service manager, which is used in most modern Linux distributions. It allows the user to manage and control various system services, daemons, and targets, such as starting, stopping, enabling, or disabling them.

1. To start a service:

   ```bash
   sudo systemctl start service-name
   ```
2. To stop a service:

   ```bash
   sudo systemctl stop service-name
   ```
3. To restart a service:

   ```bash
   sudo systemctl restart service-name
   ```
4. To check the status of a service:

   ```bash
   sudo systemctl status service-name
   ```
5. To enable a service to start at boot:

   ```bash
   sudo systemctl enable service-name
   ```
6. To disable a service from starting at boot:

   ```bash
   sudo systemctl disable service-name
   ```
7. To reload the configuration of a service:

   ```bash
   sudo systemctl reload service-name
   ```
8. To list all active services:

   ```bash
   sudo systemctl list-units --type=service
   ```
9. To check if a service is enabled:

   ```bash
   sudo systemctl is-enabled service-name
   ```
10. To check if a service is running:

    ```bash
    sudo systemctl is-active service-name
    ```

## Some helpful commands

### !!

The `!!` command is a shell shortcut that allows you to repeat the previous command. It simply executes the previous command in the command history. It is a quick way to repeat a command without having to type it out again.

1. Suppose you mistakenly entered a command as a non-root user that required root permissions. You can use `sudo !!` to quickly execute the same command as root.
2. If you want to repeat a command with slight modifications, you can use `!!` and then edit the command to suit your needs.
3. If you accidentally typed a command incorrectly, you can use `!!` to repeat the corrected version of the command.

### top

The `top` command is a Linux utility that provides real-time information about the processes that are currently running on the system, as well as information about the system's overall resource usage. It displays a dynamic, ordered list of running processes and updates it periodically. The `top` command is often used by system administrators to monitor the system's performance and identify processes that are consuming too many resources.

1. Simply run `top` to view a real-time dynamic display of the system's processes.
2. Use `top -u username` to display all processes that belong to a particular user.
3. To sort processes by CPU usage, press the "P" key. To sort by memory usage, press "M". To sort by process ID, press "N". To switch between ascending and descending order, press "R".
4. Use the `top -H` command to display individual threads of processes.
5. Use `top -p PID` to view the information of a particular process using its PID.

### htop

`htop` is a command-line utility for monitoring system resources on Linux. It is an improved version of the `top` command and provides a more user-friendly and interactive way of viewing and managing processes and system resource usage.

1. To start `htop` in interactive mode, simply run the command `htop` in the terminal.
2. To sort the processes by CPU usage, press the F6 key, select the "PERCENT\_CPU" option, and press Enter.
3. To search for a specific process, press the F3 key and enter the name of the process in the search field.
4. To kill a process, select it using the arrow keys and press the F9 key. Then, select the signal you want to send to the process (e.g. SIGTERM or SIGKILL) and press Enter.
5. To monitor a specific user's processes, press the F4 key and enter the username in the "Setup filter" field.
6. To change the color scheme, press the F2 key and select "Colors" from the menu. You can then select a pre-defined color scheme or customize your own.

### ps

The `ps` command in Linux is used to display information about the running processes on a system. It can be used to view the currently running processes, their process IDs (PIDs), and other information such as their CPU and memory usage.

1. Display a list of all running processes with additional information:

   ```bash
   ps aux
   ```
2. Display a process tree for all running processes:

   ```bash
   ps ef
   ```
3. Display information for a specific process ID:

   ```bash
   ps -p 1234
   ```
4. Display all processes owned by a specific user:

   ```bash
   ps -u username
   ```

### grep

The `grep` command is a command-line utility for searching for a specific pattern or regular expression in a file or output. It can be used to search for specific strings in a single file or across multiple files. The command returns the lines containing the search string and is commonly used in conjunction with other commands in a pipeline.

1. Search for the pattern in the specified file and displays all lines that contain the pattern.

   ```bash
   grep pattern file.txt
   ```
2. Search for the pattern in the specified file, ignoring case sensitivity:

   ```bash
   grep -i pattern file.txt
   ```
3. Search for the pattern recursively in all files within the specified directory and its subdirectories.

   ```bash
   grep -r pattern /directory
   ```
4. List all running processes and filters the output to display only the process with the specified name.

   ```bash
   ps -ef | grep process_name
   ```
5. Search through the command history and displays only the commands that contain the specified name.

   ```bash
   history | grep command_name
   ```

### netstat

`netstat` (network statistics) is a command-line tool used to display various information about network connections, routing tables, and network interfaces on a Linux system. It can be used to view active network connections, check listening ports, display network statistics, and monitor network activity. This information can be helpful in troubleshooting network issues, monitoring network traffic, and identifying network security threats.

1. Show all active network connections and the processes that are listening on those connections.

   ```bash
   netstat -tulpn
   ```
2. Display the kernel routing table.

   ```bash
   netstat -r
   ```
3. Display statistics for each protocol.

   ```bash
   netstat -s
   ```
4. Display all active network connections, both listening and non-listening.

   ```bash
   netstat -a
   ```
5. Display all listening network connections.

   ```bash
   netstat -l
   ```
6. Display network addresses as numbers rather than host and domain names

   ```bash
   netstat -n
   ```
7. Display the process ID and name of the program using each network connection.

   ```bash
   netstat -p
   ```
8. Display a continuous stream of network connection information.

   ```bash
   netstat -c
   ```

### ifconfig

The `ifconfig` command is a network configuration tool used to display and manage network interface configuration. It shows the status of the network interfaces available on a system and can be used to configure and troubleshoot network-related problems. With the `ifconfig command`, you can view the IP address, netmask, and other network-related information about each interface on the system. You can also use it to assign an IP address, enable or disable an interface, and configure other network-related settings.

1. To display the configuration of all network interfaces:

   ```bash
   ifconfig -a
   ```
2. To display only the IP addresses of all network interfaces:

   ```bash
   ifconfig | grep 'inet '
   ```
3. To configure a network interface with a specific IP address:

   ```bash
   sudo ifconfig eth0 192.168.1.100 netmask 255.255.255.0
   ```
4. To bring up a network interface that is currently down:

   ```bash
   sudo ifconfig eth0 up
   ```
5. To bring down a network interface:

   ```bash
   sudo ifconfig eth0 down
   ```

### ip

The `ip` command is used for configuring and displaying network interfaces and routing tables in Linux. It is a replacement for the older `ifconfig` command and provides more advanced and detailed information about network configurations. It can be used for assigning IP addresses to interfaces, setting up routes, configuring VLANs, tunnels, and bridges, and managing network namespaces.

1. To show the IP address of a network interface:

   ```bash
   ip address show eth0
   ```
2. To set the IP address of a network interface:

   ```bash
   ip address add 192.168.1.10/24 dev eth0
   ```
3. To delete an IP address from a network interface:

   ```bash
   ip address del 192.168.1.10/24 dev eth0
   ```
4. To show the routing table:

   ```bash
   ip route show
   ```
5. To add a route to the routing table:

   ```bash
   ip route add 192.168.2.0/24 via 192.168.1.1 dev eth0
   ```
6. To delete a route from the routing table:

   ```bash
   ip route del 192.168.2.0/24 via 192.168.1.1 dev eth0
   ```

### iptables

`iptables` is a powerful command-line tool used to manage the Linux firewall. It allows you to set up rules and filters to control network traffic coming into and out of your system. Using `iptables`, you can create rules to accept or reject traffic based on various criteria such as the source IP address, destination IP address, protocol, and port number.

1. Allow all incoming traffic from a specific IP address:

   ```bash
   iptables -A INPUT -s 192.168.1.100 -j ACCEPT
   ```
2. Block all incoming traffic from a specific IP address:

   ```bash
   iptables -A INPUT -s 192.168.1.100 -j DROP
   ```
3. Allow all traffic to a specific port:

   ```bash
   iptables -A INPUT -p tcp --dport 22 -j ACCEPT
   ```
4. Block all traffic to a specific port:

   ```bash
   iptables -A INPUT -p tcp --dport 22 -j DROP
   ```
5. Allow all traffic on the loopback interface:

   ```bash
   iptables -A INPUT -i lo -j ACCEPT
   ```
6. Block all traffic from a specific network interface: \`\` bash iptables -A INPUT -i eth0 -j DROP

   ```
   ```

### nftables

`nftables` is a command-line utility in Linux used to manage the Netfilter firewall subsystem. It is designed to replace the previous iptables tool. It provides a simpler and more expressive syntax, improved performance, and enhanced features for managing network traffic. Using `nftables`, you can configure firewall rules and filters, create network address translation (NAT) rules, and perform packet mangling. It allows you to filter and modify network packets based on various criteria such as IP addresses, ports, protocols, and packet content.

1. Add a rule to the filter table of nftables that allows incoming TCP traffic on port 22 (SSH) to be accepted.

   ```bash
   nft add rule filter input tcp dport 22 accept
   ```
2. List all the rules that are currently configured in the nftables ruleset.

   ```bash
   nft list ruleset
   ```
3. Create a new table named nat in the nftables ruleset.

   ```bash
   nft add table nat
   ```
4. Add a new chain named prerouting to the nat table that is triggered before the routing decision is made

   ```bash
   nft add chain nat prerouting { type nat hook prerouting priority 0; }
   ```
5. Add a rule to the prerouting chain that redirects incoming TCP traffic on port 80 to the IP address 192.168.1.2.

   ```bash
   nft add rule nat prerouting tcp dport 80 dnat 192.168.1.2
   ```

### df

`df` (Disk Free) is a command in Linux/Unix systems used to display the amount of available and used disk space on a file system. It provides information about the total size of a filesystem, the amount of free space available, and the amount of space used by each directory and file within that filesystem. It is often used to identify file systems that are running low on disk space.

1. Show the disk space usage information for all mounted file systems

   ```bash
   df
   ```
2. Show the disk space usage information in a human-readable format (e.g. in gigabytes, megabytes, etc.)

   ```bash
   df -h
   ```
3. Show the disk space usage information along with the file system type

   ```bash
   df -T
   ```
4. Show the inode usage information for file systems

   ```bash
   df -i
   ```
5. Shoq the disk space usage information for all file systems, including those that are not mounted yet

   ```bash
   df -a
   ```
6. Shows the disk space usage information for a specific file system (in this example, /dev/sda1)

   ```bash
   df /dev/sda1
   ```

### openssl

`openssl` is a command-line tool used for working with secure communications over networks using SSL/TLS protocols. It provides various cryptographic functions such as generating and verifying digital signatures, creating and verifying SSL/TLS connections, generating and encrypting private keys, and more.

1. Generate a new private key

   ```bash
   openssl genpkey -algorithm RSA -out private_key.pem -aes256
   ```
2. Generate a self-signed certificate:

   ```bash
   openssl req -new -x509 -key private_key.pem -out public_cert.pem -days 365
   ```
3. Verify a certificate

   ```bash
   openssl verify public_cert.pem
   ```
4. Encrypt a file with a password:

   ```bash
   openssl enc -aes-256-cbc -salt -in file.txt -out file.txt.enc
   ```
5. Decrypt a file:

   ```bash
   openssl enc -d -aes-256-cbc -in file.txt.enc -out file.txt
   ```

### rsync

The `rsync` command is used for file synchronization and transfer between multiple systems. It can transfer files over SSH or a direct network connection and is designed to be fast and efficient. The command can also perform incremental backups and only transfer the changed parts of a file, reducing network traffic and improving transfer speed.

1. Copy files from local to remote server:

   ```bash
   rsync -avz /path/to/local/folder/ user@remote:/path/to/remote/folder/
   ```
2. Copy files from remote to local server:

   ```bash
   rsync -avz user@remote:/path/to/remote/folder/ /path/to/local/folder/
   ```
3. Sync two folders on the same server:

   ```bash
   rsync -avz /path/to/source/folder/ /path/to/destination/folder/
   ```
4. Exclude certain files or directories:

   ```bash
   rsync -avz --exclude='*.log' /path/to/source/folder/ /path/to/destination/folder/
   ```
5. Copy files in archive mode:

   ```bash
   rsync -avz --archive /path/to/source/folder/ /path/to/destination/folder/
   ```
6. Delete files on the destination that do not exist on the source:

   ```bash
   rsync -avz --delete /path/to/source/folder/ /path/to/destination/folder/
   ```

### lsb\_release

The `lsb_release` command is used to obtain information about the Linux distribution release on which the system is running. It prints the LSB (Linux Standard Base) and distribution-specific information. It can be used to determine the distribution name, release number, and codename.

1. To display the distribution-specific information:

   ```bash
   lsb_release -a
   ```
2. To display only the distribution ID:

   ```bash
   lsb_release -i
   ```
3. To display only the distribution release number:

   ```bash
   lsb_release -r
   ```
4. To display only the description of the distribution:

   ```bash
   lsb_release -d
   ```


# Getting started with Ethereum Clients

Ethereum is a decentralized platform that allows developers to build and deploy smart contracts and decentralized applications (DApps) on top of its blockchain network. In order to interact with the Ethereum network, you need an Ethereum client. Ethereum clients come in two main types: execution layer clients and consensus layer clients. Execution layer clients are used to deploy and interact with smart contracts, while consensus layer clients participate in the consensus process of validating transactions and maintaining the blockchain network. In this lesson, we will cover the different types of Ethereum clients, how to set them up on your Linux system, and how to interact with the Ethereum network.

## Execution and Consensus Layer Node Clients

#### What is the Ethereum Consensus Layer?

The Ethereum consensus layer refers to the underlying mechanism that enables the network to reach agreement on the state of the blockchain. Consensus is essential in a decentralized system like Ethereum to ensure that all nodes in the network have the same version of the blockchain.

In Ethereum, the consensus layer is implemented using a consensus algorithm called Proof of Work (PoW), which is used to validate transactions and add new blocks to the blockchain. This process involves miners competing to solve complex mathematical puzzles, with the first miner to solve the puzzle being rewarded with newly minted Ether.

However, Ethereum is in the process of transitioning to a new consensus algorithm called Proof of Stake (PoS) through a protocol upgrade known as Ethereum 2.0. Under PoS, validators put up a stake of Ether to participate in block validation, and the probability of being selected to validate a block is proportional to the amount of Ether staked. This mechanism is expected to be more energy-efficient than PoW, which requires a lot of computational power to solve the puzzles.

In summary, the Ethereum consensus layer is the foundational mechanism that enables the network to maintain a consistent and accurate version of the blockchain, and it is implemented through a consensus algorithm such as PoW or PoS.

***

#### What is the Ethereum Execution Layer?

The Ethereum execution layer refers to the component of the Ethereum network responsible for executing and processing smart contracts and decentralized applications (DApps).

Smart contracts are self-executing contracts with the terms of the agreement between buyer and seller being directly written into lines of code. They are a key feature of the Ethereum network and enable developers to create decentralized applications that can run on the blockchain.

The execution layer of Ethereum is implemented using the Ethereum Virtual Machine (EVM), which is a virtual machine that runs on every node in the network. The EVM is responsible for executing the bytecode of smart contracts and DApps, ensuring that the execution is consistent and predictable across all nodes in the network.

The execution layer also includes a range of tools and infrastructure for developers to build and deploy smart contracts and DApps, such as the Solidity programming language and the Truffle development framework.

Overall, the Ethereum execution layer is the component of the network that enables the processing and execution of smart contracts and DApps, and it is implemented using the Ethereum Virtual Machine and associated development tools.

#### What is the relation between the Ethereum consensus layer and execution layer?

The consensus layer is responsible for maintaining the integrity and security of the network by ensuring that all nodes in the network agree on the current state of the blockchain. This is achieved through a consensus algorithm such as Proof of Work (PoW) or Proof of Stake (PoS).

The execution layer, on the other hand, is responsible for executing and processing smart contracts and DApps on the blockchain. This is achieved through the Ethereum Virtual Machine (EVM), which is a decentralized virtual machine that runs on every node in the network.

In summary, while the consensus layer ensures the consistency and security of the network, the execution layer enables developers to create and deploy decentralized applications on the blockchain.

***

### Node Clients

#### What is an Execution Layer (EL) Client?

An Ethereum execution layer client, also known as an Ethereum client, is a piece of software that allows users to interact with the Ethereum network and execute smart contracts and decentralized applications (DApps).

Ethereum clients can be divided into three main categories: full, light and archive node clients. Full nodes store a copy of the entire Ethereum blockchain and validate all transactions and smart contracts on the network, while light clients only download a portion of the blockchain and rely on full nodes to provide them with transaction data and block headers. Full nodes typically store only the most recent state of the blockchain, whereas Archive nodes store a complete history of all states since the beginning of the blockchain. This makes Archive nodes useful for querying historical blockchain data that is not accessible on Full nodes.

There are several Ethereum client implementations available, each with their own features and characteristics. Some of the most popular Ethereum clients include Geth, Nethermind, Erigon, Hyperledger Besu and OpenEthereum.

Ethereum clients typically provide a range of functionalities for interacting with the network, including sending and receiving Ether and other tokens, creating and deploying smart contracts, and interacting with DApps. They also allow developers to build and test their own DApps and smart contracts.

In summary, an Ethereum execution layer client is a software application that allows users to interact with the Ethereum network and execute smart contracts and DApps, and there are several different client implementations available.

#### Popular EL Clients

1. **Geth**: Geth is an Ethereum client implemented in the Go programming language. It is a full node client that allows users to download and store a copy of the entire Ethereum blockchain. Geth is widely used by developers and is known for its reliability and performance.
2. **OpenEthereum**: OpenEthereum, formerly known as Parity-Ethereum, is an Ethereum client implemented in Rust. It is a full node client that is designed to be modular and flexible, allowing users to customize their node's functionality. OpenEthereum is known for its ease of use and comprehensive documentation.
3. **Nethermind**: Nethermind is an Ethereum client implemented in .NET. It is a full node client that is optimized for performance and scalability. Nethermind is known for its user-friendly interface and support for mining.
4. **Besu**: Besu is an Ethereum client implemented in Java. It is a full node client that is designed to be enterprise-friendly, with features such as privacy and permissioning. Besu is known for its compatibility with enterprise blockchain use cases and its focus on interoperability.

#### What is a Consensus Layer (CL) Client?

A consensus layer client is a software application that implements the consensus rules of the Ethereum network. Consensus layer clients play a critical role in ensuring that all nodes on the network agree on the state of the blockchain. These clients are responsible for validating transactions and adding new blocks to the chain based on the rules of the Ethereum consensus protocol.

#### Polular CL Clients

Some popular Ethereum consensus layer clients include Lighthouse, Prysm, Nimbus, Teku, and Lodestar. These clients are designed to implement the Ethereum consensus protocol and are responsible for validating transactions, adding new blocks to the blockchain, and maintaining network consensus.

1. Lighthouse - Lighthouse is an open-source Ethereum 2.0 client developed by Sigma Prime. It is written in Rust and is designed to be fast, efficient, and reliable. Lighthouse supports both mainnet and testnet environments, and includes features such as validator management, peer-to-peer networking, and Eth1 integration.
2. Prysm - Prysm is an open-source Ethereum 2.0 client developed by Prysmatic Labs. It is written in Go and is designed to be easy to use and accessible to developers of all skill levels. Prysm includes features such as validator management, peer-to-peer networking, and Eth1 integration.
3. Nimbus - Nimbus is an open-source Ethereum 2.0 client developed by Status. It is written in Nim and is designed to be lightweight and resource-efficient. Nimbus supports both mainnet and testnet environments, and includes features such as validator management, peer-to-peer networking, and Eth1 integration.
4. Teku - Teku is an open-source Ethereum 2.0 client developed by ConsenSys. It is written in Java and is designed to be scalable, reliable, and secure. Teku supports both mainnet and testnet environments, and includes features such as validator management, peer-to-peer networking, and Eth1 integration.
5. Lodestar - Lodestar is an open-source Ethereum 2.0 client developed by Chainsafe. It is written in TypeScript and is designed to be modular and extensible. Lodestar supports both mainnet and testnet environments, and includes features such as validator management, peer-to-peer networking, and Eth1 integration.

Each of these clients is designed to implement the Ethereum consensus protocol, which is responsible for maintaining network consensus and ensuring the integrity of the blockchain. They provide different features and benefits, depending on the needs of the developer or organization using them.

***

### Setting Up The Client

#### EL Client

* How to Set Up the Geth Client (Homebrew)

  ```
  brew tap ethereum/ethereum
  brew install ethereum
  brew install ethereum --devel
  ```
* How to Set Up the Erigon Client

  ```
  git clone --recurse-submodules -j8 https://github.com/ledgerwatch/erigon.git
  cd erigon
  make erigon
  ./build/bin/erigon
  ```
* How to Set Up the Besu Client (Homebrew)

  ```
  brew tap hyperledger/besu
  brew install hyperledger/besu/besu
  ```
* How to Set Up the Nethermind Client (Homebrew)

  ```
  brew tap nethermindeth/nethermind
  brew install nethermind
  ```

#### CL Client

* How to Set Up the Lighthouse Client (Homebrew)

  ```
  brew install lighthouse
  ```
* How to Set Up the Prysm Client (Homebrew)

  ```
  mkdir prysm && cd prysm
  curl https://raw.githubusercontent.com/prysmaticlabs/prysm/master/prysm.sh --output prysm.sh && chmod +x prysm.sh
  ```
* How to Set Up the Nimbus Client

  ```
  git clone https://github.com/status-im/nimbus-eth1
  cd nimbus-eth1
  make update
  make nimbus
  ./build/nimbus
  ```
* How to Set Up the Teku Client (Homebrew)

  ```
  brew tap ConsenSys/teku
  brew install ConsenSys/teku/teku
  ```
* How to Set Up the Lodestar Client

  ```
  npm install -g @chainsafe/lodestar-cli
  ```


# Lab 1: Sync a Gnosis blockchain node

In this lab, you will apply your knowledge of Linux and Ethereum clients to set up a local development environment for Ethereum. You will learn how to install and configure the Nethermind client, connect to the Gnosis network, and interact with the Gnosis blockchain. By the end of this lab, you will have a functional Gnosis node running on your machine and will be ready to start exploring The Graph ecosystem.

This lab exercise assumes you are configuring a [Hetzner AX102 dedicated root server](https://www.hetzner.com/dedicated-rootserver/ax102) for your Gnosis blockchain node.

## Configure the server

### Put your Hetzner AX102 server into RescueMode

1. Log in to your Hetzner account and go to the "Server" tab.
2. Select the server you want to put into RescueMode.
3. Click on the "Rescue" tab in the server details.
4. Choose the Rescue system you want to use and click on "Activate".
5. Wait for the system to activate, which may take a few minutes.
6. Once the Rescue system is active, you can log in using the provided login credentials.

### Install the [Ubuntu 22.04](https://releases.ubuntu.com/22.04/) Linux distribution with the [`installimage`](https://docs.hetzner.com/robot/dedicated-server/operating-systems/installimage/) script

1. Use the password displayed on Hetzner Robot to log into the Rescue System as "root".
2. Run the `installimage` script by typing the following command

   ```bash
   installimage -n GnosisNode -r yes -i images/Ubuntu-2204-jammy-amd64-base.tar.gz -d sda -p /boot:ext3:1024M,lvm:vg0:all -v vg0:root:/:ext4:all
   ```

   Overall, this command will perform an installation of Ubuntu 22.04 on the "sda" device using the specified partition and logical volume layout, with the hostname set to "GnosisNode" and the server rebooting automatically after the installation is complete.

   1. `installimage` - This is the command to execute the installimage script.
   2. `-n GnosisNode` - This sets the hostname for the server to "GnosisNode".
   3. `-r yes` - This specifies that the server should automatically reboot after the installation process is complete.
   4. `-i images/Ubuntu-2204-jammy-amd64-base.tar.gz` - This specifies the path to the base installation image for Ubuntu 22.04. In this case, the file is located in the "images" directory and is named "Ubuntu-2204-jammy-amd64-base.tar.gz".
   5. `-d sda` - This specifies the device that will be used for the installation. In this case, the installation will be performed on the "sda" device.
   6. `-p /boot:ext3:1024M,lvm:vg0:all` - This specifies the partition layout for the installation. In this case, there will be two partitions created: one for the "/boot" directory, which will be formatted with the ext3 file system and will have a size of 1024MB, and one for LVM, which will contain all remaining space on the disk and will be used for logical volume management.
   7. `-v vg0:root:/:ext4:all` - This specifies the logical volume layout for the installation. In this case, one logical volume named "root" will be created in the volume group "vg0", which will be mounted at the root directory ("/") and formatted with the ext4 file system.

### Install Linux packages

1. Update packages

   ```bash
   apt update && apt upgrade 
   ```
2. Install build-essential

   ```bash
   apt install build-essential 
   ```
3. Install `git`

   ```bash
   apt install git
   ```
4. Install `unzip`

   ```bash
   apt install unzip
   ```
5. Install `ufw` firewall

   ```bash
   apt install ufw 
   ```

### User management

1. Add a new user account named `dev` to a Linux system

   ```bash
   adduser dev 
   ```
2. Adds the `dev` user to the `sudo` group, giving them the ability to execute commands with administrative privileges. Note that after running this command, the user will need to log out and log back in for the changes to take effect. This type of user account is typically used for system services or applications that need to run with a specific set of permissions, but do not require direct access to the system.

   ```bash
   usermod -aG sudo dev
   ```

   1. `usermod` - This is the command to modify user account properties.
   2. `-aG sudo` - The `-a` option appends the specified group to the user's list of groups, while the `-G` option specifies the groups to which the user should be added. In this case, the sudo group is added to the user's list of groups.
   3. `dev` - This is the username of the user account that will be modified.
3. Add a new user account named `nethermind` to a Linux system

   ```bash
   sudo useradd --no-create-home --shell /bin/false nethermind
   ```

   1. `sudo` - This command is used to run the useradd command with elevated privileges. This is necessary because creating a new user account requires administrative privileges.
   2. `useradd` - This is the command to create a new user account.
   3. `--no-create-home` - This option specifies that a home directory should not be created for the new user account.
   4. `--shell /bin/false` - This option sets the login shell for the new user account to `/bin/false`, which means that the user will not be able to log in to the system.
   5. `nethermind` - This is the username of the new user account that will be created.

### SSH

1. Switch to `dev` user

   ```bash
   su dev
   ```
2. Change the current working directory to the user's home directory.

   ```bash
   cd ~
   ```
3. Create a directory called `.ssh`

   ```bash
   mkdir .ssh
   ```
4. Create a file to store your public `ssh` keys

   ```bash
   touch .ssh/authorized_keys
   ```
5. Change the file permissions of the `.ssh` directory to `rwx------`, which means that only the owner of the directory can read, write, and execute files within it. This is useful for ensuring that sensitive files within the directory, such as private SSH keys, are only accessible to the owner of the directory.

   ```bash
   chmod 700 .ssh 
   ```

   1. `chmod` - This is the command to change the file permissions of a file or directory.
   2. `700` - This is the numerical representation of the file permissions. In this case, `7` sets the owner's permissions to `rwx` (read, write, execute), while `0` sets the permissions for the group and others to `---` (no permissions).
   3. `.ssh` - This is the name of the directory whose file permissions are being changed.
6. Change the file permissions of the `authorized_keys` file within the `.ssh` directory to `rw-------`, which means that only the owner of the file can read and write to it. This is an important security measure, as the authorized\_keys file is used to authenticate SSH connections, and granting unauthorized access to it could allow an attacker to gain access to the system.

   ```bash
   chmod 600 .ssh/authorized_keys
   ```

   1. `chmod` - This is the command to change the file permissions of a file or directory.
   2. `600` - This is the numerical representation of the file permissions. In this case, `6` sets the owner's permissions to `rw` (read, write), while `0` sets the permissions for the group and others to `---` (no permissions).
   3. `.ssh/authorized_keys` - This is the name and path of the file whose file permissions are being changed.
7. Change the current working directory to the .ssh directory within the user's home directory

   ```bash
   cd .ssh
   ```
8. Open the `authorized_keys` file in the Nano text editor for editing and paste in your public `ssh` keys. Once the user has finished editing the file, they can save their changes and exit the editor by pressing `Ctrl+X`, then `Y` to confirm the changes and `Enter` to save the file with the same name.
9. Check that you can login to your server as `dev` user with `ssh` public key authentication. Replace server\_ip\_address with the actual IP address of the server.

   ```bash
   ssh dev@server_ip_address
   ```
10. Disable `root` and password-based logins to your server

    ```bash
    sudo nano /etc/ssh/sshd_config
    ```

    1. Set `PermitRootLogin no`: This is a security best practice because the root user has unrestricted access to the entire system, so allowing remote login as root poses a significant security risk. Instead, it's recommended to log in as a non-root user with sudo privileges, and use the sudo command to perform administrative tasks.
    2. Set `PasswordAuthentication no`: This is a security best practice because it reduces the risk of brute force attacks against SSH login credentials. Public key authentication requires the use of a private key on the client machine and a corresponding public key on the server. This method of authentication is much more secure than using passwords, which can be guessed or cracked through brute force attacks.
    3. Set `UsePAM no`: The server will not use the PAM framework for authentication, and will instead rely on its own built-in authentication mechanisms. PAM is a modular system that allows for different authentication methods to be used, such as LDAP or Kerberos. However, disabling PAM can provide a more secure environment since it reduces the attack surface of the system.

### Firewall

1. Allow incoming SSH traffic on port 22 through the system's firewall. This is necessary in order to establish SSH connections to the system from remote clients, such as other computers or mobile devices.

   ```bash
   sudo ufw allow 22
   ```

   1. `sudo` - This command is used to run the `ufw` command with elevated privileges. This is necessary because modifying firewall rules requires administrative privileges.
   2. `ufw` - This is the command to manage the system's firewall rules using the `ufw` utility.
   3. `allow` - This option is used to add a new rule to allow incoming traffic through the firewall.
   4. `22` - This specifies the port number for the incoming traffic that should be allowed. In this case, port 22 is used, which is the default port for SSH traffic.
2. Allow incoming traffic on port 40403 through the system's firewall. This is useful when running a service or application that requires incoming traffic on that particular port, such as a web server or a database server.

   ```bash
   sudo ufw allow 40403
   ```
3. Enable the `ufw` (Uncomplicated Firewall) utility on your system, with administrative privileges. All incoming and outgoing traffic is blocked by default, except for ports with an `allow` rule. This is a good security measure, as it prevents unauthorized access to the system.

   ```bash
   sudo ufw enable
   ```

## Configure the blockchain client

### Nethermind

In this section, we will learn how to run Nethermind, a client implementation of the Ethereum blockchain. We will:

* Download the latest version of Nethermind from the official website
* Configure the client by editing the nethermind.cfg file to set the appropriate network ID and parameters for syncing the blockchain
* Run the Nethermind client using the appropriate command for your operating system (e.g., `nethermind.Run` for Windows or `./nethermind` for Linux/Mac)
* Monitor the client's progress using the logs and various tools available in the Nethermind interface
* Once fully synced, you can interact with the Ethereum network using the Nethermind client and start using various Ethereum-based applications and services.

1. **Installing Nethermind**

   `sudo add-apt-repository ppa:nethermindeth/nethermind`

   * Adds the Nethermind PPA to the system's software sources.
   * Allows you to install and receive updates for Nethermind using the apt package manager.

   `sudo apt install nethermind`

   * Installs the Nethermind package from the system's package repositories.
   * Downloads and installs the necessary files and dependencies for Nethermind to run.
   * Enables you to run Nethermind using the nethermind command in the terminal.

   `docker pull nethermind/nethermind`

   * docker pull is a command used to download a Docker image from a container registry.
   * nethermind/nethermind is the name of the image being downloaded from Docker Hub.
   * This command downloads the latest version of the Nethermind image from Docker Hub.
   * Once the image is downloaded, it can be used to run Nethermind in a Docker container.
2. **Configure JSON-RPC API**

   JWT Secrets - JSON Web Token authentication was added to the JSON-RPC API for security reasons to ensure that nothing interferes with the communication between the Execution Client (Nethermind in this case) and the Consensus Client. This requires you to create a file containing a hexadecimal “secret” that will be passed to each.

   To create this “Secret File” use the following command: `openssl rand -hex 32 | tr -d "\n" > "/tmp/jwtsecret"` where "/tmp/jwtsecret" will be the file path and name when created.

   Engine module needs to be explicitly switched on in the Netherming config file:

   ```
   "JsonRpc": {
       "Enabled": true,
       "Timeout": 20000,
       "Host": "127.0.0.1",
       "Port": 8545,
       "EnabledModules": ["Eth", "Subscribe", "Trace", "TxPool", "Web3", "Personal", "Proof", "Net", "Parity", "Health"],
       "EnginePort": 8551,
       "EngineHost": "127.0.0.1",
       "JwtSecretFile": "keystore/jwt-secret"
   },
   ```
3. **Run Nethermind**

   Ensure you have:

   * Installed Nethermind
   * Created a JWT secret file
   * Engine module is enabled with authenticated port

   **Running Nethermind from docker:**

   `docker run -it -v /home/user/data:/nethermind/data nethermind/nethermind --config ropsten --JsonRpc.Enabled true --JsonRpc.JwtSecretFile=PATH --datadir data --JsonRpc.EngineHost=0.0.0.0 --JsonRpc.EnginePort=8551`

   * `--config` flag \*\*\*\* is the network.
   * `v /home/user/data:/nethermind/data` sets local directory we will be storing our data to
   * `--JsonRpc.JwtSecretFile=PATH` where PATH is the location of your JWT secret ex. /tmp/jwtsecret
   * `--datadir` data maps the database, keystore, and logs all at once
4. **Run Consensus Clients**

   Once Nethermind has started you can start the CL client. See the next section for commands to install and run the CL client you installed.

To learn more about running nethermind, refer to the official docs [here](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/running-nethermind-post-merge)

## Claim your Unit 1 POAP

### Create a new issue in the Indexing 101 tutorial repository using the Unit 1 POAP Form template

1. Navigate to the [Unit 1 POAP Form template](https://github.com/IndexerDAO/docs/issues/new?assignees=\&labels=\&template=unit-1-poap-form.md\&title=%5BUnit+1+Submission%5D%3A+)
2. Update the issue with a screenshot of your `journalctl` logs and Ethereum address
3. Click `Submit new issue`


# Overview

InfraDAO provides comprehensive documentation for setting up archive nodes with all features required to Index subgraphs on The Graph Network.


# Arbitrum


# Baremetal

Authors: \[Vince | Nodeify]

## System Requirements

<table><thead><tr><th align="center">CPU</th><th width="147" align="center">OS</th><th width="165" align="center">RAM</th><th align="center">Storage</th></tr></thead><tbody><tr><td align="center">4 + core CPU</td><td align="center">Ubuntu 22.04</td><td align="center">16GB+ for Nitro and 32GB+ for Classic</td><td align="center">>= 8 TiB NVMe SSD</td></tr></tbody></table>

## Offchain Labs ⛓️

Official Docs <https://docs.arbitrum.io/node-running/how-tos/running-an-archive-node>

### Pre-requisites

Update, upgrade, and clean the system, and then install essential development tools (build-essential), firewall management (ufw), and the Git version control system.

**You must have a running Ethereum Mainnet RPC**

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install -y git docker.io docker-compose aria2 clang cmake make \
	librocksdb-dev libboost-all-dev pkg-config libusb-1.0-0-dev \
	python3 python3-pip gperf libgoogle-perftools-dev autoconf \
	automake libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev \
	liblz4-dev libzstd-dev libtool libudev-dev libssl-dev \
	libmpfr-dev libgmp-dev clang-format dtrx
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Nitro Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8546
```

{% hint style="danger" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

### Install go

Download the Go programming language distribution archive, extracts it to the "/usr/local" directory, and then removes the downloaded archive, effectively installing Go version 1.20.6 on the system.

```bash
wget https://go.dev/dl/go1.20.6.linux-amd64.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz && \
rm go1.20.6.linux-amd64.tar.gz
```

Please add the Go executable path to your system's `PATH` environment variable, and then test to ensure that Go is working correctly.

```bash
echo "export PATH=$PATH:/usr/local/go/bin:/root/.local/bin" >> /root/.bashrc
source /root/.bashrc
go version #test
```

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash 
source /root/.bashrc
nvm -v #test 
```

### Install npm and yarn

```bash
nvm install 16.0.0 && npm install --global yarn
source /root/.bashrc
npm -v #test
yarn -v #test
```

### Build Nitro with Docker

Clone the Erigon repository from GitHub, including its submodules, changes the current directory to the Erigon directory, checks out the latest release tag, and then compile the project using the "make" build system.

```bash
git clone --recurse-submodules https://github.com/OffchainLabs/nitro/
cd nitro
docker build -t nitro .
```

### Copy Nitro binary from docker to `/root/nitro/build/bin`

```bash
docker cp $(docker run -it -d nitro):/usr/local/bin/nitro /root/nitro/build/bin/
/root/nitro/build/bin/nitro -h # test
```

### Download Nitro Snapshot

```bash
mkdir -p /root/.local/share/nitro/datadir
cd /root/.local/share/nitro/datadir
#Faster but requires double the storage
aria2c --file-allocation=none -c -x 10 -s 10 https://snapshot.arbitrum.foundation/arb1/nitro-archive.tar
dtrx -f nitro-archive.tar
#Saves space but much slower
wget -O - https://snapshot.arbitrum.foundation/arb1/nitro-archive.tar | tar -x -C /root/.local/share/nitro/datadir
```

### Create service to run Nitro Node

Change flag to your Ethereum RPC `--l1.url=1.2.3.4:8545`

<pre class="language-bash"><code class="lang-bash">sudo echo "[Unit]
Description=Arbitrum Nitro Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/nitro
ExecStart=/root/nitro/build/bin/nitro \
        --node.caching.archive \
        --persistent.chain=/root/.local/share/nitro/datadir/ \
        --persistent.global-config=/root/.local/share/nitro/ \
        --l1.url=<a data-footnote-ref href="#user-content-fn-1">{YOUR_L1_RPC}</a> \
        --l2.chain-id=42161 \
        --http.api=net,web3,eth,debug \
        --http.corsdomain=* \
        --http.addr=0.0.0.0 \
        --http.port=8546 \
        --node.rpc.classic-redirect=http://0.0.0.0:8547 \
        --http.vhosts=* \
        --log-level=3

KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/nitro.service
</code></pre>

### Run Nitro

Reload the systemd manager configuration, start the Nitro service, and enable it to start automatically on system boot, ensuring that the Nitro Service is active and will be automatically started upon system startup.

```bash
sudo systemctl daemon-reload
sudo systemctl start nitro
sudo systemctl enable nitro
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Nitro service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu nitro
```

[^1]: Required L1 RPC URL


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4+ core CPU</td><td align="center">Ubuntu 22.04</td><td align="center">16GB+ for Nitro and 32GB+ for Classic</td><td align="center">>= 8TB SSD/NVME</td></tr></tbody></table>

## Offchain Labs ⛓️

Official Docs <https://docs.arbitrum.io/node-running/how-tos/running-an-archive-node>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Arbitrum directory

The first command, `mkdir arbitrum`, will create a new directory named arbitrum in the current location. The second command, `cd arbitrum`, will change your current working directory to the newly created arbitrum directory. Now you are inside the arbitrum directory and can start storing docker-compose and related files in it.

```bash
mkdir arbitrum
cd arbitrum
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
ARBITRUM_L1_URL={YOUR_L1_RPC} #RPC endpoint of Ethereum L1 RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

x-logging:
  &default-logging
  options:
    max-file: '1'
    compress: 'false'
  driver: local

networks:
  monitor-net:
    driver: bridge

volumes:
  arbitrum-nitro: {}
  arbitrum-classic: {}
  traefik_letsencrypt: {}

services:

######################################################################################
#####################         ARBITRUM NITRO CONTAINER          ######################
###################################################################################### 

  arbitrum-nitro:
    image: 'offchainlabs/nitro-node:v2.0.14-2baa834-slim-amd64'
    container_name: nitro
    restart: unless-stopped
    stop_grace_period: 30s
    user: root
    volumes:
      - 'arbitrum-nitro:/arbitrum-node'
    expose:
      - 8547
      - 8548
    command:
      - --init.url=https://snapshot.arbitrum.foundation/arb1/nitro-archive.tar
      - --node.caching.archive
      - --persistent.chain=/arbitrum-node/data/
      - --persistent.global-config=/arbitrum-node/
      - --node.rpc.classic-redirect=http://arbitrum-classic:8547/
      - --l1.url=${ARBITRUM_L1_URL}
      - --l2.chain-id=42161
      - --http.api=net,web3,eth,debug
      - --http.corsdomain=*
      - --http.addr=0.0.0.0
      - --http.vhosts=*
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.arbitrum.loadbalancer.server.port=8547"
      - "traefik.http.routers.arbitrum.entrypoints=websecure"
      - "traefik.http.routers.arbitrum.tls.certresolver=myresolver"
      - "traefik.http.routers.arbitrum.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.arbitrum.middlewares=ipwhitelist"

######################################################################################
#####################         ARBITRUM CLASSIC CONTAINER          ####################
###################################################################################### 

  arbitrum-classic:
    image: 'kw1k/arbnode:latest'
    container_name: classic
    restart: always
    stop_grace_period: 30s
    user: root
    volumes:
    - 'arbitrum-classic:/root/.arbitrum/mainnet'
    expose:
      - 8547
      - 8548
    command:
      - --l1.url=${ARBITRUM_L1_URL}
      - --l2.disable-upstream
      - --node.chain-id=42161
      - --node.rpc.tracing.enable
      - --node.rpc.tracing.namespace=trace
      - --core.checkpoint-pruning-mode=off
      - --node.cache.allow-slow-lookup
      - --core.checkpoint-gas-frequency=156250000
      - --node.rpc.addr=0.0.0.0
      - --l2.final-classic-block=22207816

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################   

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

In this step, we will create a helpful script named `arbitrum-classic-entrypoint.sh` to automatically download the initial snapshot for your Arbitrum Classic node when it starts for the first time.

```bash
sudo nano arbitrum-classic-entrypoint.sh
```

Paste the following into the file.

```
#!/bin/bash

if [ -f /root/.arbitrum/mainnet/INITIALIZED ]; then
    echo "The data directory has already been initialized."
else
    echo "lemme download the database quickly"
    rm -rf /root/.arbitrum/mainnet/db
    curl https://snapshot.arbitrum.foundation/arb1/classic-archive.tar | tar -xv -C /root/.arbitrum/mainnet/ && touch /root/.arbitrum/mainnet/INITIALIZED    
fi

echo "LFG!!!"

/home/user/go/bin/arb-node $@
```

### Run Arbitrum Node

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

### Monitor Logs

Use `docker logs` to monitor your nitro and classic nodes. The `-f` flag ensures you are following the log output

```
docker logs nitro -f
docker logs classic -f
```

## Test Arbitrum RPC 🧪

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

{% endcode %}

{% hint style="warning" %}
You should receive result.
{% endhint %}

{% code overflow="wrap" %}

```
{"jsonrpc":"2.0","id":1,"result":{"batchProcessed":308668,"batchSeen":308668,"blockNum":96352870,"broadcasterQueuedMessagesPos":0,"lastL1BlockNum":17885784,"lastl1BlockHash":"0x758b86452273e12b74cdfdc1fb11c373e25589676c09b9b42fd917015fcdeccd","messageOfLastBlock":74145055,"messageOfProcessedBatch":97883962,"msgCount":97884349}}
```

{% endcode %}


# Arbitrum Sepolia


# Baremetal

Authors: \[man4ela | catapulta.eth]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU          | OS                     | RAM          | DISK               |
| ------------ | ---------------------- | ------------ | ------------------ |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | =6TB+(SSD or NVMe) |

{% hint style="info" %}
*The Arbitrum Sepolia archive node has a size of 5.2TB on November 18th, 2024*
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum Sepolia RPC URL (e.g. Erigon) and Consensus Layer Beacon endpoint (e.g. Lighthouse) ready.
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

{% endcode %}

### Install Docker

```bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

# Install Docker Packages
 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
 # Verify Docker Installation is Successful
sudo docker run hello-world
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Mode Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Install dependencies

#### Required Software Dependencies

<table><thead><tr><th width="115">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install GO

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

source /root/.bashrc
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

<pre class="language-bash"><code class="lang-bash">source /root/.bashrc
<strong>
</strong><strong>foundryup
</strong></code></pre>

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

## Build the Nitro Node

```bash
git clone --branch v3.2.1 https://github.com/OffchainLabs/nitro.git

cd nitro

git submodule update --init --recursive --force

docker build . --tag nitro-node
```

To upgrade `nitro` check for latest version at <https://github.com/OffchainLabs/nitro/releases>:

```bash
#Copy Nitro binary from docker to /root/nitro/build/bin

docker pull offchainlabs/nitro-node:v3.2.1-d81324d

docker run -d --name nitro offchainlabs/nitro-node:v3.2.1-d81324d

docker cp nitro:/usr/local/bin/nitro /root/nitro/build/bin/
```

**Create Data directory and download latest snapshot**

```bash
cd

screen -S snapshot #start a screen session named snapshot to download a db archive for nitro:

mkdir snapshot && cd snapshot

#check for actual snapshot here 
https://snapshot-explorer.arbitrum.io/

#Download snapshot parts
aria2c -Z -x 16 "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part0" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part1" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part2" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part3" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part4" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part5" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part6" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part7" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part8" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part9" "https://snapshot.arbitrum.io/sepolia-rollup/2024-11-03-4398c4dd/archive.tar.part10"

#To quit a session window during download progress use ctrl A+D and screen -r snapshot to attach again

#extract downloaded archive parts
cat archive.tar.part0 archive.tar.part1 archive.tar.part2 archive.tar.part3 archive.tar.part4 archive.tar.part5 archive.tar.part6 archive.tar.part7 archive.tar.part8 archive.tar.part9 archive.tar.part10 | tar -xvf -

mkdir -p /root/.local/share/nitro/datadir/nitro/nitro

#move contents into data directory:

mv arbitrumdata l2chaindata keystore nodes LOCK /root/.local/share/nitro/datadir/nitro/nitro
```

#### Create Systemd service for Nitro

```bash
sudo nano /etc/systemd/system/nitro-sepolia.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Arbitrum Sepolia Nitro Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/nitro
ExecStart=/root/nitro/build/bin/nitro \
        --execution.caching.archive \
        --persistent.chain=/root/.local/share/nitro/datadir/nitro \
        --persistent.global-config=/root/.local/share/nitro/datadir \
        --parent-chain.connection.url={ETH SEPOLIA URL} \
        --chain.id=421614 \
        --http.api=net,web3,eth,debug \
        --http.corsdomain=* \
        --http.addr=0.0.0.0 \
        --http.port=9545 \
        --execution.rpc.gas-cap=0 \
        --http.vhosts=* \
        --log-level=3 \
        --parent-chain.blob-client.beacon-url={ETH SEPOLIA CL URL} \
        --validation.wasm.allowed-wasm-module-roots \
        --ws.addr=0.0.0.0 \
        --ws.port=9658 \
        --ws.api=net,web3,eth,debug \
        --ws.origins=*
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target
```

{% hint style="info" %}
Replace `{ETH SEPOLIA URL}` and `{ETH SEPOLIA CL URL}` with your synced Ethereum Sepolia and Ethereum Sepolia Consensus Layer endpoints
{% endhint %}

#### Launch Nitro

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable nitro-sepolia #enable nitro-sepolia.service at system startup

sudo systemctl start nitro-sepolia #start nitro-sepolia.service

sudo systemctl stop nitro-sepolia #stop nitro-sepolia.service

sudo nano /etc/systemd/system/nitro-sepolia.service #make changes in nitro-sepolia.service file
```

### Monitor the logs for errors

```bash
journalctl -u nitro-sepolia.service -f -n 100 #follow logs of nitro-sepolia.service
```

### Run *`curl`* command in the terminal to check the status of your node

<pre class="language-bash"><code class="lang-bash"><strong>curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:9545
</strong></code></pre>

Expected output during synchronization:

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"batchProcessed":346862,"batchSeen":346862,"blockNum":98302890,"consensusSyncTarget":98303169,"feedPendingMessageCount":0,"messageOfLastBlock":98302890,"messageOfProcessedBatch":98302538,"msgCount":98303174,"syncTargetMsgCount":98303169}}
```

{% endcode %}

When it returns `false` then your node is fully synchronized with the network

### References <a href="#references" id="references"></a>

{% embed url="<https://github.com/OffchainLabs/nitro/releases>" %}

{% embed url="<https://docs.arbitrum.io/run-arbitrum-node/nitro/build-nitro-locally>" %}


# Avalanche


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4c/8t CPU</td><td align="center">Ubuntu 22.04</td><td align="center">16GB+</td><td align="center">>= 5TB SSD/NVME</td></tr></tbody></table>

## Avalanche Go ⛰

Official Docs&#x20;

<https://docs.avax.network/nodes>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Avalanche directory

The first command, `mkdir avalanche`, will create a new directory named avalanche in the current location. The second command, `cd avalanche`, will change your current working directory to the newly created avalanche directory. Now you are inside the avalanche directory and can start storing docker-compose and related files in it.

```bash
mkdir avalanche
cd avalanche
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
  avax_data: {}
  traefik_letsencrypt: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################               AVAX CONTAINER             #######################
######################################################################################     

  avax:
    image: avaplatform/avalanchego:v1.10.7
    container_name: avax
    restart: unless-stopped
    expose:
      - "9650" # RPC
      - "9650" #/ext/metrics
    ports:
      - "9651:9651/tcp"
      - "9651:9651/udp"
    networks:
      - monitor-net
    command:
      - "/avalanchego/build/avalanchego --http-host="
    volumes:
      - avax_data:/root/.avalanchego
      - ./archive-config.json:/root/.avalanchego/configs/chains/C/config.json
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.avax-replacepath.replacepath.path=/ext/bc/C/rpc"
      - "traefik.http.services.avalanche.loadbalancer.server.port=9650"
      - "traefik.http.routers.avax.entrypoints=websecure"
      - "traefik.http.routers.avax.tls.certresolver=myresolver"
      - "traefik.http.routers.avax.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.avax.middlewares=ipwhitelist"
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

Download archive-config.json

```bash
wget https://github.com/kw1knode/node-vault/blob/main/avalanche/docker/archive-config.json
```

### Run Avalanche Node

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

### Monitor Logs

Use `docker logs` to monitor your Avalanche node. The `-f` flag ensures you are following the log output

```
docker logs avax -f
```

## Test Avalanche RPC 🧪

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

{% endcode %}

{% hint style="warning" %}
You should receive this result when synced.
{% endhint %}

{% code overflow="wrap" %}

```
{"jsonrpc":"2.0","id":1,"result":false}
```

{% endcode %}


# Base


# Erigon


# Baremetal

Authors: \[payne | stakesquid]

## System Requirements

|      CPU     |           OS           |      RAM     |          DISK         |
| :----------: | :--------------------: | :----------: | :-------------------: |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | 1TB+ (NVME preffered) |

{% hint style="info" %}
*The Base archive node reached a size of 804GB by May 2, 2024*
{% endhint %}

## Base <mark style="color:blue;">🔵</mark>

{% hint style="success" %}
Base is a secure, low-cost Ethereum L2 built on Optimism’s open-source [OP Stack](https://stack.optimism.io/). In this guide, Optimism's `op-erigon` and `op-node`binaries are built from source to facilitate the node's installation. This method has proved to sync an archive node successfully in \~48 hours using the official snapshot provided by the Base team.
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) ready.
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Base Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

## Download a snapshot

Snapshots URL: <https://snapshot.testinprod.io/>

*Create a directory and start downloading an archive in screen session as it takes \~9 hours*

{% code overflow="wrap" %}

```bash
mkdir base && cd base

screen -S archive

aria2c --file-allocation=none -c -x 10 -s 10 "https://datadirs.testinprod.io/base-mainnet-db-14631082.zst"
```

{% endcode %}

```bash
#to return to previous screen and continue installation press 

Ctrl+a+d
```

## Compile Op-node

### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install go

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
foundryup

source /root/.bashrc
```

### Install node and yarn

```bash
nvm install 16 && npm install --global yarn && nvm use 16 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

### Create directories

```bash
mkdir -p /root/github
mkdir -p /root/data/base/op-node
mkdir -p /root/data/base/op-erigon
```

### Build op-node

```bash
cd /root/github/

git clone https://github.com/ethereum-optimism/optimism.git

cd optimism

git checkout v1.7.0

nvm install && npm install --global yarn && nvm use node && npm -g install pnpm

pnpm install

pnpm build

make op-node
```

*#The binary is built at /root/github/optimism/op-node/bin/op-node*

### Create systemd service

{% hint style="warning" %}
You'll need your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) in order to run Base
{% endhint %}

{% code overflow="wrap" %}

```bash
echo "[Unit]
Description=Base OP Node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/base/op-node/
ExecStart=/root/data/optimism/op-node/bin/op-node \
        --l1=http://<your_l1_eth_node>:9656 \
        --l1.beacon=http://<your_l1_eth_beacon>:5052 \
        --l1.trustrpc=true \
        --l1.rpckind=erigon \
        --l2=http://0.0.0.0:8552 \
        --l2.jwt-secret=/root/data/base/erigon/jwt.hex \
        --rpc.addr=0.0.0.0 \
        --rpc.port=9546 \
        --rollup.config=/root/data/base/erigon/rollup.json \
        --metrics.enabled \
        --metrics.addr=0.0.0.0 \
        --metrics.port=7301 \
        --network=base-mainnet  \
        --p2p.listen.tcp=9923 \
        --p2p.listen.udp=9923 \
        --p2p.bootnodes=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \
        --verifier.l1-confs=4 \
        --rollup.load-protocol-versions=true
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-node.service
```

{% endcode %}

```bash
sudo nano /etc/systemd/system/op-node.service #make changes in op-node service file

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-node.service #start op-node

sudo systemctl enable op-node.service #enable op-node service at system startup

sudo journalctl -fu op-node.service #follow logs of op-node service
```

## Compile Erigon

```bash
cd /root/github/

git clone https://github.com/testinprod-io/op-erigon

cd op-erigon

git checkout v2.60.0-0.6.1

make
```

#### Create JWT secret file and download genesis and rollup .json files

```bash
cd /root/data/base/erigon

openssl rand -hex 32 > /root/data/base/erigon/jwt.txt
curl -LO https://raw.githubusercontent.com/base-org/node/main/mainnet/genesis-l2.json 
curl -LO https://raw.githubusercontent.com/base-org/node/main/mainnet/rollup.json

```

### Create systemd service

```bash
sudo echo "[Unit]
Description=Erigon Base Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/base/erigon/
ExecStart=/root/data/github/op-erigon/build/bin/erigon \
        --datadir=/root/data/base/erigon/datadir \
        --ethash.dagdir=/root/data/base/erigon/datadir/ethash \
        --authrpc.jwtsecret=/root/data/base/erigon/jwt.hex \
        --authrpc.port=8552 \
        --http \
        --http.addr=0.0.0.0 \
        --http.port=9660 \
        --http.compression \
        --http.vhosts=* \
        --http.corsdomain=* \
        --http.api=eth,debug,net,trace,web3,erigon \
        --private.api.addr=0.0.0.0:9095 \
        --ws --ws.compression \
        --metrics --metrics.addr=0.0.0.0 --metrics.port=9700 \
        --torrent.download.rate 80mb \
        --torrent.port=42070 \
        --rpc.returndata.limit=1000000 \
        --txpool.gossip.disable=true \
        --chain=base-mainnet \
        --db.size.limit=8TB \
        --nodiscover \
        --p2p.allowed-ports=30303,30304,30305,30306,30307,30308,30309,30310 \
        --rollup.sequencerhttp="https://mainnet-sequencer.base.org"
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-erigon.service
```

## Sync using downloaded Snapshot

```bash
screen –r archive

ls #to see the name of downloaded archive

zstd --decompress base-mainnet-db-14631082.zst -o mdbx.dat
```

*#Unzipping takes \~3-4 hrs so you can go touch some grass*

Consider switching screen by pressing`ctrl A+D`to allow a process run in the background

#### After extracting is done move the contents of geth directory into op-erigon data directoy:

```bash
mv mdbx.dat /root/data/erigon/datadir/chaindata/
```

### Start op-erigon

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-erigon.service #start op-erigon

sudo systemctl enable op-erigon.service #enable op-erigon service at system startup

sudo journalctl -fu op-erigon.service #follow logs of op-erigon service
```

{% hint style="info" %}
To check or modify `op-erigon.service` parameters simply run

`sudo nano /etc/systemd/system/op-erigon.service`

Ctrl+X and Y to save changes
{% endhint %}


# GETH


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

|      CPU     |           OS           |      RAM     |          DISK         |
| :----------: | :--------------------: | :----------: | :-------------------: |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | 6TB+ (NVME preffered) |

{% hint style="info" %}
*The Base archive node reached a size of 13TB on November 30th, 2024*
{% endhint %}

## Base <mark style="color:blue;">🔵</mark>

{% hint style="success" %}
Base is a secure, low-cost Ethereum L2 built on Optimism’s open-source [OP Stack](https://stack.optimism.io/). In this guide, Optimism's `op-geth` and `op-node`binaries are built from source to facilitate the node's installation. This method has proved to sync an archive node successfully in \~48 hours using the official snapshot provided by the Base team.
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) ready.
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Base Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

## Download a snapshot

*Create a directory and start downloading an archive in screen session as it takes \~9 hours*

{% code overflow="wrap" %}

```bash
mkdir base && cd base

screen -S archive

aria2c --file-allocation=none -c -x 10 -s 10 "https://base-snapshots-mainnet-archive.s3.amazonaws.com/$(curl https://base-snapshots-mainnet-archive.s3.amazonaws.com/latest)"
```

{% endcode %}

```bash
#to return to previous screen and continue installation press 

Ctrl+a+d
```

## Compile Op-node

### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.22</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install go

<pre class="language-bash" data-overflow="wrap" data-full-width="false"><code class="lang-bash">sudo wget https://go.dev/dl/go1.22.9.linux-amd64.tar.gz &#x26;&#x26; sudo rm -rf /usr/local/go &#x26;&#x26; sudo tar -C /usr/local -xzf go1.22.9.linux-amd64.tar.gz &#x26;&#x26; rm go1.22.9.linux-amd64.tar.gz

#to verify Go installation
go version

#If it returns Command 'go' not found simply run 
echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc
<strong>
</strong><strong>#and then apply changes with
</strong>
source /root/.bashrc
</code></pre>

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
source /root/.bashrc #or start a new terminal session to use foundryup

foundryup
```

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version 
nvm -v
npm -v
yarn -v
pnpm -v
```

### Create directories

```bash
mkdir -p /root/github
mkdir -p /root/data/base/geth/op-node
mkdir -p /root/data/base/geth/op-geth
```

### Build op-node

```bash
cd /root/github/

git clone https://github.com/ethereum-optimism/optimism.git

cd optimism

git checkout v1.9.5

make op-node
```

*#The binary is built at /root/github/optimism/op-node/bin/op-node*

### Create systemd service

{% hint style="warning" %}
You'll need your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) in order to run Base
{% endhint %}

{% code overflow="wrap" %}

```bash
echo "[Unit]
Description=Base OP Node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000

WorkingDirectory=/root/data/base/geth/op-node
Environment=OP_GETH_GENESIS_FILE_PATH=/root/data/base/geth/op-geth/genesis-l2.json \
OP_GETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org \
OP_GETH_BOOTNODES=enode://87a32fd13bd596b2ffca97020e31aef4ddcc1bbd4b95bb633d16c1329f654f34049ed240a36b449fda5e5225d70fe40bc667f53c304b71f8e68fc9d448690b51@3.231.138.188:30301,enode://ca21ea8f176adb2e229ce2d700830c844af0ea941a1d8152a9513b966fe525e809c3a6c73a2c18a12b74ed6ec4380edf91662778fe0b79f6a591236e49e176f9@184.72.129.189:30301,enode://acf4507a211ba7c1e52cdf4eef62cdc3c32e7c9c47998954f7ba024026f9a6b2150cd3f0b734d9c78e507ab70d59ba61dfe5c45e1078c7ad0775fb251d7735a2@3.220.145.177:30301,enode://8a5a5006159bf079d06a04e5eceab2a1ce6e0f721875b2a9c96905336219dbe14203d38f70f3754686a6324f786c2f9852d8c0dd3adac2d080f4db35efc678c5@3.231.11.52:30301,enode://cdadbe835308ad3557f9a1de8db411da1a260a98f8421d62da90e71da66e55e98aaa8e90aa7ce01b408a54e4bd2253d701218081ded3dbe5efbbc7b41d7cef79@54.198.153.150:30301 \
OP_NODE_L1_ETH_RPC={L1 RPC URL} \
OP_NODE_L1_BEACON={L1 BEACON RPC URL} \
OP_NODE_L2_ENGINE_AUTH= /root/data/base/geth/op-geth/jwt.hex \
OP_NODE_L2_ENGINE_RPC=http://0.0.0.0:8551 \
OP_NODE_LOG_LEVEL=info \
OP_NODE_METRICS_ADDR=0.0.0.0 \
OP_NODE_METRICS_ENABLED=true \
OP_NODE_METRICS_PORT=7200 \
OP_NODE_NETWORK=base-mainnet \
OP_NODE_P2P_AGENT=base \
OP_NODE_P2P_LISTEN_IP=0.0.0.0 \
OP_NODE_P2P_LISTEN_TCP_PORT=9222 \
OP_NODE_P2P_LISTEN_UDP_PORT=9222 \
OP_NODE_ROLLUP_CONFIG=/root/data/base/geth/op-geth/rollup.json \
OP_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \
OP_NODE_RPC_ADDR=0.0.0.0 \
OP_NODE_RPC_PORT=7545 \
OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log \
OP_NODE_VERIFIER_L1_CONFS=4 \
OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true \
OP_NODE_L1_TRUST_RPC=true

ExecStart=/root/github/optimism/op-node/bin/op-node \
--l1={L1 RPC URL} \
--l1.beacon={L1 BEACON RPC URL} \
--l2=http://0.0.0.0:8551 \
--l2.jwt-secret=/root/data/base/geth/op-geth/jwt.hex \
--rollup.config=/root/data/base/geth/op-geth/rollup.json
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-node.service

```

{% endcode %}

```bash
sudo nano /etc/systemd/system/op-node.service #make changes in op-node service file

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-node.service #start op-node

sudo systemctl enable op-node.service #enable op-node service at system startup

sudo journalctl -fu op-node.service #follow logs of op-node service
```

## Compile op-geth

```bash
cd /root/github/

git clone https://github.com/ethereum-optimism/op-geth.git

cd op-geth

git checkout v1.101411.1

make geth
```

*#The binary is built at /root/github/op-geth/build/bin/geth*

#### Create JWT secret file and download genesis and rollup .json files

```bash
cd /root/data/base/geth/op-geth/

openssl rand -hex 32 > /root/data/base/geth/op-geth/jwt.hex

curl -LO https://raw.githubusercontent.com/base-org/node/main/mainnet/genesis-l2.json 
curl -LO https://raw.githubusercontent.com/base-org/node/main/mainnet/rollup.json

```

### Create systemd service

```bash
sudo echo "[Unit]
Description=BASE OP GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/github/op-geth/build/bin/
ExecStart=/root/github/op-geth/build/bin/geth \
            --datadir=/root/data/base/geth/op-geth \
            --verbosity=3 \
            --http \
            --http.corsdomain=* \
            --http.vhosts=* \
            --http.addr=0.0.0.0 \
            --http.port=8545 \
            --http.api=web3,debug,eth,txpool,net,engine \
            --authrpc.addr=0.0.0.0 \
            --authrpc.port=8551 \
            --authrpc.vhosts=* \
            --authrpc.jwtsecret=/root/data/base/geth/op-geth/jwt.hex \
            --ws \
            --ws.addr=0.0.0.0 \
            --ws.port=8546 \
            --ws.origins=* \
            --ws.api=debug,eth,txpool,net,engine \
            --metrics \
            --metrics.addr=0.0.0.0 \
            --metrics.port=7300 \
            --syncmode=full \
            --gcmode=archive \
            --nodiscover \
            --maxpeers=100 \
            --networkid=8453 \
            --nat=extip:0.0.0.0 \
            --rollup.sequencerhttp=https://mainnet-sequencer.base.org
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-geth.service

```

{% hint style="info" %}
If you wish to sync from scratch, consider bootstraping the node first by running

`/root/github/op-geth/build/bin/geth --datadir /root/data/base/geth/op-geth init /root/data/base/geth/op-geth/genesis-l2.json`
{% endhint %}

## Sync using downloaded Snapshot

```bash
screen –r archive

ls #to see the name of downloaded archive

dtrx -f base-mainnet-archive-xxxxxx.tar.gz
```

*#Unzipping takes \~3-4 hrs so you can go touch some grass*

Consider switching screen by pressing`ctrl A+D`to allow a process run in the background

#### After extracting is done move the contents of geth directory into op-geth data directoy:

```bash
mv /root/base/snapshots/mainnet/download/geth/* /root/data/base/geth/op-geth/geth/
```

### Start op-geth

<pre class="language-bash"><code class="lang-bash">sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-geth.service #start op-geth

sudo systemctl enable op-geth.service #enable op-geth service at system startup

<strong>sudo journalctl -fu op-geth.service #follow logs of op-geth service
</strong></code></pre>

{% hint style="info" %}
To check or modify `op-geth.service` parameters simply run&#x20;

`sudo nano /etc/systemd/system/op-geth.service`

Ctrl+X and Y to save changes
{% endhint %}

#### You can also run `curl` command in the terminal to check the status of your node

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" http://localhost:8545
```

You can see If blocks increase at <https://base.blockscout.com/> by entering returned hash. It means the node is catching up and the setup is successful.

## References

{% embed url="<https://docs.optimism.io/builders/node-operators/tutorials/node-from-source>" %}

{% embed url="<https://github.com/base-org/node>" %}

{% embed url="<https://docs.base.org/tutorials/run-a-base-node>" %}


# Docker

Authors: \[Vince | Nodeify]

*Last updated at date: 10.04.2024 - updated opgeth and opnode images*

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">8c CPU</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 5TB</td></tr></tbody></table>

{% hint style="info" %}
*Note: The Base archive node consumes 5.1 TB of space on June 13.2024*
{% endhint %}

## Base 🔵

Official Docs <https://docs.base.org/guides/run-a-base-node/>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

## Setting up a domain name to access RPC

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.  Example video of [How to Point a Domain Name to an IP Address](https://www.youtube.com/watch?v=QcNBLSSn8Vg)

### Create base directory

The first command, `mkdir base`, will create a new directory named base in the current location. The second command, `cd base`, will change your current working directory to the newly created base directory. Now you are inside the base directory and can start storing docker-compose and related files in it.

```bash
mkdir base
cd base
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} ##Domain should be something like rpc.mywebsite.com, e.g. linea.infradao.org
WHITELIST={YOUR_REMOTE_MACHINE_IP} #the server's IP itself and IP's allowed to connect to RPC (eg. Indexer)
LAYER_1_RPC={YOUR_L1_RPC} #Your preferred L1 (Ethereum, not Base) node RPC URL
L1_BEACON={YOUR_L1_BEACON} #Your preferred L1 CL (Consensus Layer) Beacon endpoint, e.g. Lighthouse
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

Ensure you have an Ethereum L1 full node RPC available. It needs to be synced before Base will be able to fully sync

### Make configuration directory

```
mkdir config
cd config
```

### Download genesis.json and rollup.json

```
curl -LO https://raw.githubusercontent.com/base-org/node/v0.8.4/mainnet/genesis-l2.json
curl -LO https://raw.githubusercontent.com/base-org/node/v0.8.4/mainnet/rollup.json
```

Create `base_geth_data` docker volume

```
docker volume create base_geth_data
```

### Initialize Geth

{% hint style="warning" %}
It's required to initialize Geth if you plan to sync from scratch.

If you are going to sync using the snapshot, you shouldn't need to initialize Geth. The docker-compose would do the trick
{% endhint %}

This command runs a Docker container using the `op-geth` image. It mounts two volumes: `base_geth_data` to `/data` inside the container and `/root/base/config` to `/config`. The container then initializes the Ethereum client with a genesis file located at `/config/genesis-l2.json` using the `--datadir` option to specify the data directory as `/data`

```
docker run -v base_geth_data:/data -v /root/base/config:/config us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:0402d543c3d0cff3a3d344c0f4f83809edb44f10 --datadir=/data init /config/genesis-l2.json
```

{% hint style="info" %}
You should receive a quick output that your genesis file has been initialized.&#x20;

`INFO [08-14|19:31:15.573] Successfully wrote genesis state`
{% endhint %}

### Create jwt.hex

```
openssl rand -hex 32 | tr -d "\n" > "./jwt.hex"
```

### Create docker-compose.yml

```bash
cd ~/base
sudo nano docker-compose.yml
```

Assuming that this guide is current, you’ll be able to paste the following into the docker-compose.yml and then ctrl + x and y to save file. The more likely scenario is that this .yml template is a bit outdated and you will need to update the version under the opnode > image as well as the geth > image sections. You can find the latest releases of the op-node and geth nodes here: <https://docs.optimism.io/builders/node-operators/releases>.

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    geth_data: {}
    traefik_letsencrypt: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################            OP-NODE CONTAINER             #######################
###################################################################################### 

  opnode:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.7.0
    container_name: opnode
    networks:
     - monitor-net
    restart: unless-stopped
    expose:
      - "8545" # RPC
      - "7300" # METRICS
    ports:
      - "9222:9222"     # P2P TCP
      - "9222:9222/udp" # P2P UDP
    volumes:
      - ./config/rollup.json:/mainnet/rollup.json
      - ./config/genesis-l2.json:/mainnet/genesis-l2.json
      - ./config/jwt.hex:/root/jwt/jwt.hex:ro
    environment:
      - OP_GETH_GENESIS_FILE_PATH=/mainnet/genesis-l2.json
      - OP_GETH_SEQUENCER_HTTP=https://mainnet-sequencer.base.org
      - OP_NODE_L1_ETH_RPC=${LAYER_1_RPC}
      - OP_NODE_L1_BEACON=${L1_BEACON}
      - OP_NODE_L2_ENGINE_AUTH=/root/jwt/jwt.hex
      - OP_NODE_L2_ENGINE_RPC=http://geth:8551
      - OP_NODE_LOG_LEVEL=info
      - OP_NODE_METRICS_ADDR=0.0.0.0
      - OP_NODE_METRICS_ENABLED=true
      - OP_NODE_METRICS_PORT=7300
      - OP_NODE_P2P_AGENT=base
      - OP_NODE_P2P_BOOTNODES=enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG
      - OP_NODE_P2P_LISTEN_IP=0.0.0.0
      - OP_NODE_P2P_LISTEN_TCP_PORT=9222
      - OP_NODE_P2P_LISTEN_UDP_PORT=9222
      - OP_NODE_ROLLUP_CONFIG=/mainnet/rollup.json
      - OP_NODE_RPC_ADDR=0.0.0.0
      - OP_NODE_RPC_PORT=8545
      - OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
      - OP_NODE_VERIFIER_L1_CONFS=4
      - OP_NODE_L1_TRUST_RPC=true

######################################################################################
#####################            GETH CONTAINER             #######################
######################################################################################

  geth:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101308.2
    container_name: geth
    restart: unless-stopped
    networks:
      - monitor-net
    expose:
      - "8545"       # RPC
      - "8546"       # websocket
      - "7300"       # metrics
    ports:
      - "30303:30303" # Peers
      - "30303:30303/udp" # Peers
    volumes:
      - ./config/jwt.hex:/root/jwt/jwt.hex:ro
      - geth_data:/data
    command:
      - --datadir=/data
      - --verbosity=3
      - --http
      - --http.corsdomain=*
      - --http.vhosts=*
      - --http.addr=0.0.0.0
      - --http.port=8545
      - --http.api=web3,debug,eth,txpool,net,engine
      - --authrpc.addr=0.0.0.0
      - --authrpc.port=8551
      - --authrpc.vhosts=*
      - --authrpc.jwtsecret=/root/jwt/jwt.hex
      - --ws
      - --ws.addr=0.0.0.0
      - --ws.port=8546
      - --ws.origins=*
      - --ws.api=debug,eth,txpool,net,engine
      - --metrics
      - --metrics.addr=0.0.0.0
      - --metrics.port=7300
      - --syncmode=full
      - --gcmode=archive
      - --nodiscover
      - --maxpeers=100
      - --networkid=8453
      - --nat=extip:0.0.0.0
      - --rollup.sequencerhttp=https://mainnet-sequencer.base.org
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.base.service=base" #https
      - "traefik.http.services.base.loadbalancer.server.port=8545"
      - "traefik.http.routers.base.entrypoints=websecure"
      - "traefik.http.routers.base.tls.certresolver=myresolver"
      - "traefik.http.routers.base.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.base.middlewares=ipwhitelist"
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Optional/Recommended: Download Base Snapshot

{% hint style="success" %}
This is an optional step based on whether you want to sync the node from scratch or sync the node from a snapshot. Based on InfraDAO’s experience, we recommend downloading a snapshot and syncing the node from that snapshot. Syncing the node from the scratch took around two weeks while the snapshot took requires 9-10 hours to download, 4-6 hours to unzip, and roughly 24 hours to sync from that point.
{% endhint %}

To sync from a snapshot, visit the Base Docs to validate the recommended approach for restoring from snapshot: <https://docs.base.org/tutorials/run-a-base-node/#snapshots>. Next, in the home directory of your (i.e. the `base` folder), create a folder named `geth-data`. If you already have this folder, remove it to clear the existing state and then recreate it. Next, run the following code and wait for the operation to complete.

As downloading a snapshot takes about 9 hrs it is better to run it in a screen session

```
screen -S archive
```

Use `aria2c` to download the most recent Mainnet Archive Snapshot

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>cd ~/base
</strong>
aria2c --file-allocation=none -c -x 10 -s 10 "https://base-snapshots-mainnet-archive.s3.amazonaws.com/$(curl https://base-snapshots-mainnet-archive.s3.amazonaws.com/latest)"
</code></pre>

*press `ctrl+A and D` to return to previous screen and continue installation*

```bash
screen -r archive #will bring you back to monitor downloading progress
```

You'll then need to untar the downloaded snapshot and place the geth subfolder inside of it in the geth-data folder you created (unless you changed the location of your data directory)

```bash
tar -xvzf filename.tar.gz
# tar -xvzf base-mainnet-archive-1712388985.tar.gz
```

Next, you’ll need to move the snapshot to the where the geth data was stored in the docker container. If you initially tried to sync the node from scratch and are now trying with a snapshot:

```bash
cd /var/lib/docker/volumes/base_geth_data/_data 

rm -rf geth

cd ~/base/snapshots/mainnet/download/

mv ~/base/snapshots/mainnet/download/geth /var/lib/docker/volumes/base_geth_data/_data/

cd /var/lib/docker/volumes/base_geth_data/_data/

ls
```

### Run Base Node

```bash
cd ~/base

docker-compose up -d
```

### Monitor Logs

Use `docker logs` to monitor your geth and op-node. The `-f` flag ensures you are following the log output

```
docker logs geth -f --tail 100

docker logs opnode -f --tail 100
```

Once your Base node starts syncing, the logs should look like this:

for op-geth:

```bash
INFO [05-14|00:11:15.654] Imported new potential chain segment     number=14,428,064 hash=581e26..7e597a blocks=1 txs=43 mgas=5.638  elapsed=82.078ms    mgasps=68.687  snapdiffs=161.36KiB triedirty=0.00B
INFO [05-14|00:11:15.656] Chain head was updated                   number=14,428,064 hash=581e26..7e597a root=01059a..8a2f59 elapsed=1.210252ms
INFO [05-14|00:11:17.759] Aborting state snapshot generation       root=2c98d7..a0d61d in=0c4e7d..ec261d at=5aebd1..a6a6dc accounts=3,270,959 slots=6,006,594 storage=650.88MiB dangling=0 elapsed=7m17.533s   eta=2h24m23.981s
INFO [05-14|00:11:17.759] Resuming state snapshot generation       root=e19a42..4325ec in=0c4e7d..ec261d at=5aebd1..a6a6dc accounts=3,270,959 slots=6,006,594 storage=650.88MiB dangling=0 elapsed=7m17.534s   eta=2h24m24.001s
INFO [05-14|00:11:17.790] Imported new potential chain segment     number=14,428,065 hash=ad1eb4..fa4c07 blocks=1 txs=47 mgas=7.296  elapsed=135.218ms   mgasps=53.955  snapdiffs=166.58KiB triedirty=0.00B
```

for op-node:

```bash
t=2024-05-13T22:02:48+0000 lvl=info msg="Received signed execution payload from p2p" id=0x303089f3d89660725bfccad20d306eab71eb97dc59cf87baee419d103bae13ae:14424210 peer=16Uiu2HAmEjC9jKoKzZhM4zLHrfDGth9DTL287asWALv5JY8f5UeN
t=2024-05-13T22:02:48+0000 lvl=info msg="Optimistically queueing unsafe L2 execution payload" id=0x303089f3d89660725bfccad20d306eab71eb97dc59cf87baee419d103bae13ae:14424210
t=2024-05-13T22:02:48+0000 lvl=info msg="Sync progress" reason="unsafe payload from sequencer" l2_finalized=0x52677a4adc91111968ee08ef4e56e2fdeb89ff71ba233c7331a227175e56365f:14407839 l2_safe=0xfb6626d86728c555db2e0722e38341f79a6646ed1955a488a9ef9df5862c2064:14407925 l2_pending_safe=0xfb6626d86728c555db2e0722e38341f79a6646ed1955a488a9ef9df5862c2064:14407925 l2_unsafe=0x303089f3d89660725bfccad20d306eab71eb97dc59cf87baee419d103bae13ae:14424210 l2_time=1715637767 l1_derived=0x6380d5a1c889e951981d6c34cfb347671650b3a5f64ab2fbd4d4a2f1d7f77fe5:19861259
t=2024-05-13T22:02:48+0000 lvl=info msg="Advancing bq origin" origin=0x153e0928fe8b7dbbe93f227af8c1364e8c181bf5fb9a5412ccb92027299ee648:19861260 originBehind=false
t=2024-05-13T22:02:50+0000 lvl=info msg="Reading channel" channel=004ac887def59644f5fc6c46a1c244ae frames=6
t=2024-05-13T22:02:50+0000 lvl=info msg="Found next batch" batch_type=SpanBatch batch_timestamp=1715605199 parent_check=0xfb6626d86728c555db2e0722e38341f79a6646ed origin_check=0x1f1df86ea9abd1140e95d5bdd2b7211a4cda56ef start_epoch_number=19861236 end_epoch_number=19861252 block_count=88
t=2024-05-13T22:02:50+0000 lvl=info msg="generated attributes in payload queue" txs=37 timestamp=1715605199
```

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{YOUR_DOMAIN}
```

{% endcode %}

The result will return `false` if a node is fully synced

**Alternatively you can run**

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" https://{YOUR_DOMAIN}
```

and it will return more details about syncing progress

{% hint style="warning" %}
Sync speed will be highly dependent on your Layer 1 RPC
{% endhint %}


# Base Sepolia


# Baremetal

Authors: \[ Ankur | Dapplooker]

## System Requirements

| CPU    | OS           | RAM   | DISK       |
| ------ | ------------ | ----- | ---------- |
| 8 vCPU | Ubuntu 22.04 | 16 GB | 1 TB (SSD) |

{% hint style="success" %}
*The node has a size of 585 GB as of March 14th, 2025.*
{% endhint %}

## Pre-requisite <a href="#pre-requisite" id="pre-requisite"></a>

Before starting, clean the setup then update and upgrade. Install following:

* Git
* Go v1.23+
* rustc
* make
* just
* op-node&#x20;
* op-reth
* jq&#x20;
* Ethereum Sepolia L1 RPC URL
* L1 Consensus Layer Beacon URL

{% hint style="warning" %}

### Before you start, make sure that you have your own synced `Ethereum Sepolia L1 RPC URL` (Ethereum not base ) & `L1 Consensus Layer Beacon endpoint` (e.g. Lighthouse Sepolia) ready. <a href="#before-you-start-make-sure-that-you-have-your-own-synced-ethereum-sepolia-l1-rpc-url-and-l1-consensu" id="before-you-start-make-sure-that-you-have-your-own-synced-ethereum-sepolia-l1-rpc-url-and-l1-consensu"></a>

{% endhint %}

### Installation Command

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install -y git make just wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Install Rustc

```bash
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh # Follow the prompt instruction 
rustc --version #Verifying the installation
```

### Install Op-node

```bash
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism/op-node
just VERSION=v1.12.1 op-node # build op-node
cp ./bin/op-node /usr/bin #Placing op-node binary in /usr/bin
op-node -v #Verify version 
```

{% hint style="warning" %}
Version (v1.12.1) may change in future look for op-node latest version <https://github.com/ethereum-optimism/optimism/releases?q=op-node&expanded=true>&#x20;
{% endhint %}

### Install Op-reth

```bash
git clone https://github.com/paradigmxyz/reth.git
cd reth
make build-op # build op-reth must install/upgrade dependencies
cp ./target/release/op-reth /usr/bin #Placing op-reth binary in /usr/bin
op-reth -V # Verify Version 
```

## Setting up Firewall <a href="#setting-up-firewall" id="setting-up-firewall"></a>

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 8545
sudo ufw allow 5052
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

### Enable Firewall

```bash
sudo ufw enable
```

## Setup Instructions <a href="#setup-instructions" id="setup-instructions"></a>

{% stepper %}
{% step %}

## &#x20;Cloning Base node repository <a href="#id-71fb" id="id-71fb"></a>

```bash
git clone https://github.com/base/node.git
mv node /mnt/base-sepolia
cd base-sepolia
```

{% endstep %}

{% step %}

### Creating op-node service file

```bash
echo "[Unit]
Description=Optimistic Node Client
After=network.target

[Service]
User=root
Environment=HOME="/mnt/base-sepolia"
Environment=OP_GETH_GENESIS_FILE_PATH="/mnt/base-sepolia/node/sepolia/genesis-l2.json"
Environment=OP_GETH_SEQUENCER_HTTP="https://sepolia-sequencer.base.org"
Environment=OP_NODE_L1_ETH_RPC="http://L1_ETH_ENDPOINT_URL"
Environment=OP_NODE_L1_BEACON="http://L1_BEACON_URL"
Environment=OP_NODE_P2P_ADVERTISE_IP=YOUR_PUBLIC_IP_ADDRESS
Environment=OP_NODE_BETA_EXTRA_NETWORKS="true"
Environment=OP_NODE_L2_ENGINE_AUTH="/mnt/base-sepolia/data/engine-auth-jwt"
Environment=OP_NODE_L2_ENGINE_AUTH_RAW="688f5d737bad920bdfb2fc2f488d6b6209eebda1dae949a8de91398d932c517a"
Environment=OP_NODE_L2_ENGINE_RPC="http://localhost:8551"
Environment=OP_NODE_LOG_LEVEL="info"
Environment=OP_NODE_METRICS_ADDR=0.0.0.0
Environment=OP_NODE_METRICS_ENABLED="true"
Environment=OP_NODE_METRICS_PORT=7300
Environment=OP_NODE_NETWORK="base-sepolia"
Environment=OP_NODE_P2P_AGENT="base"
Environment=OP_NODE_P2P_BOOTNODES="enr:-J64QBwRIWAco7lv6jImSOjPU_W266lHXzpAS5YOh7WmgTyBZkgLgOwo_mxKJq3wz2XRbsoBItbv1dCyjIoNq67mFguGAYrTxM42gmlkgnY0gmlwhBLSsHKHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDmoWSi8hcsRpQf2eJsNUx-sqv6fH4btmo2HsAzZFAKnKDdGNwgiQGg3VkcIIkBg,enr:-J64QFa3qMsONLGphfjEkeYyF6Jkil_jCuJmm7_a42ckZeUQGLVzrzstZNb1dgBp1GGx9bzImq5VxJLP-BaptZThGiWGAYrTytOvgmlkgnY0gmlwhGsV-zeHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDahfSECTIS_cXyZ8IyNf4leANlZnrsMEWTkEYxf4GMCmDdGNwgiQGg3VkcIIkBg"
Environment=OP_NODE_P2P_LISTEN_IP=0.0.0.0
Environment=OP_NODE_P2P_LISTEN_TCP_PORT=9222
Environment=OP_NODE_P2P_LISTEN_UDP_PORT=9222
Environment=OP_NODE_RPC_ADDR=0.0.0.0
Environment=OP_NODE_RPC_PORT=8547
Environment=OP_NODE_SNAPSHOT_LOG="/mnt/base-sepolia/data/Environment=op-node-snapshot-log"
Environment=OP_NODE_VERIFIER_L1_CONFS=4
Environment=OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS="true"
Environment=OP_NODE_L1_TRUST_RPC="true"
Environment=OP_NODE_SYNCMODE="execution-layer"
Environment=OP_GETH_BOOTNODES="enode://548f715f3fc388a7c917ba644a2f16270f1ede48a5d88a4d14ea287cc916068363f3092e39936f1a3e7885198bef0e5af951f1d7b1041ce8ba4010917777e71f@18.210.176.114:30301,enode://6f10052847a966a725c9f4adf6716f9141155b99a0fb487fea3f51498f4c2a2cb8d534e680ee678f9447db85b93ff7c74562762c3714783a7233ac448603b25f@107.21.251.55:30301"
Environment=GETH_DATA_DIR="/mnt/base-sepolia/data"
Environment=VERBOSITY=3
Environment=RPC_PORT=8545
Environment=WS_PORT=8546
Environment=AUTHRPC_PORT=8551
Environment=METRICS_PORT=6060
Environment=HOST_IP=0.0.0.0
Environment=P2P_PORT=30304
Environment=OP_GETH_GCMODE="archive"
Environment=OP_GETH_SYNCMODE="full"
Type=simple
ExecStart=/usr/bin/op-node
TimeoutStopSec=90
Restart=on-failure
RestartSec=10s
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=op-node

[Install]
WantedBy=multi-user.target"  > /etc/systemd/system/op-node.service
```

{% hint style="warning" %}
If you don’t know your public IP address `curl http://api.ipify.org`&#x20;

* Replace `http://L1_ETH_ENDPOINT_URL` , `http://L1_BEACON_URL` & `YOUR_PUBLIC_IP_ADDRESS` .
* Create a data directory under project :

{% code fullWidth="false" %}

```bash
mkdir /mnt/base-sepolia/data
```

{% endcode %}

* Create secret file :

```
cd /mnt/base-sepolia/data
openssl rand -hex 32 | tr -d "\n" > "./engine-auth-jwt"
```

{% endhint %}
{% endstep %}

{% step %}

### Creating op-reth service file

```bash
echo "[Unit]
Description=Optimism Go-arbiturum client
After=network.target

[Service]
User=root
Type=simple
ExecStart=/usr/bin/op-reth node \
--datadir=/mnt/base-sepolia/data-reth \
--ws \
--ws.origins="*" \
--ws.addr=0.0.0.0 \
--ws.port=8546 \
--ws.api=debug,eth,net,trace,txpool,web3,rpc,reth,admin \
--http \
--http.corsdomain="*" \
--http.addr=0.0.0.0 \
--http.port=8545 \
--http.api=debug,eth,net,trace,txpool,web3,rpc,reth,admin \
--authrpc.addr=0.0.0.0 \
--authrpc.port=8551 \
--authrpc.jwtsecret=/mnt/base-sepolia/data-reth/engine-auth-jwt \
--metrics=0.0.0.0:6060 \
--chain=base-sepolia \
--rollup.sequencer-http=https://sepolia-sequencer.base.org \
--rollup.disable-tx-pool-gossip

KillMode=process
KillSignal=SIGINT
TimeoutStopSec=90
Restart=on-failure
RestartSec=10s
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-reth.service
```

{% hint style="warning" %}
Create a data directory:

```bash
mkdir -p /mnt/base-sepolia/data-reth
cp /mnt/base-sepolia/data/engine-auth-jwt /mnt/base-sepolia/data-reth/engine-auth-jwt
```

{% endhint %}
{% endstep %}

{% step %}

### Enable Services&#x20;

```bash
systemctl daemon-reload
systemctl enable op-node.service
systemctl enable op-reth.service
```

{% endstep %}

{% step %}

### Start Services

```bash
systemctl start op-node.service
systemctl start op-reth.service
```

{% endstep %}
{% endstepper %}

## Monitoring <a href="#monitor-logs" id="monitor-logs"></a>

{% hint style="warning" %}
The Sync time is \~24 hours ; depending upon L1 RPC, Peers , Disk & Internet speed .
{% endhint %}

* Check is Service file is running and status is <mark style="color:green;">active(running)</mark>

```bash
systemctl status op-node.service
systemctl status op-reth.service
```

* Check op-node service file logs&#x20;

```bash
journalctl -fu op-node.service # Live logs
```

&#x20;  *result*&#x20;

```json
Mar 15 08:08:58 op-node[2644281]: t=2025-03-15T08:08:58+0100 lvl=info msg="Optimistically queueing unsafe L2 execution payload" id=0x90e199e558a43d057755c3b10375098888c71c24e59e0b68752d0e2779cd8637:23127125
Mar 15 08:08:58 op-node[2644281]: t=2025-03-15T08:08:58+0100 lvl=info msg="Inserted new L2 unsafe block (synchronous)" hash=0x90e199e558a43d057755c3b10375098888c71c24e59e0b68752d0e2779cd8637 number=23127125 newpayload_time=46.682ms fcu2_time=422.404µs total_time=47.106ms mgas=20.235851 mgasps=429.57957359986085
Mar 15 08:08:58 op-node[2644281]: t=2025-03-15T08:08:58+0100 lvl=info msg="Sync progress" reason="new chain head block" l2_finalized=0xad05950d632d858da449f885a4d6216af4793521b636adc42e20d8d01344049a:23096311 l2_safe=0xad05950d632d858da449f885a4d6216af4793521b636adc42e20d8d01344049a:23096311 l2_pending_safe=0xad05950d632d858da449f885a4d6216af4793521b636adc42e20d8d01344049a:23096311 l2_unsafe=0x90e199e558a43d057755c3b10375098888c71c24e59e0b68752d0e2779cd8637:23127125 l2_backup_unsafe=0x0000000000000000000000000000000000000000000000000000000000000000:0 l2_time=1742022538
Mar 15 08:08:58 op-node[2644281]: t=2025-03-15T08:08:58+0100 lvl=info msg="successfully processed payload" ref=0x90e199e558a43d057755c3b10375098888c71c24e59e0b68752d0e2779cd8637:23127125 txs=72
```

* Check op-reth service file logs

```bash
journalctl -fu op-reth.service # Live logs
```

*result*

```json
Mar 15 08:08:48 op-reth[2644142]: 2025-03-15T07:08:48.796637Z  INFO Canonical chain committed number=23127120 hash=0xe65860150e39a3f1784e38c9f2eced0913b8697106a910ebfa6bfb5d0c68c0a8 elapsed=131.183µs
Mar 15 08:08:50 op-reth[2644142]: 2025-03-15T07:08:50.465654Z  INFO State root task finished state_root=0x1611ce8389868100d8fec8c4edf019cb7937bd0f2f3b97be628dc76481242f4c elapsed=4.161285ms
Mar 15 08:08:50 op-reth[2644142]: 2025-03-15T07:08:50.465808Z  INFO Block added to canonical chain number=23127121 hash=0x7527aee3323166d9e173d3014b11547e998fd4f7ee96d71cc56ef7ba96f3dfaf peers=60 txs=69 gas=14.87 Mgas gas_throughput=423.14 Mgas/second full=24.8% base_fee=0.01gwei blobs=0 excess_blobs=0 elapsed=35.151491ms
Mar 15 08:08:50 op-reth[2644142]: 2025-03-15T07:08:50.466326Z  INFO Canonical chain committed number=23127121 hash=0x7527aee3323166d9e173d3014b11547e998fd4f7ee96d71cc56ef7ba96f3dfaf elapsed=100.196µs
```

## Sync Status

*Run a query to check the latest synchronized L2 block:*

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber",
"params":[],"id":83}' http://localhost:8545
```

*Response should look like:*

```json
{"jsonrpc":"2.0","id":83,"result":"0x160e561"}
```

## References

{% embed url="<https://sepolia.basescan.org/>" %}


# Docker


# Op-Reth

Authors: \[man4ela | catapulta.eth]

## System Requirements

<table><thead><tr><th align="center">CPU</th><th align="center">OS</th><th width="254" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">8-Core CPU</td><td align="center">Debian 12/Ubuntu 22.04</td><td align="center">=> 16 GB RAM</td><td align="center"><p>1 TB+</p><p> (NVMe)</p></td></tr></tbody></table>

{% hint style="info" %}
*Op-Reth Base Sepolia archive node has a size of 637GB on March 10th, 2025*
{% endhint %}

{% hint style="success" %}
Base is a secure, low-cost Ethereum L2 built on Optimism’s open-source [OP Stack](https://stack.optimism.io/). In this guide, we cover docker installation of `op-reth` and `op-node`to facilitate the node's synchronization on Sepolia Testnet Network. This method has proved to sync an archive node successfully in \~24 hours using the official snapshot provided by the Base team
{% endhint %}

{% hint style="warning" %}

## Before you start, make sure that you have your own synced Ethereum Sepolia L1 RPC URL and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse Sepolia) ready

{% endhint %}

### Pre-Requisites <a href="#pre-requisties" id="pre-requisties"></a>

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
​
sudo apt install -y wget curl screen git ufw
```

### Setting up Firewall <a href="#setting-up-firewall" id="setting-up-firewall"></a>

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Enable Firewall

```bash
sudo ufw enable
```

## Install Docker

#### Run this command to remove any conflicting docker

```bash
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
```

#### Add Docker's official GPG key:

```bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
```

#### Add the repository to ppt sources:

```bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
sudo apt-get update
```

#### Install docker

```bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Test docker is working
sudo docker run hello-world

#Install docker compose

sudo apt-get update
sudo apt-get install docker-compose-plugin

# Test the docker version
docker compose version
```

## Setting up a domain name to access RPC

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://youtu.be/QcNBLSSn8Vg>" %}

**Create Base Sepolia directory**

```bash
mkdir base-sepolia && cd base-sepolia
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

<pre class="language-bash"><code class="lang-bash"><strong>EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
</strong>DOMAIN={YOUR_DOMAIN} #Domain should be something like rpc.mywebsite.com, e.g. base-sepolia.infradao.org
WHITELIST={YOUR_REMOTE_MACHINE_IP} #the server's own IP and comma separated list of IP's allowed to connect to RPC (e.g. Indexer)
LAYER_1_RPC={YOUR_L1_RPC} #Your ready synced L1 Ethereum Sepolia node RPC endpoint
L1_BEACON={YOUR_L1_BEACON} #Your synced L1 CL (Consensus Layer) Beacon endpoint, e.g. Lighthouse (Prysm, Lodestar) Sepolia
</code></pre>

{% hint style="info" %}
`Ctrl + x` and `y` to save file
{% endhint %}

### Create JWT secret file

```bash
mkdir -p /root/data/base-sepolia/op-reth/ && cd /root/data/base-sepolia/op-reth/

openssl rand -hex 32 | tr -d "\n" > "./jwt.hex"
```

### Optional/Recommended: Download Base Snapshot

{% hint style="success" %}
This is an optional step based on whether you want to sync the node from scratch or sync the node from a snapshot. Based on InfraDAO’s experience, we recommend downloading a snapshot and syncing the node from that snapshot. Syncing the node from the scratch will take weeks while the snapshot requires a couple of hours to download, some time to extract, and roughly 24 hours to sync from that point.
{% endhint %}

To sync from a snapshot, visit the Base Docs to validate the recommended approach for restoring from snapshot: <https://docs.base.org/chain/run-a-base-node>.

As downloading a snapshot takes some time it is good idea to run it in a screen session

```
screen -S reth
```

Use `aria2c` to download the most recent **Base Sepolia Reth Archive** Snapshot

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>cd /root/base-sepolia
</strong>
aria2c --file-allocation=none -c -x 15 -s 15 https://sepolia-reth-archive-snapshots.base.org/$(curl https://sepolia-reth-archive-snapshots.base.org/latest)
</code></pre>

*press `ctrl+A and D` to return to previous screen and continue installation*

```bash
screen -r reth #will bring you back to monitor downloading progress
```

You'll need to extract the downloaded snapshot and move its contents to the `op-reth-data` directory, where Docker stores persistent data.

```bash
zstd -d base-sepolia-reth-1741404553.tar.zst -c | tar xvf -
# replace the archive with an actual name
```

{% hint style="warning" %}
If you initially tried to sync the node from scratch and are now trying with a snapshot make sure to empty the destination directory first:
{% endhint %}

<pre class="language-bash"><code class="lang-bash"><strong>cd /var/lib/docker/volumes/reth_op-reth_data/_data 
</strong>
ls 

#if directory isn't empty remove all contents

rm -rf blobstore  db  discovery-secret  invalid_block_hooks  known-peers.json  reth.toml  static_files

mv /root/base-sepolia/snapshots/sepolia/download/* /var/lib/docker/volumes/reth_op-reth_data/_data/

cd /var/lib/docker/volumes/reth_op-reth_data/_data/

ls
</code></pre>

{% hint style="warning" %}
If you haven't started the node yet, create `op-reth-data directory first:`

```bash
docker volume create reth_op-reth_data

cd /var/lib/docker/volumes/reth_op-reth_data/_data

mv /root/base-sepolia/snapshots/sepolia/download/* /var/lib/docker/volumes/reth_op-reth_data/_data/

ls
```

{% endhint %}

### Launch Base Sepolia

```bash
cd /root/base-sepolia

sudo nano docker-compose.yml
```

Paste the following into the `docker-compose.yml:`

```bash
networks:
  monitor-net:
    driver: bridge

volumes:
  op-reth_data: {}
  traefik_letsencrypt: {}

services:

  ######################################################################################
  #####################         TRAEFIK PROXY CONTAINER          #######################
  ######################################################################################

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=${EMAIL}"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=${WHITELIST}"

  ######################################################################################
  #####################            OP-NODE CONTAINER             #######################
  ######################################################################################

  opnode:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.11.1
    container_name: opnode
    user: root  # Run as root
    networks:
      - monitor-net
    restart: unless-stopped
    expose:
      - "7545"  # RPC
      - "7373"  # METRICS
    ports:
      - "9222:9222"      # P2P TCP
      - "9222:9222/udp"  # P2P UDP
    volumes:
      - /root/data/base-sepolia/op-reth/jwt.hex:/root/data/base-sepolia/op-reth/jwt.hex:ro
    environment:
      - OP_GETH_SEQUENCER_HTTP=https://sepolia-sequencer.base.org
      - OP_SEQUENCER_HTTP=https://sepolia-sequencer.base.org
      - OP_NODE_NETWORK=base-sepolia
      - OP_NODE_L1_ETH_RPC=${LAYER_1_RPC}
      - OP_NODE_L1_BEACON=${L1_BEACON}
      - OP_NODE_L2_ENGINE_AUTH=/root/data/base-sepolia/op-reth/jwt.hex
      - OP_NODE_L2_ENGINE_RPC=http://op-reth:8551
      - OP_NODE_LOG_LEVEL=info
      - OP_NODE_METRICS_ADDR=0.0.0.0
      - OP_NODE_METRICS_ENABLED=true
      - OP_NODE_METRICS_PORT=7373
      - OP_NODE_P2P_AGENT=base
      - OP_NODE_P2P_LISTEN_IP=0.0.0.0
      - OP_NODE_P2P_LISTEN_TCP_PORT=9222
      - OP_NODE_P2P_LISTEN_UDP_PORT=9222
      - OP_NODE_ROLLUP_LOAD_PROTOCOL_VERSIONS=true
      - OP_NODE_RPC_ADDR=0.0.0.0
      - OP_NODE_RPC_PORT=7545
      - OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
      - OP_NODE_VERIFIER_L1_CONFS=4
      - OP_NODE_L1_TRUST_RPC=true
      - OP_NODE_P2P_BOOTNODES=enr:-J64QBwRIWAco7lv6jImSOjPU_W266lHXzpAS5YOh7WmgTyBZkgLgOwo_mxKJq3wz2XRbsoBItbv1dCyjIoNq67mFguGAYrTxM42gmlkgnY0gmlwhBLSsHKHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDmoWSi8hcsRpQf2eJsNUx-sqv6fH4btmo2HsAzZFAKnKDdGNwgiQGg3VkcIIkBg,enr:-J64QFa3qMsONLGphfjEkeYyF6Jkil_jCuJmm7_a42ckZeUQGLVzrzstZNb1dgBp1GGx9bzImq5VxJLP-BaptZThGiWGAYrTytOvgmlkgnY0gmlwhGsV-zeHb3BzdGFja4S0lAUAiXNlY3AyNTZrMaEDahfSECTIS_cXyZ8IyNf4leANlZnrsMEWTkEYxf4GMCmDdGNwgiQGg3VkcIIkBg

  ######################################################################################
  #####################            OP-RETH CONTAINER            ######################
  ######################################################################################

  op-reth:
    image: ghcr.io/paradigmxyz/op-reth:v1.1.5
    container_name: op-reth
    user: root  # Run as root
    restart: unless-stopped
    networks:
      - monitor-net
    expose:
      - "8545"  # RPC
      - "8546"  # WebSocket
      - "7300"  # Metrics
      - "8551"  # AuthRPC
    ports:
      - "30303:30303"      # Peers
      - "30303:30303/udp"  # Peers
      - "8551:8551"
    volumes:
      - /root/data/base-sepolia/op-reth/jwt.hex:/root/data/base-sepolia/op-reth/jwt.hex:ro
      - op-reth_data:/data
    command: node --authrpc.jwtsecret=/root/data/base-sepolia/op-reth/jwt.hex --datadir=/data --log.stdout.format log-fmt --ws --ws.origins="*" --ws.addr=0.0.0.0 --ws.port=8546 --ws.api="debug,eth,net,trace,txpool,web3,rpc,reth,admin" --http --http.corsdomain="*" --http.addr=0.0.0.0 --http.port=8545 --http.api="debug,eth,net,trace,txpool,web3,rpc,reth,admin" --authrpc.addr=0.0.0.0 --authrpc.port=8551 --metrics=0.0.0.0:7300 --chain=base-sepolia --rollup.sequencer-http=https://sepolia-sequencer.base.org --rollup.disable-tx-pool-gossip
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.base.service=base"
      - "traefik.http.services.base.loadbalancer.server.port=8545"
      - "traefik.http.routers.base.entrypoints=websecure"
      - "traefik.http.routers.base.tls.certresolver=myresolver"
      - "traefik.http.routers.base.rule=Host(`${DOMAIN}`)"
      - "traefik.http.routers.base.middlewares=ipwhitelist"
```

```bash

docker compose up -d
```

### Monitor Logs

Use `docker logs` to monitor your op-reth and op-node. The `-f` flag ensures you are following the log output

<pre><code>docker logs op-reth -f --tail 100

<strong>docker logs opnode -f --tail 100
</strong></code></pre>

Once your Base node starts syncing, the logs should look like this:

for op-reth:

```bash
ts=2025-03-10T02:53:38.709075686Z level=info target=reth_node_events::node message="Canonical chain committed" number=22903465 hash=0xa134676a4ed89f82eb1ce0ef5cf6fd58b0041e5e5c64e2f54cbc39a2bcfc34bf elapsed=132.57µs
ts=2025-03-10T02:53:40.4913852Z level=info target=reth_node_events::node message="Block added to canonical chain" number=22903466 hash=0x14dad5067b691a304f9b4167834cfd7664ffabf5dc87aef941e2854a60864158 peers=39 txs=77 gas="15.59 Mgas" gas_throughput="312.27 Mgas/second" full=26.0% base_fee=0.00gwei blobs=0 excess_blobs=0 elapsed=49.936088ms
```

for op-node:

```bash
t=2025-03-10T02:52:20+0000 lvl=info msg="Sync progress" reason="new chain head block" 
l2_finalized=0xaefc5cf3494778144b7be0b0f60ec021f62be261fe436408ec444d5beb96f59b:22902892 l2_safe=0x68567e5cbacbb9d765746e6057e15c52b20b403131f8910467cc1566deb10a8d:22903391 l2_pending_safe=0x68567e5cbacbb9d765746e6057e15c52b20b403131f8910467cc1566deb10a8d:22903391 
l2_unsafe=0x676daa0eff1ab38bc20afeae069231b7cb870d3280a89a4a0aa756f05be9a361:22903426 l2_backup_unsafe=0x0000000000000000000000000000000000000000000000000000000000000000:0 l2_time=1741575140
t=2025-03-10T02:52:20+0000 lvl=info msg="successfully processed payload" ref=0x676daa0eff1ab38bc20afeae069231b7cb870d3280a89a4a0aa756f05be9a361:22903426 txs=92
```

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{YOUR_DOMAIN}
```

{% endcode %}

The result will return `false` if a node is fully synced

**Alternatively you can run**

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" https://{YOUR_DOMAIN}
```

and it will return more details about syncing progress

{% hint style="warning" %}
Sync speed will be highly dependent on your Layer 1 RPC
{% endhint %}

### References

{% embed url="<https://docs.base.org/chain/run-a-base-node>" %}


# Berachain


# Reth


# Baremetal

Authors: \[ Godwin]

## System Requirements

<table data-full-width="false"><thead><tr><th>CPU</th><th>OS</th><th>RAM</th><th>DISK</th></tr></thead><tbody><tr><td>8 vCPU</td><td>Ubuntu 22.04</td><td>48 GB</td><td>400+ GB </td></tr></tbody></table>

{% hint style="success" %}
*The Berachain node has a size of  237 GB on 19, May, 2025. Reth: 165 and Beacond: 71GB*
{% endhint %}

## Pre-requisite

{% hint style="info" %}
At the time when this node was set up, Reth v1.3.12 and GO v1.23 were the required version for the Berachain setup.

Check out <https://docs.berachain.com/nodes/evm-execution> to find the version required when setting up the node.
{% endhint %}

### **Commands**

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
```

{% endcode %}

## Firewall Settings

### Check status & enable UFW&#x20;

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong>sudo ufw status verbose
</code></pre>

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP, and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 30303
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9944 
```

## Setup Instructions&#x20;

```bash
mkdir beranode-setup
cd beranode-setup
git clone https://github.com/berachain/guides
mv guides/apps/node-scripts/* ./
rm -r guide
```

Depending on the execution client you intend to use, delete the other client files.&#x20;

For a full list of the clients and versions, go to this page - [EVM Execution Layer ⟠ | Berachain Core Docs](https://docs.berachain.com/nodes/evm-execution)

For this guide, I chose Reth client, so this guide will follow the installation of Reth as the execution layer, as well as Beacond for the consensus layer.

### Install Reth

First, **install Rust** using [rustup](https://rustup.rs/)：&#x20;

`curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`

The rustup installer provides an easy way to update the Rust compiler and works on all platforms.

Install the following dependencies if running on Ubuntu:&#x20;

`apt-get install libclang-dev pkg-config build-essential`

### Build Reth

Berachain node requires reth v1.1.x for mainnet. With Rust and the dependencies installed, you're ready to build Reth. First, clone the repository:

```bash
git clone https://github.com/paradigmxyz/reth
cd reth
git checkout v1.1.5
```

Then, install Reth into your PATH directly via:

`cargo install --locked --path bin/reth --bin reth` The binary will now be accessible as reth via the command line, and exist under your default `.cargo/bin` folder.

Beacond Consensus Layer Note: Beacond requires go version 1.17.x - 1.23.x

### Install go

```bash
sudo wget https://go.dev/dl/go1.23.9.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.9.linux-amd64.tar.gz && rm go1.23.9.linux-amd64.tar.gz

export PATH=$PATH:/usr/local/go/bin
```

### Install Beacond

```bash
git clone https://github.com/berachain/beacon-kit.git
make install

make build
```

Edit Env.sh The file `env.sh` contains environment variables used in the other scripts. `fetch-berachain-params.sh` obtains copies of the genesis file and other configuration files. Then we have `setup-` and `run-` scripts for various execution clients and `beacond.`

```bash
#!/bin/bash

# CHANGE THESE VALUES
export CHAIN_SPEC=mainnet   # or "testnet"
export MONIKER_NAME=anyname
export WALLET_ADDRESS_FEE_RECIPIENT=0x9BcaA41DC32627776b1A4D714Eef627E640b3EF5
export EL_ARCHIVE_NODE=false # set to true if you want to run an archive node on CL and EL
export MY_IP=`curl -s canhazip.com`

# VALUES YOU MIGHT WANT TO CHANGE
export LOG_DIR=$(pwd)/logs
export BEACOND_BIN=/root/beacon-kit/build/bin/beacond
export BEACOND_DATA=$(pwd)/data/beacond
export BEACOND_CONFIG=$BEACOND_DATA/config  # can't change this. sorry.
export JWT_PATH=$BEACOND_CONFIG/jwt.hex

export RETH_BIN=/root/.cargo/bin/reth
#export GETH_BIN=$(command -v geth || echo $(pwd)/geth)
#export NETHERMIND_BIN=$(command -v Nethermind.Runner || echo #$(pwd)/Nethermind.Runner)
#export ERIGON_BIN=$(command -v erigon || echo $(pwd)/erigon)
```

You need to set these constants:

1. **CHAIN\_SPEC**: Set to `testnet` or `mainnet`.
2. **MONIKER\_NAME**: Should be a name of your choice for your node.
3. **WALLET\_ADDRESS\_FEE\_RECIPIENT**: This is the address that will receive the priority fees for blocks sealed by your node. If your node will not be a validator, this won't matter.
4. **EL\_ARCHIVE\_NODE**: Set to `true` if you want the execution client to be a full archive node.
5. **MY\_IP**: This is used to set the IP address that your chain clients advertise to other peers on the network. If you leave it blank, `geth` and `reth` will discover the address with UPnP (if you are behind a NAT gateway) or assign the node's ethernet IP (which is OK if your computer is directly on the internet and has a public IP). In a cloud environment such as AWS or GCP where you are behind a NAT gateway, you **must** specify this address or allow the default `curl canhazip.com` to auto-detect it, if connections to that address lead back to your instance.

You should verify these constants:

* **LOG\_DIR**: This directory stores log files.
* **BEACOND\_BIN**: Set this to the full path where you installed `beacond`. The expression provided finds it in your $PATH.
* **BEACOND\_DATA**: Set this to where the consensus data and config should be kept. BEACOND\_CONFIG must be under BEACOND\_PATH as shown. Don't change it.
* **RETH\_BIN** or other chain client: Set this to the full path where you installed `reth`. The expression provided finds it in your $PATH.

### Fetch Mainnet Parameters

Run

```bash
# FROM: ~/beranode-setup

./fetch-berachain-params.sh;

# [Expected Output for mainnet]: # cd3a642dc78823aea8d80d5239231557 seed-data-80094/eth-genesis.json # c0b7dc21e089f9074d97957526fcd08f seed-data-80094/eth-nether-genesis.json # c66dbea5ee3889e1d0a11f856f1ab9f0 seed-data-80094/genesis.json # 5d0d482758117af8dfc20e1d52c31eef seed-data-80094/kzg-trusted-setup.json
```

### Set up the Consensus Client

The script `setup-beacond.sh` invokes `beacond init` and `beacond jwt generate`.&#x20;

This script:

1. Runs `beacond init` to create the file `var/beacond/config/priv_validator_key.json`. This contains your node's private key, and especially if you intend to become a validator, this file should be kept safe. It cannot be regenerated, and losing it means you will not be able to participate in the consensus process.
2. Runs `beacond jwt generate` to create the file `jwt.hex`. This contains a secret shared between the consensus client and execution client so they can securely communicate. Protect this file. If you suspect it has been leaked, generate a new one with `beacond jwt generate -o $JWT_PATH`.
3. Rewrites the beacond configuration files to reflect settings chosen in `env.sh`.
4. Places the mainnet parameters fetched above where Beacon-Kit expects them, and shows you an important hash from the genesis file.

```bash
# FROM: ~/beranode-setup

./setup-beacond.sh;

# expected output:
BEACOND_DATA: /root/beranode-setup/data/beacond
BEACOND_BIN: /root/beacon-kit/build/bin/beacond
  Version: v1.2.0.rc2-19-g0da575879
✓ Private validator key generated in /root/beranode-setup/data/beacond/config/priv_validator_key.json
✓ JWT secret generated at /root/beranode-setup/data/beacond/config/jwt.hex
✓ Config files in /root/beranode-setup/data/beacond/config updated
0xdf609e3b062842c6425ff716aec2d2092c46455d9b2e1a2c9e32c6ba63ff0bda
✓ Beacon-Kit set up. Confirm genesis root is correct.
```

### Set up the Execution Client [​](https://docs.berachain.com/nodes/quickstart#set-up-the-execution-client-%F0%9F%9B%A0%EF%B8%8F)

The provided scripts `setup-reth`, `setup-geth` and `setup-nether` create a runtime directory and configuration for those respective chain clients. The node is configured with pruning settings according to the `EL_ARCHIVE_NODE` setting in `config.sh`.

Here's an example of `setup-reth`:

```bash
# FROM: ~/beranode-setup

./setup-reth.sh;

# [Expected Output]:
RETH_DATA: /root/beranode-setup/var/reth/data
RETH_BIN: /root/.cargo/bin/reth
  Version: reth Version: 1.1.5
2025-05-09T08:35:56.850901Z  INFO Initialized tracing, debug log directory: /root/.cache/reth/logs/80094
2025-05-09T08:35:56.853494Z  INFO reth init starting
2025-05-09T08:35:56.853891Z  INFO Opening storage db_path="/root/beranode-setup/var/reth/data/db" sf_path="/root/beranode-setup/var/reth/data/static_files"
2025-05-09T08:35:56.861490Z  INFO Verifying storage consistency.
2025-05-09T08:35:59.340630Z  INFO Genesis block written hash=0xd57819422128da1c44339fc7956662378c17e2213e669b427ac91cd11dfcfb38

✓ Reth set up.
```

Your genesis block hash **must** agree with the above

### Run the Client

Setup Services for both beacond and reth

**Beacond service**

```bash
sudo echo "[Unit]
Description=beacond-node
After=network.target

[Service]
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/beranode-setup
ExecStart=/root/beranode-setup/run-beacond.sh

KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
" > /etc/systemd/system/beacond.service
```

**Reth Service**

```bash
sudo echo "[Unit]
Description=reth
After=network.target

[Service]
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/beranode-setup
ExecStart=/root/beranode-setup/run-reth.sh

KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/reth.service
```

Contents of run-reth.sh

This file can be configured based on your needs

```bash
#!/bin/bash

set -e
. ./env.sh

PEERS_OPTION=${EL_PEERS:+--trusted-peers $EL_PEERS}
BOOTNODES_OPTION=${EL_BOOTNODES:+--bootnodes $EL_BOOTNODES}
ARCHIVE_OPTION=$([ "$EL_ARCHIVE_NODE" = true ] && echo "" || echo "--full")
IP_OPTION=${MY_IP:+--nat extip:$MY_IP}

$RETH_BIN node                                  \
        --datadir $RETH_DATA                    \
        --chain $RETH_GENESIS_PATH              \
        $ARCHIVE_OPTION                         \
        $BOOTNODES_OPTION                       \
        $PEERS_OPTION                           \
        $IP_OPTION                              \
        --authrpc.addr 127.0.0.1                \
        --authrpc.port $EL_AUTHRPC_PORT         \
        --authrpc.jwtsecret $JWT_PATH           \
        --port $EL_ETH_PORT                     \
        --metrics $EL_PROMETHEUS_PORT           \
        --http                                  \
        --http.addr 0.0.0.0                     \
        --http.port $EL_ETHRPC_PORT             \
        --http.api web3,debug,eth,txpool,trace,net,reth,rpc  \
        --ws                                    \
        --ws.addr 0.0.0.0                       \
        --ws.port 8546                          \
        --ws.api web3,debug,eth,txpool,trace,net,reth,rpc  \
        --ipcpath /tmp/reth.ipc.$EL_ETHRPC_PORT \
        --discovery.port $EL_ETH_PORT           \
        --http.corsdomain '*'                   \
        --log.file.directory $LOG_DIR           \
        --engine.persistence-threshold 0        \
        --engine.memory-block-buffer-target 0 
```

Contents of run-beacon.sh

```bash
!/bin/bash

set -e
. ./env.sh

$BEACOND_BIN start --home $BEACOND_DATA
```

#### Start the service

```bash
sudo systemctl daemon-reload
sudo systemctl enable beacond.service reth.service
sudo systemctl start beacond.service reth.service
```

### Confirm Node Syncing

```bash
journalctl -xeu beacond.service
journalctl -xeu reth.service
```

beacon

```bash
May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Processed withdrawals service=state-processor num_withdrawals=1 evm_inflation=0
May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Forkchoice updated service=execution-engine head_block_hash=0xb06fb69887d4966c9122a1da3b3211a6ec516f00e11127b3ddf22c2b9c311a8e safe_block_hash=0x8a12334f9fabd>May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Finalized block module=state height=6440 num_txs_res=2 num_val_updates=0 block_app_hash=D353B3D4ED32B3BC614B4BC641690AF3AD78E6C9B9826D0F5F73EF97D8F4EDB0 synci>May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Committed state module=state height=6440 block_app_hash=B368447416331674634AC8BE6D870565C6D3BC4152361EA94B322471E37F9224
```

reth

```bash
May 09 11:31:08 run-reth.sh[1049997]: 2025-05-09T09:31:08.198893Z  INFO Forkchoice updated head_block_hash=0x17cafd43d064ed2e68653dd5099712e836dc815f09e68c768c1a4fe91782a978 safe_block_hash=0x7d5c2d440f097fd2b4b34eece9431d486b69d4>May 09 11:31:08 run-reth.sh[1049997]: 2025-05-09T09:31:08.209230Z  INFO Block added to canonical chain number=7349 hash=0x0133d491f063346adb431d321a52371d3ae9335c6992bd7dcfc6c07da638f7d6 peers=24 txs=0 gas=0.00 Kgas gas_throughput>May 09 11:31:08 run-reth.sh[1049997]: 2025-05-09T09:31:08.210002Z  INFO Canonical chain committed number=7349 hash=0x0133d491f063346adb431d321a52371d3ae9335c6992bd7dcfc6c07da638f7d6 elapsed=4.428µs
May 09 11:31:08 Sufax run-reth.sh[1049997]: 2025-05-09T09:31:08.210014Z  INFO Forkchoice updated head_block_hash=0x0133d491f063346adb431d321a52371d3ae9335c6992bd7dcfc6c07da638f7d6 safe_block_hash=0x17cafd43d064ed2e68653dd5099712e836dc81>May 09 11:31:08 run-reth.sh[1049997]: 2025-05-09T09:31:08.222898Z  INFO Block added to canonical chain number=7350 hash=0xf11199dc86a79d5e09cc2388ebe4ce1a96038a983cf23ff5ccc49e170a11dc4b peers=24 txs=0 gas=0.00 Kgas gas_throughput>May 09 11:31:08 run-reth.sh[1049997]: 2025-05-09T09:31:08.223694Z  INFO Canonical chain committed number=7350 hash=0xf11199dc86a79d5e09cc2388ebe4ce1a96038a983cf23ff5ccc49e170a11dc4b elapsed=6.382µs
```

#### Testing Local RPC Node

**Get current execution block number**

```bash
curl --location 'http://localhost:8545' \ --header 'Content-Type: application/json' \ --data '{ "jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":420 }';
```

Result

```bash
{"jsonrpc":"2.0","id":420,"result":"0x1860b"}
```

**Get Current Consensus Block Number**

```bash
curl -s http://localhost:26657/status | jq '.result.sync_info.latest_block_height'
```

Result

```bash
"99730"
```

{% embed url="<https://docs.berachain.com/nodes/quickstart>" %}


# Erigon


# Baremetal

Authors: \[ Godwin]

## System Requirements

<table data-full-width="false"><thead><tr><th>CPU</th><th>OS</th><th>RAM</th><th>DISK</th></tr></thead><tbody><tr><td>8 vCPU</td><td>Ubuntu 22.04</td><td>48 GB</td><td>400+ GB </td></tr></tbody></table>

{% hint style="success" %}
*The Berachain node has a size of  237 GB on 19, May, 2025. Erigon: 165 and Beacond: 71GB*
{% endhint %}

## Pre-requisite

{% hint style="info" %}
At the time when this node was set up, Erigon v2.61.x and GO v1.23.x were the required version for the Berachain setup.

Check out  <https://docs.berachain.com/nodes/evm-execution> to find the correct required version when setting up the node.
{% endhint %}

### **Commands**

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
```

{% endcode %}

## Firewall Settings

### Check status & enable UFW&#x20;

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong>sudo ufw status verbose
</code></pre>

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP, and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 30303
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9944 
```

## Setup Instructions&#x20;

```bash
mkdir beranode-setup
cd beranode-setup
git clone https://github.com/berachain/guides
mv guides/apps/node-scripts/* ./
rm -r guide
```

Depending on your execution client you intend to use, you delete the other client files. For a full list of the clients and versions go to this page - [EVM Execution Layer ⟠ | Berachain Core Docs](https://docs.berachain.com/nodes/evm-execution)

For this guide, I chose erigon client, so this guide will follow the installation of erigon as the execution layer as well as beacond for the consensus layer.

### Install Erigon

### First Install go

```bash
sudo wget https://go.dev/dl/go1.23.9.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.23.9.linux-amd64.tar.gz && rm go1.23.9.linux-amd64.tar.gz

export PATH=$PATH:/usr/local/go/bin
```

### Build Erigon

Berachain node requires erigon v1.26.x for mainnet. With Rust and the dependencies installed, you're ready to build Erigon. First, clone the repository:

```bash
git clone https://github.com/erigontech/erigon.git
cd erigon/
git checkout v2.61.1
make erigon 
```

Install Beacond Consensus Layer Note: Beacond requires go version 1.17.x - 1.23.x

### Install Beacond

```bash
git clone https://github.com/berachain/beacon-kit.git
make install

make build
```

Edit Env.sh The file `env.sh` contains environment variables used in the other scripts. `fetch-berachain-params.sh` obtains copies of the genesis file and other configuration files. Then we have `setup-` and `run-` scripts for various execution clients and `beacond.`

```bash
#!/bin/bash

# CHANGE THESE VALUES
export CHAIN_SPEC=mainnet   # "mainnet" or "testnet"
export MONIKER_NAME=anyname
export WALLET_ADDRESS_FEE_RECIPIENT=0x9BcaA41DC32627776b1A4D714Eef627E640b3EF5
export EL_ARCHIVE_NODE=true # set to true if you want to run an archive node on CL and EL
export MY_IP=`curl -s ipv4.canhazip.com`

########
# VALUES YOU MIGHT WANT TO CHANGE
export LOG_DIR=/root/erigon-beranode/scripts/logs
export BEACOND_BIN=/root/erigon-beranode/beacon-kit/build/bin/beacond
export BEACOND_DATA=/root/erigon-beranode/scripts/var/beacond
export BEACOND_CONFIG=$BEACOND_DATA/config  # can't change this. sorry.
export JWT_PATH=$BEACOND_CONFIG/jwt.hex

# need at least one of these
#export RETH_BIN=$(command -v reth || echo $(pwd)/reth)
#export GETH_BIN=$(command -v geth || echo $(pwd)/geth)
#export NETHERMIND_BIN=$(command -v Nethermind.Runner || echo $(pwd)/Nethermind.Runner)
export ERIGON_BIN=/root/erigon-beranode/erigon/build/bin/erigon 
```

You need to set these constants:

1. **CHAIN\_SPEC**: Set to `testnet` or `mainnet`.
2. **MONIKER\_NAME**: Should be a name of your choice for your node.
3. **WALLET\_ADDRESS\_FEE\_RECIPIENT**: This is the address that will receive the priority fees for blocks sealed by your node. If your node will not be a validator, this won't matter.
4. **EL\_ARCHIVE\_NODE**: Set to `true` if you want the execution client to be a full archive node.
5. **MY\_IP**: This is used to set the IP address your chain clients advertise to other peers on the network. If you leave it blank, `geth` and `reth` will discover the address with UPnP (if you are behind a NAT gateway) or assign the node's ethernet IP (which is OK if your computer is directly on the internet and has a public IP). In a cloud environment such as AWS or GCP where you are behind a NAT gateway, you **must** specify this address or allow the default `curl canhazip.com` to auto-detect it, if connections to that address lead back to your instance.

You should verify these constants:

* **LOG\_DIR**: This directory stores log files.
* **BEACOND\_BIN**: Set this to the full path where you installed `beacond`. The expression provided finds it in your $PATH.
* **BEACOND\_DATA**: Set this to where the consensus data and config should be kept. BEACOND\_CONFIG must be under BEACOND\_PATH as shown. Don't change it.
* **ERIGON\_BIN** or other chain client: Set this to the full path where you installed `erigon`. The expression provided finds it in your $PATH.

### Fetch Mainnet Parameters

Run

```bash
 # ./fetch-berachain-params.sh 
0038db129d91238c9bff8e495c5fa93f  /root/erigon-beranode/scripts/seed-data-80094/app.toml
8e5601f00d14d3694b4eccc8c101b15b  /root/erigon-beranode/scripts/seed-data-80094/config.toml
5aeab3cb885d8f32892685fc8e44151b  /root/erigon-beranode/scripts/seed-data-80094/el-bootnodes.txt
b00257ebcaa13f02559861696b55c5da  /root/erigon-beranode/scripts/seed-data-80094/el-peers.txt
cd3a642dc78823aea8d80d5239231557  /root/erigon-beranode/scripts/seed-data-80094/eth-genesis.json
c0b7dc21e089f9074d97957526fcd08f  /root/erigon-beranode/scripts/seed-data-80094/eth-nether-genesis.json
c66dbea5ee3889e1d0a11f856f1ab9f0  /root/erigon-beranode/scripts/seed-data-80094/genesis.json
5d0d482758117af8dfc20e1d52c31eef  /root/erigon-beranode/scripts/seed-data-80094/kzg-trusted-setup.json
```

### Set up the Consensus Client

The script `setup-beacond.sh` invokes `beacond init` and `beacond jwt generate`. This script:

1. Runs `beacond init` to create the file `var/beacond/config/priv_validator_key.json`. This contains your node's private key, and especially if you intend to become a validator, this file should be kept safe. It cannot be regenerated, and losing it means you will not be able to participate in the consensus process.
2. Runs `beacond jwt generate` to create the file `jwt.hex`. This contains a secret shared between the consensus client and execution client so they can securely communicate. Protect this file. If you suspect it has been leaked, generate a new one with `beacond jwt generate -o $JWT_PATH`.
3. Rewrites the beacond configuration files to reflect settings chosen in `env.sh`.
4. Places the mainnet parameters fetched above where Beacon-Kit expects them, and shows you an important hash from the genesis file.

```bash
# ./setup-beacond.sh 
BEACOND_DATA: /root/erigon-beranode/scripts/var/beacond
BEACOND_BIN: /root/erigon-beranode/beacon-kit/build/bin/beacond
  Version: v1.2.0.rc2-28-gcbb6cfac3
✓ Private validator key generated in /root/erigon-beranode/scripts/var/beacond/config/priv_validator_key.json
✓ JWT secret generated at /root/erigon-beranode/scripts/var/beacond/config/jwt.hex
✓ Config files in /root/erigon-beranode/scripts/var/beacond/config updated
Genesis validator root: 0xdf609e3b062842c6425ff716aec2d2092c46455d9b2e1a2c9e32c6ba63ff0bda
✓ Beacon-Kit set up. Confirm genesis root is correct.
```

### Set up the Execution Client [​](https://docs.berachain.com/nodes/quickstart#set-up-the-execution-client-%F0%9F%9B%A0%EF%B8%8F)

The provided scripts `setup-reth`, `setup-geth` and `setup-nether` create a runtime directory and configuration for those respective chain clients. The node is configured with pruning settings according to the `EL_ARCHIVE_NODE` setting in `config.sh`.

Here's an example of `setup-erigon`:

```bash
# ./setup-erigon.sh 
ERIGON_DATA: /root/erigon-beranode/scripts/var/erigon
ERIGON_BIN: /root/erigon-beranode/erigon/build/bin/erigon
  Version: erigon version 2.61.1-b3129c00
INFO[05-14|21:51:19.609] logging to file system                   log dir=/root/erigon-beranode/scripts/var/erigon/logs file prefix=erigon log level=info json=false
INFO[05-14|21:51:21.246] Starting Erigon on Ethereum mainnet... 
INFO[05-14|21:51:21.247] Maximum peer count                       ETH=100 total=100
INFO[05-14|21:51:21.247] starting HTTP APIs                       port=8545 APIs=eth,erigon,engine
INFO[05-14|21:51:21.247] Opening Database                         label=chaindata path=/root/erigon-beranode/scripts/var/erigon/chaindata
INFO[05-14|21:51:21.248] [db] open                                label=chaindata sizeLimit=12TB pageSize=8192
INFO[05-14|21:51:21.249] Re-Opening DB in exclusive mode to apply migrations 
INFO[05-14|21:51:21.250] [db] open                                label=chaindata sizeLimit=12TB pageSize=8192
INFO[05-14|21:51:21.251] Apply migration                          name=db_schema_version5
INFO[05-14|21:51:21.251] Applied migration                        name=db_schema_version5
INFO[05-14|21:51:21.251] Apply migration                          name=txs_begin_end
INFO[05-14|21:51:21.251] Applied migration                        name=txs_begin_end
INFO[05-14|21:51:21.251] Apply migration                          name=txs_v3
INFO[05-14|21:51:21.251] Applied migration                        name=txs_v3
INFO[05-14|21:51:21.251] Apply migration                          name=prohibit_new_downloads_lock
INFO[05-14|21:51:21.251] Applied migration                        name=prohibit_new_downloads_lock
INFO[05-14|21:51:21.251] Apply migration                          name=prohibit_new_downloads_lock2
INFO[05-14|21:51:21.251] Applied migration                        name=prohibit_new_downloads_lock2
INFO[05-14|21:51:21.252] Updated DB schema to                     version=6.1.0
INFO[05-14|21:51:21.253] [db] open                                label=chaindata sizeLimit=12TB pageSize=8192
INFO[05-14|21:51:27.874] Writing custom genesis block             hash=0xd57819422128da1c44339fc7956662378c17e2213e669b427ac91cd11dfcfb38
INFO[05-14|21:51:27.981] Successfully wrote genesis state         hash=0xd57819422128da1c44339fc7956662378c17e2213e669b427ac91cd11dfcfb38

✓ Erigon set up.
```

Your genesis block hash **must** agree with the above

### Run the Client

Setup Services for both beacond and erigon

Beacond service

```bash
sudo echo "[Unit]
Description=beacond-node
After=network.target

[Service]
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/erigon-beranode/scripts/
ExecStart=/root/erigon-beranode/scripts/run-beacond.sh

KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
" > /etc/systemd/system/erigon-beacond.service
```

Erigon Service

```bash
sudo echo "[Unit]
Description=erigon
After=network.target

[Service]
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/erigon-beranode/scripts/
ExecStart=/root/erigon-beranode/scripts/run-erigon.sh

KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/erigon.service
```

Contents of run-erigon.sh

This file can be configured based on your needs

```bash
#!/bin/bash

set -e
. ./env.sh

BOOTNODES_OPTION=${EL_BOOTNODES:+--bootnodes $EL_BOOTNODES}
PEERS_OPTION=${EL_PEERS:+--staticpeers $EL_PEERS}
IP_OPTION=${MY_IP:+--nat extip:$MY_IP}

$ERIGON_BIN                                     \
        --datadir $ERIGON_DATA                  \
        $BOOTNODES_OPTION                       \
        $PEERS_OPTION                           \
        $IP_OPTION                              \
        --metrics                               \
        --metrics.addr 0.0.0.0                  \
        --metrics.port $EL_PROMETHEUS_PORT      \
        --http                                  \
        --http.addr 0.0.0.0                     \
        --http.port $EL_ETHRPC_PORT             \
        --http.api eth,erigon,web3,net,debug,trace \
        --http.vhosts "*"                       \
        --http.corsdomain "*"                   \
        --ws                                    \
        --ws.port 8549                          \
        --port $EL_ETH_PORT                     \
        --p2p.allowed-ports 30305,30306 \
        --authrpc.addr 127.0.0.1                \
        --authrpc.port $EL_AUTHRPC_PORT         \
        --authrpc.jwtsecret $JWT_PATH           \
        --authrpc.vhosts localhost
```

Contents of run-beacon.sh

```bash
!/bin/bash

set -e
. ./env.sh

$BEACOND_BIN start --home $BEACOND_DATA
```

#### Start the service

```bash
sudo systemctl daemon-reload
sudo systemctl enable erigon-beacond.service erigon.service
sudo systemctl start erigon-beacond.service erigon.service
```

### Confirm Node Syncing

```bash
journalctl -xeu erigon-beacond.service
journalctl -xeu erigon.service
```

Beacon

```bash
May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Processed withdrawals service=state-processor num_withdrawals=1 evm_inflation=0
May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Forkchoice updated service=execution-engine head_block_hash=0xb06fb69887d4966c9122a1da3b3211a6ec516f00e11127b3ddf22c2b9c311a8e safe_block_hash=0x8a12334f9fabd>May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Finalized block module=state height=6440 num_txs_res=2 num_val_updates=0 block_app_hash=D353B3D4ED32B3BC614B4BC641690AF3AD78E6C9B9826D0F5F73EF97D8F4EDB0 synci>May 09 11:30:45 run-beacond.sh[1047966]: 2025-05-09T11:30:45+02:00 INFO Committed state module=state height=6440 block_app_hash=B368447416331674634AC8BE6D870565C6D3BC4152361EA94B322471E37F9224
```

Erigon

```bash
May 19 15:34:57 Sufax run-erigon.sh[1238087]: [INFO] [05-19|15:34:57.146] [NewPayload] Handling new payload        height=3792435 hash=0x>May 19 15:34:57 Sufax run-erigon.sh[1238087]: [INFO] [05-19|15:34:57.152] [updateForkchoice] Fork choice update: flushing in-memory state>May 19 15:34:57 Sufax run-erigon.sh[1238087]: [INFO] [05-19|15:34:57.153] RPC Daemon notified of new headers       from=3792434 to=379243>May 19 15:34:57 Sufax run-erigon.sh[1238087]: [INFO] [05-19|15:34:57.153] head updated           
```

#### Testing Local RPC Node

**Get the current execution block number**

```bash
curl --location 'http://localhost:8545' \ --header 'Content-Type: application/json' \ --data '{ "jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":420 }';
```

Result

```bash
{"jsonrpc":"2.0","id":420,"result":"0x1860b"}
```

**Get Current Consensus Block Number**

```bash
curl -s http://localhost:26657/status | jq '.result.sync_info.latest_block_height'
```

Result

```bash
"99730"
```

{% embed url="<https://docs.berachain.com/nodes/quickstart>" %}


# Binance


# Erigon


# Baremetal

Authors: \[Payne | Stake🦑Squid]

## System Requirements

<table><thead><tr><th align="center">CPU</th><th width="147" align="center">OS</th><th width="119" align="center">RAM</th><th align="center">Storage</th></tr></thead><tbody><tr><td align="center">8 Cores / 16 Threads</td><td align="center">Ubuntu 22.04</td><td align="center">>= 32GB</td><td align="center">>= 14 TiB NVMe SSD</td></tr></tbody></table>

BNB archive size on June 20th 2024 was 11TB

## Erigon 🦦

Official Docs <https://github.com/node-real/bsc-erigon>

### Snapshots

To download archive snapshots, please use the following: <https://github.com/binance-chain/bsc-snapshots>

### Install go

Download the Go programming language distribution archive, extracts it to the "/usr/local" directory, and then removes the downloaded archive, effectively installing Go version 1.22.4 on the system.

```bash
wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go1.22.4.linux-amd64.tar.gz && \
rm go1.22.4.linux-amd64.tar.gz
```

Please add the Go executable path to your system's `PATH` environment variable, and then test to ensure that Go is working correctly.

```bash
echo "export PATH="$PATH:/root/.foundry/bin:/usr/local/go/bin"" >> /root/.bashrc
source /root/.bashrc
go version #test
```

### Build Erigon

Clone the Erigon repository from GitHub, including its submodules, changes the current directory to the Erigon directory, checks out the latest release tag, and then compile the project using the "make" build system.

```bash
mkdir -p /root/data/github
cd /root/data/github/
git clone --recurse-submodules https://github.com/node-real/bsc-erigon
cd erigon
git checkout <latest release tag>
make
```

### Configure Erigon

Append a systemd service configuration for the Erigon BNB Mainnet Service to the "/etc/systemd/system/erigon.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
[Unit]
Description=Erigon BSC Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/bsc/erigon
ExecStart=/root/data/github/bsc-erigon/build/bin/erigon \
        --datadir=/root/data/bsc/erigon/datadir \
        --chain=bsc \
        --http \
        --http.addr=0.0.0.0 \
        --http.port=9656 \
        --http.compression \
        --http.vhosts=* \
        --http.corsdomain=* \
        --http.api=eth,debug,net,trace,web3,erigon \
        --private.api.addr=0.0.0.0:9092 \
        --ws --ws.compression \
        --metrics --metrics.addr=0.0.0.0 --metrics.port=9696 \
        --rpc.returndata.limit=1000000 \
        --db.pagesize=16kb \
        --db.size.limit=14TB \
        --snapshots=false
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target
```

### Run Erigon

Reload the systemd manager configuration, start the Erigon service, and enable it to start automatically on system boot, ensuring that the Erigon BNB Mainnet Service is active and will be automatically started upon system startup.

```bash
sudo systemctl daemon-reload
sudo systemctl start erigon
sudo systemctl enable erigon
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Erigon service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu erigon
```


# Blast


# Baremetal

Authors: \[man4ela | catapulta.eth]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU          | OS                     | RAM          | DISK                  |
| ------------ | ---------------------- | ------------ | --------------------- |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | 4TB+ (NVME preffered) |

*The Blast archive node has a size of 3.9TB on January 10th, 2025*

## Blast

{% hint style="success" %}
Blast is a fork of Optimism’s open-source [OP Stack](https://stack.optimism.io/). In this guide, Blast forked Optimism's `op-geth` and `op-node`binaries are built from source to facilitate the node's installation.
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) ready.
{% endhint %}

## Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Blast Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Allow P2P Connections

```bash
sudo ufw allow 30304/tcp
sudo ufw allow 30304/udp
```

Enable Firewall

```bash
sudo ufw enable
```

To check the status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Install dependencies

#### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install GO

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && \
sudo rm -rf /usr/local/go && \
sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && \
rm go1.21.6.linux-amd64.tar.gz

# Verify the installation
/usr/local/go/bin/go version
```

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
foundryup

source /root/.bashrc
```

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependencies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

### Create directories

```bash
mkdir -p /root/data/blast/geth/blast-geth
mkdir -p /root/data/blast/geth/blast-optimism
```

## Compile Blast-geth

```bash
git clone https://github.com/blast-io/blast.git

cd blast/blast-geth

git checkout tags/v1.1.0 -b v1.1.0

make
```

*#The binary is built at /root/blast/blast-geth/build/bin/geth*

#### Create JWT secret file and download genesis and rollup .json files

```bash
cd /root/data/blast/geth/blast-geth

openssl rand -hex 32 | tr -d "\n" > /root/data/blast/geth/blast-geth/jwt.hex

cd /root/blast

git clone https://github.com/blast-io/deployment.git #contains genesis and rollup configs
```

### Create systemd service

```bash
sudo echo "[Unit]
Description=Blast-geth Service
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/blast/blast-geth/build/bin/
ExecStart=/root/blast/blast-geth/build/bin/geth \
  --datadir=/root/data/blast/geth/blast-geth/ \
  --http \
  --http.corsdomain=* \
  --http.vhosts=* \
  --http.addr=0.0.0.0 \
  --http.port=8545 \
  --http.api=web3,debug,eth,txpool,net,engine \
  --ws \
  --ws.addr=0.0.0.0 \
  --ws.port=8546 \
  --ws.origins=* \
  --ws.api=debug,eth,txpool,net,engine \
  --authrpc.addr=0.0.0.0 \
  --authrpc.port=8551 \
  --authrpc.vhosts=* \
  --authrpc.jwtsecret=/root/data/blast/geth/blast-geth/jwt.hex \
  --syncmode=full \
  --gcmode=archive \
  --networkid=81457 \
  --nodiscover \
  --maxpeers=0 \
  --rollup.disabletxpoolgossip=true \
  --override.canyon=0 \
  --override.ecotone=1716843599 \
  --rollup.sequencerhttp=https://sequencer.blast.io

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/blast-geth.service

```

Bootstrap the node by running

`/root/blast/blast-geth/build/bin/geth --datadir /root/data/blast/geth/blast-geth/ init /root/blast/deployment/mainnet/genesis.json`

### Start blast-geth

<pre class="language-bash"><code class="lang-bash">sudo systemctl daemon-reload #refresh systemd configuration when changes made
<strong>
</strong>sudo systemctl start blast-geth.service #start blast-geth

sudo systemctl enable blast-geth.service #enable blast-geth service at system startup

sudo journalctl -fu blast-geth.service #follow logs of blast-geth service
</code></pre>

{% hint style="info" %}
To check or modify `blast-geth.service` parameters simply run&#x20;

`sudo nano /etc/systemd/system/blast-geth.service`

Ctrl+X and Y to save changes
{% endhint %}

#### You can run *`curl`* command in the terminal to check the status of your node

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" http://localhost:8545
```

## Compile Op-node (Blast-optimism)

```bash
cd blast/blast-optimism

make op-node
```

#### Create systemd service

{% hint style="warning" %}
Make sure to replace `--l1` and `--l1.beacon` flags with your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse)
{% endhint %}

```bash
echo "[Unit]
Description=Blast-optimism node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/blast/blast-optimism/op-node/bin/
ExecStart=/root/blast/blast-optimism/op-node/bin/op-node \
    --l1={L1 RPC URL} \
    --l1.rpckind=any \
    --l1.beacon={L1 BEACON RPC URL} \
    --l2=http://0.0.0.0:8551 \
    --l2.jwt-secret=/root/data/blast/blast-geth/jwt.hex \
    --rollup.config=/root/blast/deployment/mainnet/rollup.json \
    --p2p.listen.tcp=30304 \
    --p2p.listen.udp=30304 \
    --p2p.bootnodes=enr:-J64QGwHl9uYLfC_cnmxSA6wQH811nkOWJDWjzxqkEUlJoZHWvI66u-BXgVcPCeMUmg0dBpFQAPotFchG67FHJMZ9OSGAY3d6wevgmlkgnY0gmlwhANizeSHb3BzdGFja4Sx_AQAiXNlY3AyNTZrMaECg4pk0cskPAyJ7pOmo9E6RqGBwV-Lex4VS9a3MQvu7PWDdGNwgnZhg3VkcIJ2YQ,enr:-J64QDge2jYBQtcNEpRqmKfci5E5BHAhNBjgv4WSdwH1_wPqbueq2bDj38-TSW8asjy5lJj1Xftui6Or8lnaYFCqCI-GAY3d6wf3gmlkgnY0gmlwhCO2D9yHb3BzdGFja4Sx_AQAiXNlY3AyNTZrMaEDo4aCTq7pCEN8om9U5n_VyWdambGnQhwHNwKc8o-OicaDdGNwgnZhg3VkcIJ2YQ \

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/blast-optimism.service

```

### Start blast-optimism

```bash
sudo nano /etc/systemd/system/blast-optimism.service #make changes in blast-optimism service file

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable blast-optimism.service #enable blast-optimism service at system startup

sudo systemctl start blast-optimism.service #start blast-optimism
```

### Monitor the logs for errors

```bash
sudo journalctl -fu blast-optimism.service #follow logs of blast-optimism service

sudo journalctl -fu blast-geth.service #follow logs of blast-geth service
```

#### Run *`curl`* command in the terminal to check the status of your node

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' \
  -H "Content-Type: application/json" http://localhost:8545
```

{% embed url="<https://github.com/blast-io/deployment>" %}

{% embed url="<https://docs.optimism.io/builders/node-operators/tutorials/node-from-source>" %}

### References


# Boba


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

<table><thead><tr><th width="157" align="center">CPU</th><th align="center">OS</th><th width="166" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">8+ cores CPU</td><td align="center">Debian 12/Ubuntu 22.04</td><td align="center">=> 16 GB RAM</td><td align="center">15GB+ (SSD or NVMe)</td></tr></tbody></table>

{% hint style="info" %}
*The Boba Mainnet archive node has a size of 12GB on July 29, 2024*
{% endhint %}

## Boba

{% hint style="success" %}
Boba is built on the Optimistic Rollup developed by [Optimism](https://optimism.io/).

In this guide, we are walking through the process of setting up a Boba Mainnet archive node using a forked version of Optimism's `op-erigon,` `op-node and l2geth`.  These three components must be configured together to ensure that the node can effectively serve all historical data, which may be necessary when an Indexer syncs a specific subgraph on the Boba Network
{% endhint %}

<figure><img src="/files/PHdO8ebJLJyVbmVCao5a" alt=""><figcaption><p>Node Architecture</p></figcaption></figure>

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint with **`all historical blobs data`** (e.g. Lighthouse) ready.

<mark style="color:orange;">**Hint:**</mark> <https://console.chainstack.com/user/account/create> has a free plan enough to sync a node
{% endhint %}

## Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Blast Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9545 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Install dependencies

#### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install GO

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

#to verify Go installation
go version

#If it returns Command 'go' not found simply run 
echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

#and then apply changes with

source /root/.bashrc
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
foundryup

source /root/.bashrc
```

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

## Build the Rollup Node (op-node)

Clone the Boba Monorepo

```bash
git clone https://github.com/bobanetwork/boba.git

cd boba
```

Check out the required release branch

Release branches are created when new versions of the `op-node` are created. Read through the [Releases page](https://github.com/bobanetwork/boba/tags) to determine the correct branch to check out.

```bash
git checkout v1.6.6
```

### Build op-node

```bash
make op-node
```

#### Create database directory and jwt secret file

```bash
mkdir /root/data/boba

openssl rand -hex 32 | tr -d "\n" > /root/data/boba/jwt.hex
```

### Create systemd service for op-node

```bash
sudo echo "[Unit]
Description=Boba op-node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/boba/op-node/bin/
ExecStart=/root/boba/op-node/bin/op-node \
  --l1={L1 RPC endpoint} \
  --l1.beacon={L1 Beacon RPC endpoint} \
  --l2=http://0.0.0.0:8551 \
  --l2.jwt-secret=/root/data/boba/jwt.hex \
  --network=boba-mainnet \
  --plasma.enabled=false \
  --rpc.addr=0.0.0.0 \
  --rpc.port=8545

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-node.service
```

{% hint style="warning" %}

```
Replace {L1 RPC endpoint} and {L1 Beacon RPC endpoint} with your synced endpoints
```

{% endhint %}

## Build Legacy Geth (l2geth)

#### Clone the Boba Legacy Monorepo and build l2geth:

```bash
cd /root/

git clone https://github.com/bobanetwork/boba_legacy.git

cd boba_legacy

cd l2geth

make geth
```

#### Create database directory for l2geth, download and extract archive snapshot:

```bash
mkdir -p /root/data/boba/boba-legacy/ && cd /root/data/boba/boba-legacy/

aria2c --file-allocation=none -c -x 10 -s 10 "https://boba-db.s3.us-east-2.amazonaws.com/mainnet/boba-mainnet-geth-db-legacy.tgz"

tar -xzvf boba-mainnet-geth-db-legacy.tgz

rm -rf boba-mainnet-geth-db-legacy.tgz

ls #to see the name of extracted archive folder

mv /root/data/boba/boba-legacy/geth-1149018/* /root/data/boba/boba-legacy/

rm -rf geth-1149018
```

#### Create systemd service for l2geth

```bash
sudo nano /etc/systemd/system/boba-legacy.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Boba-legacy GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/boba/boba-legacy/

Environment=CHAIN_ID=288
Environment=NETWORK_ID=288
Environment=NO_USB=true
Environment=NO_DISCOVER=true
Environment=DATADIR=/root/data/boba/boba-legacy/
Environment=GCMODE=archive
Environment=IPC_DISABLE=true
Environment=TARGET_GAS_LIMIT=11000000
Environment=USING_OVM=true
Environment=RPC_ENABLE=true
Environment=RPC_ADDR=0.0.0.0
Environment=RPC_PORT=9546
Environment=RPC_API=eth,net,rollup,web3,debug
Environment=RPC_CORS_DOMAIN=*
Environment=RPC_VHOSTS=*
Environment=WS=false
Environment=WS_ADDR=0.0.0.0
Environment=WS_PORT=9547
Environment=WS_API=eth,net,rollup,web3
Environment=WS_ORIGINS=*
Environment=ROLLUP_BACKEND=l2
Environment=ROLLUP_VERIFIER_ENABLE=true
Environment=ROLLUP_READONLY=true
Environment=BLOCK_SIGNER_KEY=6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27
Environment=BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F
Environment=ROLLUP_ENFORCE_FEES=true
Environment=TURING_CREDIT_ADDRESS=0xF8D2f1b0292C0Eeef80D8F47661A9DaCDB4b23bf
Environment=L2_BOBA_TOKEN_ADDRESS=0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7
Environment=BOBA_GAS_PRICE_ORACLE_ADDRESS=0xeE06ee2F239d2ab11792D77f3C347d919ddA0d51

ExecStart=/root/boba_legacy/l2geth/build/bin/geth \
        --datadir=/root/data/boba/boba-legacy/ \
        --allow-insecure-unlock \
        --mine \
        --miner.etherbase 0x00000398232E2064F896018496b4b44b3D62751F \
        --gcmode=archive \
        --ws=false \
        --nousb \
        --port=30301 \
        --rollup.clienthttp http://127.0.0.1:8545 \
        --rpc \
        --rpcaddr 0.0.0.0 \
        --rpcport 9546 \
        --rpcapi eth,net,rollup,web3,debug,personal \
        --rangelimit \
        --rpc.gascap 501000000

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target

```

## Build the Execution Engine (op-Erigon)

```bash
cd /root/

git clone https://github.com/bobanetwork/op-erigon.git

cd op-erigon
```

Release branches are created when new versions of the `erigon` are created. Read through the [Releases page](https://github.com/bobanetwork/op-erigon/releases) to determine the correct branch to check out.

<pre class="language-bash"><code class="lang-bash"><strong>git checkout v1.1.5
</strong>
make erigon
</code></pre>

#### Create database directory, download and extract the most recent snapshot

{% hint style="success" %}
Consider verifying a snapshot by comparing the sha256sum of the downloaded file to the sha256sum listed on this [page](https://docs.boba.network/developer/node-operators/snapshot-downloads). Check the sha256sum of the downloaded file by running `sha256sum <filename>`in a terminal
{% endhint %}

```bash
mkdir /root/data/boba/op-erigon

cd /root/data/boba/op-erigon

aria2c --file-allocation=none -c -x 10 -s 10 "https://boba-db.s3.us-east-2.amazonaws.com/mainnet/boba-mainnet-erigon-db-1149019.tgz"

tar -xzvf boba-mainnet-erigon-db-1149019.tgz #extract archive

rm -rf boba-mainnet-erigon-db-1149019.tgz #remove archive

mv /root/data/boba/op-erigon/boba-mainnet-erigon-db-1149019/* /root/data/boba/op-erigon/ #Move database files into our database directory path

rm -rf boba-mainnet-erigon-db-1149019 #remove empty folder
```

### Create systemd service for op-erigon

```bash
sudo echo "[Unit]
Description=op-erigon Service
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/op-erigon/build/bin/
ExecStart=/root/op-erigon/build/bin/erigon \
  --datadir=/root/data/boba/op-erigon \
  --private.api.addr=localhost:9090 \
  --metrics \
  --metrics.addr=0.0.0.0 \
  --metrics.port=9700 \
  --http.addr=0.0.0.0 \
  --http.port=9545 \
  --http.corsdomain=* \
  --http.vhosts=* \
  --ws --ws.compression \
  --rpc.returndata.limit 1000000 \
  --authrpc.addr=127.0.0.1 \
  --authrpc.port=8551 \
  --authrpc.vhosts=* \
  --authrpc.jwtsecret=/root/data/boba/jwt.hex \
  --chain=boba-mainnet \
  --http.api=eth,erigon,debug,net,trace,engine,web3 \
  --txpool.gossip.disable=true \
  --rollup.sequencerhttp=https://mainnet.boba.network \
  --rollup.historicalrpc=https://mainnet.boba.network \
  --db.size.limit=8TB
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-erigon.service
```

### Start BOBA

#### Start op-erigon

{% hint style="info" %}
It's usually simpler to begin with starting`op-erigon` before you start `op-node`. You can start `op-erigon` even if `op-node` isn't running yet, but `op-erigon` won't get any blocks until `op-node` starts.
{% endhint %}

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable op-erigon.service #enable op-erigon service at system startup

sudo systemctl start op-erigon.service #start op-erigon

sudo nano /etc/systemd/system/op-erigon.service #make changes in op-erigon.service file
```

#### Start op-node

{% hint style="info" %}
Once you've started `op-erigon`, you can start `op-node`. `op-node` will connect to `op-erigon` and begin synchronizing the BOBA network. `op-node` will begin sending block payloads to `op-erigon` when it derives enough blocks from Ethereum
{% endhint %}

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable op-node.service #enable op-node service at system startup

sudo systemctl start op-node.service #start op-node

sudo nano /etc/systemd/system/op-node.service #make changes in op-node.service file
```

#### Start l2geth

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable boba-legacy.service #enable l2geth service at system startup

sudo systemctl start boba-legacy.service #start l2geth

sudo nano /etc/systemd/system/boba-legacy.service #make changes in boba-legacy.service file
```

### Monitor the logs for errors

```bash
sudo journalctl -fu op-node.service #follow logs of op-node.service

sudo journalctl -fu op-erigon.service #follow logs of op-erigon.service

sudo journalctl -fu boba-legacy.service #follow logs of boba-legacy.service
```

During the initial synchonization, you are expected to get following log messages from `op-node`

```bash
INFO [08-04|16:36:07.150] Advancing bq origin                      origin=df76ff..48987e:8301316 originBehind=false
```

After a few minutes, `op-node` finds the right batch and then it starts synchronizing. During this synchonization process, you get log messags from `op-node`

```bash
INFO [08-04|16:36:01.204] Found next batch                         epoch=44e203..fef9a5:8301309 batch_epoch=8301309                batch_timestamp=1,673,567,518
INFO [08-04|16:36:01.205] generated attributes in payload queue    txs=2  timestamp=1,673,567,518
INFO [08-04|16:36:01.265] inserted block                           hash=ee61ee..256300 number=4,069,725 state_root=a582ae..33a7c5 timestamp=1,673,567,518 parent=5b102e..13196c prev_randao=4758ca..11ff3a fee_recipient=0x4200000000000000000000000000000000000011 txs=2  update_safe=true
```

### Run *`curl`* command in the terminal to check the status of your node

```bash
curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:9545
```

If it returns `false` then your node is fully synchronized with the network

### References

{% embed url="<https://docs.boba.network/developer/node-operators/run-node-source>" %}

{% embed url="<https://github.com/bobanetwork/boba/tree/develop/boba-community>" %}


# Docker

Authors: \[Vikash Choubey | Dapplooker]

### System Requirements

| CPU    | OS        | RAM  | DISK  |
| ------ | --------- | ---- | ----- |
| 8 vCPU | Ubuntu 22 | 16GB | 52GB+ |

&#x20;*The Boba Mainnet archival node has a size of* 52GB *on September 19th, 2024*

## Pre-requisite

Before starting, clean the setup then update and upgrade. Install following:

* Docker & Docker Compose
* Git

### **Commands:**

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

### Set explicit default UFW rules

```
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP and HTTPS

```
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Setup process:

Before starting on root directory, create a direct for boba network with command `mkdir boba-archive`, then `cd boba`.

```bash
mkdir boba
cd boba
```

### Clone boba network

```bash
git clone <https://github.com/bobanetwork/boba.git>
cd boba
cd boba-community
```

### **Create an .env file**

The repository includes a sample environment variable file located at `.env.example` that you can copy and modify to get started. Make a copy of this file and name it `.env`.

```bash
cp .env.example .env
```

### **Configuration**

Download **boba mainnet** snapshot and extract

```bash
curl -o boba-mainnet-erigon-db-1149019.tgz -sL <https://boba-db.s3.us-east-2.amazonaws.com/mainnet/boba-mainnet-erigon-db-1149019.tgz>
tar xvf boba-mainnet-erigon-db-1149019.tgz
```

Download **boba l2Geth** snapshot and extract

```bash
curl -o boba-mainnet-geth-db-114909.tgz -sL https://boba-db.s3.us-east-2.amazonaws.com/mainnet/boba-mainnet-geth-db-114909.tgz
tar xvf boba-mainnet-geth-db-114909.tgz// Some code
```

Create a Shared Secret (JWT Token) using:

```bash
openssl rand -hex 32 > jwt-secret.txt
```

Modify Volume Locations

```yaml
l2:
  volumes:
  - ./jwt-secret.txt:/config/jwt-secret.txt
  - DATA_DIR:/db
op-node:
  volumes:
  - ./jwt-secret.txt:/config/jwt-secret.txt
```

### Example docker-compose file:

```yaml
version: '3.4'

services:
  op-erigon:
    image:  us-docker.pkg.dev/boba-392114/bobanetwork-tools-artifacts/images/op-erigon:v1.1.5
    container_name: op-erigon
    command: |
      --datadir=/db
      --chain=boba-mainnet
      --http.addr=0.0.0.0
      --http.port=9545
      --http.corsdomain=*
      --http.vhosts=*
      --authrpc.addr=0.0.0.0
      --authrpc.port=8551
      --authrpc.vhosts=*
      --authrpc.jwtsecret=/config/jwt-secret.txt
      --http.api=eth,debug,net,engine,web3
      --txpool.gossip.disable=true
      --rollup.sequencerhttp=https://mainnet.boba.network
      --db.size.limit=8TB
      --rollup.historicalrpc=https://mainnet.boba.network
    ports:
      - "9545:9545"
      - "8551:8551"
    user: root
    volumes:
      - /mnt/boba-data/config:/config
      - /mnt/boba-data/boba-mainnet-erigon-db-1149019:/db
  boba-legacy:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:latest
    container_name: boba-legacy
    command: >
      --datadir=/db
      --networkid=288
      --http
      --http.addr=0.0.0.0
      --http.port=9545
      --http.corsdomain=*
      --http.vhosts=*
      --authrpc.addr=0.0.0.0
      --authrpc.port=8551
      --authrpc.vhosts=*
      --authrpc.jwtsecret=/config/jwt-secret.txt
      --rollup.disabletxpoolgossip=true
      --http.api=eth,debug,net,web3
      --nodiscover
      --syncmode=full
      --maxpeers=0
      --rollup.sequencerhttp=https://mainnet.boba.network
    ports:
      - "7545:9545"
      - "7551:8551"
    volumes:
      - /mnt/boba-data/config-l2geth:/config
      - /mnt/boba-data/geth-1149019:/db
  op-node:
    depends_on:
      - op-erigon
    container_name: op-node
    image: us-docker.pkg.dev/boba-392114/bobanetwork-tools-artifacts/images/op-node:v1.6.3
    command: >
      op-node
      --l1=${ETH1_HTTP:-https://mainnet.gateway.tenderly.co}
      --l1.beacon=${ETH2_HTTP}
      --l2=http://l2:8551
      --l2.jwt-secret=/config/jwt-secret.txt
      --network=boba-mainnet
      --rpc.addr=0.0.0.0
      --rpc.port=8545
      --plasma.enabled=false
    ports:
      - "8545:8545"
    volumes:
      - /mnt/boba-data/config:/config
    restart: always
```

### **Start The Node**

`docker-compose -f [docker-compose-file] up -d`

### **Monitor Logs**

Use `docker logs` to monitor your boba node. The `-f` flag ensures you are following the log output

```bash
docker logs op-erigon -f
docker logs op-node -f
docker logs boba-legacy -f
```

### **Test RPC:**

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

You should receive a result, after the node is synced:

```json
{
	"jsonrpc":"2.0",
	"id":1,
	"result":false
}
```


# BobaBNB


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

|      CPU     |           OS           |      RAM     |         DISK         |
| :----------: | :--------------------: | :----------: | :------------------: |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | 550GB+ (SSD or NVMe) |

{% hint style="info" %}
*The BobaBNB archive node has a size of 525GB on August 8th, 2024*
{% endhint %}

## BobaBNB

{% hint style="success" %}
Boba Network is built on the Optimistic Rollup developed by [Optimism](https://optimism.io/), which ensures EVM and Solidity compatibility, minimizing the efforts required to migrate smart contracts from L1 to L2.&#x20;

In this guide, we are walking through the process of setting up a **BobaBNB** archive node using `l2geth and DTL (Data Transport Layer)`.&#x20;

**BobaBNB** is a Layer 2 scaling solution for the Binance Smart Chain (BSC), designed to enhance transaction throughput and reduce fees while maintaining the security of BSC. By deploying a **BobaBNB** archive node, you gain access to the complete transaction history, enabling advanced queries and analytics
{% endhint %}

## Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Blast Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw status verbose
</strong></code></pre>

## Install dependencies

#### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install GO

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

#to verify Go installation
go version

#If it returns Command 'go' not found simply run 
echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

#and then apply changes with

source /root/.bashrc
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
source /root/.bashrc

foundryup
```

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

## Build the Execution Engine (l2geth)

#### Clone the Boba Legacy Monorepo and build l2geth:

```bash
mkdir bobabnb && cd bobabnb

git clone https://github.com/bobanetwork/boba_legacy.git

cd boba_legacy

cd l2geth

make geth
```

#### Create database directories for l2geth and DTL:

```bash
mkdir -p /root/data/bobabnb/geth/dtl

mkdir -p /root/data/bobabnb/geth/l2geth
```

#### Creating password and block-signer key

<pre class="language-bash"><code class="lang-bash">cd /root/data/bobabnb/geth/l2geth/

touch password

<strong>echo "6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27" > /root/data/bobabnb/geth/l2geth/block-signer-key
</strong>
/root/bobabnb/boba_legacy/l2geth/build/bin/geth account import --datadir=/root/data/bobabnb/geth/l2geth/ --password /root/data/bobabnb/geth/l2geth/password /root/data/bobabnb/geth/l2geth/block-signer-key
</code></pre>

#### Create systemd service for l2geth

```bash
sudo nano /etc/systemd/system/l2geth.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=BobaBNB L2 GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/bobabnb/geth/l2geth/
#EnvironmentFile=/root/bobabnb/boba_legacy/packages/data-transport-layer/.env
Environment=DATADIR='/root/data/bobabnb/geth/l2geth/'
Environment=CHAIN_ID=56288
Environment=NETWORK_ID=56288
Environment=NO_DISCOVER=true
Environment=NO_USB=true
Environment=GASPRICE=0
Environment=TARGET_GAS_LIMIT=15000000
Environment=RPC_ADDR=0.0.0.0
Environment=RPC_API="eth,rollup,net,web3,debug"
Environment=RPC_CORS_DOMAIN=*
Environment=RPC_ENABLE=true
Environment=RPC_PORT=8545
Environment=RPC_VHOSTS=*
Environment=NODE_TYPE='archive'
Environment=ROLLUP_TIMESTAMP_REFRESH=5s
Environment=ROLLUP_STATE_DUMP_PATH=http://127.0.0.1:8081/state-dump.latest.json
Environment=ROLLUP_CLIENT_HTTP=http://127.0.0.1:7878
Environment=ROLLUP_BACKEND='l2'
Environment=ROLLUP_VERIFIER_ENABLE='true'
Environment=RETRIES=60
Environment=BLOCK_SIGNER_KEY="6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27"
Environment=BLOCK_SIGNER_ADDRESS="0x00000398232E2064F896018496b4b44b3D62751F"
Environment=ROLLUP_POLL_INTERVAL_FLAG="10s"
Environment=ROLLUP_ENFORCE_FEES='true'
Environment=TURING_CREDIT_ADDRESS="0x4200000000000000000000000000000000000020"
Environment=L2_BOBA_TOKEN_ADDRESS="0x4200000000000000000000000000000000000023"
Environment=BOBA_GAS_PRICE_ORACLE_ADDRESS="0x4200000000000000000000000000000000000024"
Environment=SEQUENCER_CLIENT_HTTP='https://bnb.boba.network/'
Environment=ETH1_HTTP='https://bsc-dataseed.binance.org/'
Environment=ETH1_SYNC_SERVICE_ENABLE=true
Environment=ETHERBASE=0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
Environment=IPC_DISABLE=true
Environment=NO_DISCOVER=true
Environment=TARGET_GAS_LIMIT=11000000
Environment=ROLLUP_ENABLE_L2_GAS_POLLING=true
Environment=ETH1_CONFIRMATION_DEPTH=0
Environment=ETH1_CTC_DEPLOYMENT_HEIGHT=1305672
Environment=USING_OVM=true
ExecStart=/root/bobabnb/boba_legacy/l2geth/build/bin/geth \
        --datadir=/root/data/bobabnb/geth/l2geth/ \
        --password=/root/data/bobabnb/geth/l2geth/password \
        --allow-insecure-unlock \
        --unlock 0x00000398232E2064F896018496b4b44b3D62751F \
        --mine \
        --miner.etherbase 0x00000398232E2064F896018496b4b44b3D62751F \
        --gcmode=archive \
        --port=30301 \
        --ws=false \
        --nousb \
        --rollup.clienthttp http://127.0.0.1:7878 \
        --rpc \
        --rpcaddr 0.0.0.0 \
        --rpcport 8545 \
        --rpcapi eth,net,rollup,web3,debug,personal \
        --rangelimit \
        --rpc.gascap 501000000
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target
```

## Build Data Transport Layer (DTL)

```bash
cd /root/bobabnb/boba_legacy/

yarn

yarn build
```

#### Create systemd service for DTL

```bash
sudo nano /etc/systemd/system/dtl.service
```

Paste DTL configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=BobaBNB DTL Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/bobabnb/boba_legacy/packages/data-transport-layer
ExecStart=/bin/bash -c '. /root/.nvm/nvm.sh && /root/.nvm/versions/node/v18.12.0/bin/node /root/.nvm/versions/node/v18.12.0/bin/yarn start'
#EnvironmentFile=/root/bobabnb/boba_legacy/packages/data-transport-layer/.env
Environment=DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT='https://bsc-dataseed.binance.org/'
Environment=DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT='https://replica.bnb.boba.network'
Environment=DATA_TRANSPORT_LAYER__L2_CHAIN_ID=56288
Environment=DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL=1000
Environment=DATA_TRANSPORT_LAYER__POLLING_INTERVAL=4000
Environment=DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000
Environment=DATA_TRANSPORT_LAYER__ETH1_CTC_DEPLOYMENT_HEIGHT=1305672
Environment=DATA_TRANSPORT_LAYER__ADDRESS_MANAGER='0xeb989B25597259cfa51Bd396cE1d4B085EC4c753'
Environment=DATA_TRANSPORT_LAYER__BSS_HARDFORK_1_INDEX=0
Environment=DATA_TRANSPORT_LAYER__TURING_V0_HEIGHT=0
Environment=DATA_TRANSPORT_LAYER__TURING_V1_HEIGHT=0
Environment=DATA_TRANSPORT_LAYER__DB_PATH="/root/data/bobabnb/geth/dtl"
Environment=DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true
Environment=DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0
Environment=DATA_TRANSPORT_LAYER__SERVER_PORT=7878
Environment=DATA_TRANSPORT_LAYER__SYNC_FROM_L1=false
Environment=DATA_TRANSPORT_LAYER__SYNC_FROM_L2=true
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target
```

#### Create Environment file for DTL:

```bash
sudo nano /root/bobabnb/boba_legacy/packages/data-transport-layer/.env
```

#### Paste the configs and save changes by entering `ctrl+X` and `Y+ENTER`:

```
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT='https://bsc-dataseed.binance.org/'
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT='https://replica.bnb.boba.network'
DATA_TRANSPORT_LAYER__L2_CHAIN_ID=56288
DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL=1000
DATA_TRANSPORT_LAYER__POLLING_INTERVAL=4000
DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000
DATA_TRANSPORT_LAYER__ETH1_CTC_DEPLOYMENT_HEIGHT=1305672
DATA_TRANSPORT_LAYER__ADDRESS_MANAGER='0xeb989B25597259cfa51Bd396cE1d4B085EC4c753'
DATA_TRANSPORT_LAYER__BSS_HARDFORK_1_INDEX=0
DATA_TRANSPORT_LAYER__TURING_V0_HEIGHT=0
DATA_TRANSPORT_LAYER__TURING_V1_HEIGHT=0
DATA_TRANSPORT_LAYER__DB_PATH="/root/data/bobabnb/geth/dtl"
DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true
DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0
DATA_TRANSPORT_LAYER__SERVER_PORT=7878
DATA_TRANSPORT_LAYER__SYNC_FROM_L1=false
DATA_TRANSPORT_LAYER__SYNC_FROM_L2=true
DATADIR='/root/data/bobabnb/geth/l2geth/'
CHAIN_ID=56288
NETWORK_ID=56288
NO_DISCOVER=true
NO_USB=true
GASPRICE=0
TARGET_GAS_LIMIT=15000000
RPC_ADDR=0.0.0.0
RPC_API="eth,rollup,net,web3,debug"
RPC_CORS_DOMAIN=*
RPC_ENABLE=true
RPC_PORT=8545
RPC_VHOSTS=*
NODE_TYPE='archive'
ROLLUP_TIMESTAMP_REFRESH=5s
ROLLUP_STATE_DUMP_PATH=http://127.0.0.1:8081/state-dump.latest.json
ROLLUP_CLIENT_HTTP=http://127.0.0.1:7878
ROLLUP_BACKEND='l2'
ROLLUP_VERIFIER_ENABLE='true'
RETRIES=60
BLOCK_SIGNER_KEY="6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27"
BLOCK_SIGNER_ADDRESS="0x00000398232E2064F896018496b4b44b3D62751F"
ROLLUP_POLL_INTERVAL_FLAG="10s"
ROLLUP_ENFORCE_FEES='true'
TURING_CREDIT_ADDRESS="0x4200000000000000000000000000000000000020"
L2_BOBA_TOKEN_ADDRESS="0x4200000000000000000000000000000000000023"
BOBA_GAS_PRICE_ORACLE_ADDRESS="0x4200000000000000000000000000000000000024"
SEQUENCER_CLIENT_HTTP='https://bnb.boba.network/'
ETH1_HTTP='https://bsc-dataseed.binance.org/'
ETH1_SYNC_SERVICE_ENABLE=true
ETHERBASE=0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
IPC_DISABLE=true
NO_DISCOVER=true
TARGET_GAS_LIMIT=11000000
ROLLUP_ENABLE_L2_GAS_POLLING=true
ETH1_CONFIRMATION_DEPTH=0
ETH1_CTC_DEPLOYMENT_HEIGHT=1305672
USING_OVM=true
```

#### Import genesis information and initialize l2geth

```bash
cd /root/bobabnb/boba_legacy/packages/data-transport-layer

wget https://raw.githubusercontent.com/bobanetwork/boba_legacy/develop/boba_community/boba-node/state-dumps/bobabnb/state-dump.latest.json -O /root/bobabnb/boba_legacy/packages/data-transport-layer/state-dump.latest.json

set -o allexport; source /root/bobabnb/boba_legacy/packages/data-transport-layer/.env; set +o allexport; /root/bobabnb/boba_legacy/l2geth/build/bin/geth init --datadir=/root/data/bobabnb/geth/l2geth /root/bobabnb/boba_legacy/packages/data-transport-layer/state-dump.latest.json --nousb
```

## Launch BobaBNB

#### Start DTL

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable dtl.service #enable dtl service at system startup

sudo systemctl start dtl.service #start dtl

sudo nano /etc/systemd/system/dtl.service #make changes in dtl.service file
```

#### Start l2geth

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable l2geth.service #enable l2geth service at system startup

sudo systemctl start l2geth.service #start l2geth

sudo nano /etc/systemd/system/l2geth.service #make changes in l2geth.service file
```

### Run *`curl`* command in the terminal to check the status of your node

<pre class="language-bash"><code class="lang-bash"><strong>curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545
</strong></code></pre>

When it returns `false` then your node is fully synchronized with the network

### Monitor the logs for errors

```bash
sudo journalctl -fu dtl.service #follow logs of dtl.service

sudo journalctl -fu l2geth.service #follow logs of l2geth.service
```

During the synchonization, you are expected to get following log messages from `DTL`:

```bash
{"level":30,"time":1722479386601,"method":"GET","url":"/transaction/latest?backend=l2","elapsed":0,"msg":"Served HTTP Request"}
{"level":30,"time":1722479393551,"fromBlock":39649105,"toBlock":39649106,"msg":"Synchronizing unconfirmed transactions from Layer 2 (Optimism)"}
```

and `l2geth`:

```bash
INFO [08-01|04:29:56.601] Syncing transaction range                start=39649105 end=39649105 backend=l2
INFO [08-01|04:29:56.609] New block                                index=39649105 l1-timestamp=1722479389 l1-blocknumber=40970591 tx-hash=0x0256f7a95b88f10495ae3a67642009b7ee681c730aac249df16472a90e7be>
INFO [08-01|04:30:07.488] Deep froze chain segment                 blocks=3   elapsed=119.358ms number=39559105 hash=256255…ce8334
```

### References

{% embed url="<https://docs.boba.network/>" %}

{% embed url="<https://github.com/bobanetwork/boba_legacy/blob/develop/boba_community/boba-node/docker-compose-bobabnb.yml>" %}


# Docker

Authors: \[Vikash Choubey | Dapplooker]

### **System Requirements**

| CPU    | OS        | RAM  | DISK   |
| ------ | --------- | ---- | ------ |
| 8 vCPU | Ubuntu 22 | 16GB | 500GB+ |

*The Boba BNB archival node has a size of 508GB on September 19th, 2024*

### Pre-requisite

Before starting, clean the setup then update and upgrade. Install following:

* Docker & Docker Compose
* Git

**Commands:**

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### **Setup**

Clone the `boba_legacy` repository to get started

```bash
git clone git@github.com:bobanetwork/boba_legacy.git
cd boba_community/boba_node
```

#### Setting up Environment Variable

You can locate environment files at `boba_legacy/ops/envs/` folder.

#### **dtl.env**

```bash
DATA_TRANSPORT_LAYER__SYNC_FROM_L1=true
DATA_TRANSPORT_LAYER__SYNC_FROM_L2=false
DATA_TRANSPORT_LAYER__DB_PATH=/db
DATA_TRANSPORT_LAYER__SERVER_PORT=7878
DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL=1000
DATA_TRANSPORT_LAYER__CONFIRMATIONS=0
DATA_TRANSPORT_LAYER__POLLING_INTERVAL=4000
DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000
DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true
DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0

DATA_TRANSPORT_LAYER__ADDRESS_MANAGER=
DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT=
DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT=
DATA_TRANSPORT_LAYER__L2_CHAIN_ID=
```

#### **geth.env**

```bash
ETH1_HTTP=
ETH1_CTC_DEPLOYMENT_HEIGHT=
ETH1_SYNC_SERVICE_ENABLE=true
ETH1_CONFIRMATION_DEPTH=0

ROLLUP_CLIENT_HTTP=
ROLLUP_POLL_INTERVAL_FLAG=4500ms
ROLLUP_ENABLE_L2_GAS_POLLING=true
# ROLLUP_ENFORCE_FEES=

ETHERBASE=0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf

RPC_ENABLE=true
RPC_ADDR=0.0.0.0
RPC_PORT=8545
RPC_API=eth,net,rollup,web3,debug
RPC_CORS_DOMAIN=*
RPC_VHOSTS=*

WS=true
WS_ADDR=0.0.0.0
WS_PORT=8546
WS_API=eth,net,rollup,web3
WS_ORIGINS=*

CHAIN_ID=31338
DATADIR=/root/.ethereum
GASPRICE=0
GCMODE=archive
IPC_DISABLE=true
NETWORK_ID=31338
NO_USB=true
NO_DISCOVER=true
TARGET_GAS_LIMIT=11000000
USING_OVM=true
```

### Example docker-compose file:

```bash
x-l1_rpc_dtl: &l1_rpc_dtl
  DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT: '<https://bsc-dataseed.binance.org/>'

x-l1_rpc_geth: &l1_rpc_geth
  ETH1_HTTP: '<https://bsc-dataseed.binance.org/>'

version: "3.9"

services:
  dtl:
    container_name: dtl
    image: bobanetwork/data-transport-layer:latest
    env_file:
      -  ../../ops/envs/dtl.env
    environment:
      << : *l1_rpc_dtl
      DATA_TRANSPORT_LAYER__L2_RPC_ENDPOINT: '<https://replica.bnb.boba.network>'
      DATA_TRANSPORT_LAYER__SYNC_FROM_L1: 'false'
      DATA_TRANSPORT_LAYER__SYNC_FROM_L2: 'true'
      DATA_TRANSPORT_LAYER__L2_CHAIN_ID: 56288
      DATA_TRANSPORT_LAYER__POLLING_INTERVAL: 10000
      DATA_TRANSPORT_LAYER__ETH1_CTC_DEPLOYMENT_HEIGHT: 1305672
      DATA_TRANSPORT_LAYER__ADDRESS_MANAGER: '0xeb989B25597259cfa51Bd396cE1d4B085EC4c753'
      DATA_TRANSPORT_LAYER__BSS_HARDFORK_1_INDEX: 0
      DATA_TRANSPORT_LAYER__TURING_V0_HEIGHT: 0
      DATA_TRANSPORT_LAYER__TURING_V1_HEIGHT: 0
    volumes:
      - ./state-dumps/bobabnb:/opt/optimism/packages/data-transport-layer/state-dumps/
    logging:
      driver: "json-file"
      options:
        max-file: "5"
        max-size: "10m"
    ports:
      - ${DTL_PORT:-7878}:7878
      - ${REGISTRY_PORT:-8080}:8081

  replica:
    container_name: replica
    depends_on:
      - dtl
    image: bobanetwork/l2geth:latest
    deploy:
      replicas: 1
    entrypoint: sh ./geth.sh
	    env_file:
      - ../../ops/envs/geth.env
    volumes:
      - <DATA_DIR>:/root/.ethereum/
    environment:
      << : *l1_rpc_geth
      ROLLUP_TIMESTAMP_REFRESH: 5s
      ROLLUP_STATE_DUMP_PATH: <http://dtl:8081/state-dump.latest.json>
      ROLLUP_CLIENT_HTTP: <http://dtl:7878>
      ROLLUP_BACKEND: 'l2'
      ROLLUP_VERIFIER_ENABLE: 'true'
      RETRIES: 60
      # no need to keep this secret, only used internally to sign blocks
      BLOCK_SIGNER_KEY: "6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27"
      BLOCK_SIGNER_ADDRESS: "0x00000398232E2064F896018496b4b44b3D62751F"
      ROLLUP_POLL_INTERVAL_FLAG: "10s"
      ROLLUP_ENFORCE_FEES: 'true'
      # turing
      TURING_CREDIT_ADDRESS: "0x4200000000000000000000000000000000000020"
      # fee token
      L2_BOBA_TOKEN_ADDRESS: "0x4200000000000000000000000000000000000023"
      BOBA_GAS_PRICE_ORACLE_ADDRESS: "0x4200000000000000000000000000000000000024"
      # sequencer http endpoint
      SEQUENCER_CLIENT_HTTP: <https://bnb.boba.network/>
      ROLLUP_HISTORICALRPC: <https://bnb.boba.network/>
    logging:
      driver: "json-file"
      options:
        max-file: "5"
        max-size: "10m"
    ports:
      - ${L2GETH_HTTP_PORT:-8549}:8545
      - ${L2GETH_WS_PORT:-8550}:8546

```

### **Start The Node**

```bash
docker-compose -f [docker-compose-file] up -d
```

### **Monitor Logs**

Use `docker logs` to monitor your boba node. The `-f` flag ensures you are following the log output

```bash
docker logs dtl -f
docker logs replica -f
```

### **Test RPC:**

```bash
curl --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' 
-H "Content-Type: application/json" -X POST https://{DOMAIN}
```

#### **You should receive a result after the node is synced:**

```bash
{
	"jsonrpc":"2.0",
	"id":1,
	"result":{HEX_VALUE}
}
```


# Celo


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4c/8t</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 2TB SSD/NVME</td></tr></tbody></table>

## Celo 🟨

Official Docs <https://docs.celo.org/network/mainnet/run-full-node#running-an-archive-node>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Celo directory

The first command, `mkdir celo`, will create a new directory named celo in the current location. The second command, `cd celo`, will change your current working directory to the newly created celo directory. Now you are inside the celo directory and can start storing docker-compose and related files in it.

```bash
mkdir celo
cd celo
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    traefik_letsencrypt: {}
    celo_data: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    expose:
      - "8082:8082" # METRICS
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################            CELO ARCHIVE CONTAINER        #######################
###################################################################################### 

  celo:
    image: us.gcr.io/celo-org/geth:mainnet
    container_name: celo
    restart: unless-stopped
    expose:
      - "8545" # RPC
    ports:
      - 31303:30303 # P2P
      - 31303:30303/udp # P2P
    networks:
      - monitor-net
    command: >
      --datadir=/root/.celo
      --syncmode=full
      --gcmode=archive
      --txlookuplimit=0
      --cache.preimages
      --port=31303
      --http
      --http.addr=0.0.0.0
      --http.vhosts="*"
      --verbosity=3
      --ws
      --ws.addr=0.0.0.0
      --ws.port=8545
      --http.api=eth,net,web3,debug,admin,personal
    volumes:
      - celo_data:/root/.celo
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.erigon.loadbalancer.server.port=8545"
      - "traefik.http.routers.erigon.entrypoints=websecure"
      - "traefik.http.routers.erigon.tls.certresolver=myresolver"
      - "traefik.http.routers.erigon.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.erigon.middlewares=ipwhitelist"
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Celo Node

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

### Monitor Logs

Use `docker logs` to monitor your celo node. The `-f` flag ensures you are following the log output

```
docker logs celo -f
```

## Test Celo RPC 🧪

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

{% endcode %}

{% hint style="warning" %}
You should receive a result. i.e.
{% endhint %}

{% code overflow="wrap" %}

```
{"jsonrpc":"2.0","id":1,"result":{"batchProcessed":308668,"batchSeen":308668,"blockNum":96352870,"broadcasterQueuedMessagesPos":0,"lastL1BlockNum":17885784,"lastl1BlockHash":"0x758b86452273e12b74cdfdc1fb11c373e25589676c09b9b42fd917015fcdeccd","messageOfLastBlock":74145055,"messageOfProcessedBatch":97883962,"msgCount":97884349}}
```

{% endcode %}


# Docker

Authors: \[ Ankur | DappLooker]

## System Requirements

<table data-full-width="false"><thead><tr><th>CPU</th><th>OS</th><th>RAM</th><th>DISK</th></tr></thead><tbody><tr><td>4 - 8 vCPU</td><td>Ubuntu 22.04</td><td>16 GB</td><td>4 TiB SSD (NVME)</td></tr></tbody></table>

{% hint style="success" %}
*The Celo L2 node has a size of  2.2 TiB on 30, June, 2025.*
{% endhint %}

## Pre-requisite

Before starting, clean the setup, then update and upgrade. Install the following:

* Docker

### **Commands**

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io ufw -y jq -y
```

{% endcode %}

## Firewall Settings

### Check status & enable UFW&#x20;

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong>sudo ufw status verbose
</code></pre>

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP, and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9993
```

### Setup Instructions <a href="#setup-instructions" id="setup-instructions"></a>

### <sub>Download Celo-L1 Data</sub>&#x20;

{% hint style="info" %}
You can skip this step if you have already running L1 node&#x20;
{% endhint %}

#### Setup Directory

```bash
mkdir -p /root/celo-data/celo
mkdir -p /root/celo-data/celo-l2
```

#### Download Data

```bash
screen -S nodeConfiguration
wget https://storage.googleapis.com/cel2-rollup-files/celo/celo-mainnet-migrated-chaindata.tar.zst
```

#### Extract File

```bash
tar --zstd -xvf celo-mainnet-migrated-chaindata.tar.zst -C /root/celo-data/celo/ 
```

{% hint style="info" %}
Use ctrl + A + D to go back to your main terminal session.

`screen -r nodeConfiguration` to return to the screen window.
{% endhint %}

### <sub>Migrate L1 Data</sub>&#x20;

```bash
git clone https://github.com/celo-org/celo-l2-node-docker-compose.git
cd celo-l2-node-docker-compose
```

#### Migrate L1 Data to L2 Data&#x20;

{% hint style="info" %}
Run it in background or screen will take few hours to complete.
{% endhint %}

```bash
./migrate.sh pre mainnet /root/celo-data/ /root/celo-data/celo-l2/
```

### <sub>Configure Environment file</sub>

```bash
cd celo-l2-node-docker-compose
cp mainnet.env .env
```

#### Edit .env file&#x20;

Update `.env` file with the following configuration.

```bash
NODE_TYPE=archive
OP_GETH__SYNCMODE=full
HISTORICAL_RPC_DATADIR_PATH=/root/celo-data/
DATADIR_PATH=/root/celo-data/celo-l2/
```

Example `.env` file&#x20;

```
###############################################################################
#                                ↓ REQUIRED ↓                                 #
###############################################################################

# Network to run the node on ("mainnet","alfajores" or "baklava")
NETWORK_NAME=mainnet

# Type of node to run ("full" or "archive"), note that "archive" is 10x bigger
NODE_TYPE=archive

###############################################################################
#                            ↓ REQUIRED (BEDROCK) ↓                           #
###############################################################################

# L1 node that the op-node (Bedrock) will get chain data from.
# To ensure reliability node operators may wish to change this to point at a service they trust.
OP_NODE__RPC_ENDPOINT=https://ethereum-rpc.publicnode.com

# L1 beacon endpoint, you can setup your own or use Quicknode.
# To ensure reliability node operators may wish to change this to point at a service they trust.
OP_NODE__L1_BEACON=https://ethereum-beacon-api.publicnode.com

# Type of RPC that op-node is connected to, see README
OP_NODE__RPC_TYPE=basic

# Reference L2 node to run healthcheck against
HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://forno.celo.org

###############################################################################
#                            ↓ OPTIONAL (BEDROCK) ↓                           #
###############################################################################

# Optional path to a datadir for an L1 node to serve RPC requests requiring historical states. If
# set a Celo L1 node will be run in archive mode to serve requests requiring state for blocks prior to the
# L2 hardfork and op-geth will be configured to proxy those requests to the Celo L1 node.
HISTORICAL_RPC_DATADIR_PATH=/root/celo-data/

# Optional provider to serve RPC requests requiring historical state, if set op-geth will proxy
# requests requiring state prior to the L2 start to here. If set this overrides the use of a local Celo L1
# node via HISTORICAL_RPC_DATADIR_PATH.
OP_GETH__HISTORICAL_RPC=

# Set to "full" to force op-geth to use --syncmode=full
OP_GETH__SYNCMODE=full

IS_CUSTOM_CHAIN=true

# Path to the datadir, If the datadir is empty then a new datadir will be
# initialised at the given path.
#
# The path can be absolute, or relative to the docker-compose.yml file.
DATADIR_PATH=/root/celo-data/celo-l2/

# If the datadir is on a disk that doesn't support unix domain sockets then you
# will need to specify a path to a disk that does support unix domain sockets.
# E.g. your normal hard drive. If left unset the default path inside the
# datadir will be used.
IPC_PATH=

# Controls how op-geth determines its public IP that is shared via the
# discovery mechanism. The value should be one of
# (any|none|upnp|pmp|pmp:<IP>|extip:<IP>|stun:<IP:PORT>) if any is selected
# op-geth will try to automatically determine its external IP. To explicitly
# set the IP that op-geth can be reached on use extip:<your-external-ip>. To
# check the value that op-geth is currently using look in the op-geth logs for
# an entry such as
# self=enode://b24c34e53adc6db27fe648615eca3b9062a58295242caeea1604690507d507d0138ddeecb3cc9805a1cbd441471790c66a6f886f0538c3cde3e0b5dbd145f1f1@127.0.0.1:30303
# alternatively you can use the admin_nodeInfo RPC to query this information.
# If unset other nodes will not be then other nodes on the network will not be
# able to discover and connect to your node.
OP_GETH__NAT=any

# This controls the IP that op-node shares with the network so that other nodes may discover and connect to it.
# To check the value that op-node is currently using you can look in the logs for an entry such as:
# msg="started p2p host" addrs="[/ip4/127.0.0.1/tcp/9222 /ip4/192.168.97.9/tcp/9222]" peerID=16Uiu2HAkv7PQ5hpa2HeWgjYQ7SChvipCWm3L95hUKejSKMM4rVPe
# alternatively you can use the op-node opp2p_self RPC to query this
# information. If unset other nodes will not be then other nodes on the network
# will not be able to discover and connect to your node.
OP_NODE__P2P_ADVERTISE_IP=

###############################################################################
#                            ↓ REQUIRED (EIGENDA) ↓                           #
###############################################################################

# Specifies the endpoint of the eigenda proxy to use. If this is unset then a local eigenda proxy will be used.
EIGENDA_PROXY_ENDPOINT=

EIGENDA_LOCAL_SVC_MANAGER_ADDR=0x870679e138bcdf293b7ff14dd44b70fc97e12fc0
EIGENDA_LOCAL_DISPERSER_RPC=disperser.eigenda.xyz:443
EIGENDA_LOCAL_SIGNER_PRIVATE_KEY_HEX=
EIGENDA_V2_LOCAL_SVC_MANAGER_ADDR=0x870679e138bcdf293b7ff14dd44b70fc97e12fc0
EIGENDA_V2_LOCAL_DISPERSER_RPC=disperser.eigenda.xyz:443
EIGENDA_V2_LOCAL_SIGNER_PAYMENT_KEY_HEX=
EIGENDA_V2_LOCAL_CERT_VERIFIER_ADDR=0xE1Ae45810A738F13e70Ac8966354d7D0feCF7BD6
EIGENDA_V2_LOCAL_BLS_OPERATOR_STATE_RETRIEVER_ADDR=0xEC35aa6521d23479318104E10B4aA216DBBE63Ce


###############################################################################
#                            ↓ OPTIONAL (EIGENDA) ↓                           #
###############################################################################

EIGENDA_LOCAL_S3_CREDENTIAL_TYPE="public"
EIGENDA_LOCAL_S3_ACCESS_KEY_ID=""
EIGENDA_LOCAL_S3_ACCESS_KEY_SECRET=""
EIGENDA_LOCAL_S3_BUCKET="eigenda-proxy-cache-mainnet"
EIGENDA_LOCAL_S3_PATH="blobs/"
EIGENDA_LOCAL_S3_ENDPOINT="storage.googleapis.com"
EIGENDA_LOCAL_ARCHIVE_BLOBS=${EIGENDA_LOCAL_S3_BUCKET:+0}

###############################################################################
#                                ↓ OPTIONAL ↓                                 #
###############################################################################

# MONITORING_ENABLED controls whether Grafana, Prometheus, Influxdb, and Healthcheck are started
# Set to "true" if you want to launch them, otherwise keep "false"
MONITORING_ENABLED=false

IMAGE_TAG__HEALTCHECK=
IMAGE_TAG__PROMETHEUS=
IMAGE_TAG__GRAFANA=
IMAGE_TAG__INFLUXDB=
IMAGE_TAG__OP_GETH=
IMAGE_TAG__OP_NODE=

# Exposed server ports (must be unique)
# See docker-compose.yml for default values
PORT__HISTORICAL_RPC_NODE_HTTP=
PORT__HISTORICAL_RPC_NODE_WS=
PORT__HEALTHCHECK_METRICS=
PORT__PROMETHEUS=
PORT__GRAFANA=
PORT__INFLUXDB=
PORT__TORRENT_UI=
PORT__TORRENT=
PORT__OP_GETH_HTTP=
PORT__OP_GETH_WS=
PORT__OP_GETH_P2P=30303
PORT__OP_NODE_P2P=
PORT__OP_NODE_HTTP=
PORT_EIGENDA_PROXY=
```

#### Example `docker-compose.yml` file

```yaml
services:
  historical-rpc-node:
    image: us-docker.pkg.dev/celo-org/us.gcr.io/geth-all:1.8.9
    restart: on-failure
    stop_grace_period: 5m
    entrypoint: /scripts/start-historical-rpc-node.sh
    env_file:
      - ./envs/common/historical-rpc-node.env
      - .env
    volumes:
      - ${HISTORICAL_RPC_DATADIR_PATH:-geth}:/geth
      - ./scripts/:/scripts/
    ports:
      - ${PORT__HISTORICAL_RPC_NODE_HTTP:-9991}:8545
      - ${PORT__HISTORICAL_RPC_NODE_WS:-9992}:8546

  healthcheck:
    platform: linux/amd64
    image: ethereumoptimism/replica-healthcheck:${IMAGE_TAG__HEALTHCHECK:-latest}
    restart: on-failure
    entrypoint: /opt/optimism/packages/replica-healthcheck/start-healthcheck.sh
    env_file:
      - ./envs/common/healthcheck.env
      - .env
    volumes:
      - ./scripts/start-healthcheck.sh:/opt/optimism/packages/replica-healthcheck/start-healthcheck.sh
    ports:
      - ${PORT__HEALTHCHECK_METRICS:-7300}:7300

  eigenda-proxy:
    platform: linux/amd64
    image: ghcr.io/layr-labs/eigenda-proxy:v1.8.2
    restart: on-failure
    stop_grace_period: 5m
    entrypoint: /scripts/start-eigenda-proxy.sh
    env_file:
      - .env
    volumes:
      - eigenda-data:/data
      - ./scripts/:/scripts
    ports:
      - ${PORT_EIGENDA_PROXY:-4242}:4242
    extra_hosts:
      - "host.docker.internal:host-gateway"

  op-geth:
    platform: linux/amd64
    image: us-west1-docker.pkg.dev/devopsre/celo-blockchain-public/op-geth:celo-v2.1.0-rc2
    restart: on-failure
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-geth.sh
    env_file:
      - ./envs/${NETWORK_NAME}/op-geth.env
      - .env
    volumes:
      - ./envs/${NETWORK_NAME}/config:/chainconfig
      - ./scripts/:/scripts
      - shared:/shared
      - ${DATADIR_PATH}:/geth
    ports:
      - ${PORT__OP_GETH_HTTP:-9993}:8545
      - ${PORT__OP_GETH_WS:-9994}:8546
      - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/udp
      - ${PORT__OP_GETH_P2P:-39393}:${PORT__OP_GETH_P2P:-39393}/tcp
    extra_hosts:
      - "host.docker.internal:host-gateway"

  op-node:
    platform: linux/amd64
    image: us-west1-docker.pkg.dev/devopsre/celo-blockchain-public/op-node:celo-v2.1.0-rc
    restart: on-failure
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-node.sh
    env_file:
      - ./envs/${NETWORK_NAME}/op-node.env
      - .env
    volumes:
      - ./envs/${NETWORK_NAME}/config:/chainconfig
      - ./scripts/:/scripts
      - shared:/shared
    ports:
      - ${PORT__OP_NODE_P2P:-9222}:9222/udp
      - ${PORT__OP_NODE_P2P:-9222}:9222/tcp
      - ${PORT__OP_NODE_HTTP:-9545}:9545
    extra_hosts:
      - "host.docker.internal:host-gateway"
    depends_on:
      op-geth:
        condition: service_started

  prometheus:
    platform: linux/amd64
    image: prom/prometheus:${IMAGE_TAG__PROMETHEUS:-latest}
    restart: on-failure
    entrypoint: /scripts/start-prometheus.sh
    env_file:
      - .env
    volumes:
      - ./docker/prometheus:/etc/prometheus
      - prometheus_data:/prometheus
      - ./scripts/start-prometheus.sh:/scripts/start-prometheus.sh
    ports:
      - ${PORT__PROMETHEUS:-9090}:9090

  grafana:
    platform: linux/amd64
    image: grafana/grafana:${IMAGE_TAG__GRAFANA:-9.3.0}
    restart: on-failure
    entrypoint: /scripts/start-grafana.sh
    env_file:
      - ./envs/common/grafana.env
      - .env
    volumes:
      - ./docker/grafana/provisioning/:/etc/grafana/provisioning/:ro
      - ./docker/grafana/dashboards/simple_node_dashboard.json:/var/lib/grafana/dashboards/simple_node_dashboard.json
      - grafana_data:/var/lib/grafana
      - ./scripts/start-grafana.sh:/scripts/start-grafana.sh
    ports:
      - ${PORT__GRAFANA:-3000}:3000

  influxdb:
    platform: linux/amd64
    image: influxdb:${IMAGE_TAG__INFLUXDB:-1.8}
    restart: on-failure
    entrypoint: /scripts/start-influxdb.sh
    env_file:
      - ./envs/common/influxdb.env
      - .env
    volumes:
      - ./docker/influxdb/influx_init.iql:/docker-entrypoint-initdb.d/influx_init.iql
      - influxdb_data:/var/lib/influxdb
      - ./scripts/start-influxdb.sh:/scripts/start-influxdb.sh
    ports:
      - ${PORT__INFLUXDB:-8086}:8086

volumes:
  geth:
  eigenda-data:
  prometheus_data:
  grafana_data:
  influxdb_data:
  shared:
```

### <sub>Start the Node</sub>

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

## Monitoring

### Monitor Logs of Docker Container&#x20;

```bash
docker ps 
docker compose logs

# for Individual Containers Logs 
docker logs celo-l2-node-docker-compose-op-geth-1 
docker logs celo-l2-node-docker-compose-op-node-1
docker logs celo-l2-node-docker-compose-historical-rpc-node-1
docker logs celo-l2-node-docker-compose-eigenda-proxy-1
```

{% hint style="warning" %}
Total time required to sync is \~3 Days.
{% endhint %}

## Sync Status

### Latest Block

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:9993
```

*Response should look like:*

```json
{"jsonrpc":"2.0","id":1,"result":"0x258fee5"}
```

## References

{% embed url="<https://docs.celo.org/cel2/operators/run-node#running-an-archive-node>" %}

{% embed url="<https://celoscan.io/>" %}


# Baremetal

Authors: Godwin

## System Requirements

|    CPU    |           OS           |  RAM  |    DISK    |
| :-------: | :--------------------: | :---: | :--------: |
| 4-8 Cores | Debian 12/Ubuntu 22.04 | 16 GB | 4TB+ (SSD) |

{% hint style="info" %}
*The celo l2 node has a size of 2.1TB on June 24, 2025*
{% endhint %}

### Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
sudo ufw allow 8546
sudo ufw allow 8547
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

### Download pre-migrated L1 data and run the migration script

The script below uses screen to create a session called archive, and download the Celo L1 data.

```bash
screen -S archive 
aria2c --file-allocation=none -c -x 10 -s 10 https://storage.googleapis.com/cel2-rollup-files/celo/celo-mainnet-migrated-chaindata.tar.zst

# you can use ctrl + A + D to go back to your main terminal session
# screen -r archive to return to the screen window.
```

Once the data has been download, you need to extract the data into a directory of your chosen.

```bash
mkdir -p /opt/celo-l1
mkdir -p /opt/celo
mkdir -p /opt/celo-migrated-l2/

tar --zstd -xvf celo-mainnet-migrated-chaindata.tar.zst -C /opt/celo-l1/

cd /opt/

# the l2 migration script attachs the directory /celo/chaindata to the source-dir argument. 
mv /opt/celo-l1/chaindata/ /opt/celo/

cd
```

Clone the celo l2 docker setup and perform the migration

```bash
git clone git@github.com:celo-org/celo-l2-node-docker-compose.git
cd celo-l2-node-docker-compose


chmod +x migrate.sh

./migrate.sh pre mainnet /opt/ /opt/celo-migrated-l2/
```

This will perform a migration of the L1 data to the Celo L2.

### Set up Celo L2 Archive Node

#### Install go

Download the Go programming language distribution archive, extracts it to the "/usr/local" directory, and then removes the downloaded archive, effectively installing Go version 1.23.5 on the system.

```bash
wget https://go.dev/dl/go1.24.4.linux-amd64.tar.gz
ls /usr/local/
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.24.4.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
```

#### Build Celo L2 OP-GETH

```bash
git clone https://github.com/celo-org/op-geth.git
cd op-geth/
make geth
sudo cp ./build/bin/geth /usr/local/bin/cl2-geth
sudo chmod +x /usr/local/bin/cl2-geth

/usr/local/bin/cl2-geth version
```

### Build Celo L2 OP-NODE

Install just

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
$HOME/.cargo/env
source $HOME/.cargo/env
cargo install just
```

```bash
git clone https://github.com/celo-org/optimism.git
cd optimism/
make build

sudo cp ./op-node/bin/op-node /usr/local/bin/op-node

op-node --version
```

Create JWT Secret

```bash
cd /opt/
mkdir chainconfig
cd chainconfig/
wget https://storage.googleapis.com/cel2-rollup-files/celo/rollup.json
sudo openssl rand -hex 32 > jwt.hex
```

### Create OP-GETH Service

```
sudo nano /etc/systemd/system/celol2-op-geth.service
```

<pre class="language-bash"><code class="lang-bash">[Unit]
Description=Celo L2 op-geth
After=network.target
Wants=network.target

[Service]
Type=exec
User=root
ExecStart=/usr/local/bin/cl2-geth \
    --datadir=/opt/celo-migrated-l2/ \
    --http \
    --http.addr=0.0.0.0 \
    --http.vhosts="*" \
    --http.port=8545 \
    --http.api=eth,net,web3,debug,admin,txpool,engine \
    --ws \
    --ws.addr=0.0.0.0 \
    --ws.port=8546 \
    --ws.api=eth,net,web3,debug,admin,txpool,engine \
    --syncmode=full \
    --gcmode=archive \
    --port=30303 \
    --discovery.port=30303 \
    --authrpc.jwtsecret=/opt/celo/chainconfig/jwt.txt \
    --authrpc.addr=0.0.0.0 \
    --authrpc.port=8551 \
    --authrpc.vhosts="*" \
    --metrics \
    --metrics.addr=0.0.0.0 \
    --metrics.port=6060 \
    --rollup.sequencerhttp="https://cel2-sequencer.celo.org" \
    --rollup.disabletxpoolgossip=true \
    --nat=any \
    --snapshot=true \
    --verbosity=3 \
    --history.transactions=0 \
    --bootnodes=enode://28f4fcb7f38c1b012087f7aef25dcb0a1257ccf1cdc4caa88584dc25416129069b514908c8cead5d0105cb0041dd65cd4ee185ae0d379a586fb07b1447e9de38@34.169.39.223:30303,enode://a9077c3e030206954c5c7f22cc16a32cb5013112aa8985e3575fadda7884a508384e1e63c077b7d9fcb4a15c716465d8585567f047c564ada2e823145591e444@34.169.212.31:30303,enode://029b007a7a56acbaa8ea50ec62cda279484bf3843fae1646f690566f784aca50e7d732a9a0530f0541e5ed82ba9bf2a4e21b9021559c5b8b527b91c9c7a38579@34.82.139.199:30303,enode://f3c96b73a5772c5efb48d5a33bf193e58080d826ba7f03e9d5bdef20c0634a4f83475add92ab6313b7a24aa4f729689efb36f5093e5d527bb25e823f8a377224@34.82.84.247:30303,enode://daa5ad65d16bcb0967cf478d9f20544bf1b6de617634e452dff7b947279f41f408b548261d62483f2034d237f61cbcf92a83fc992dbae884156f28ce68533205@34.168.45.168:30303,enode://c79d596d77268387e599695d23e941c14c220745052ea6642a71ef7df31a13874cb7f2ce2ecf5a8a458cfc9b5d9219ce3e8bc6e5c279656177579605a5533c4f@35.247.32.229:30303,enode://4151336075dd08eb6c75bfd63855e8a4bd6fd0f91ae4a81b14930f2671e16aee55495c139380c16e1094a49691875e69e40a3a5e2b4960c7859e7eb5745f9387@35.205.149.224:30303,enode://ab999db751265c714b171344de1972ed74348162de465a0444f56e50b8cfd048725b213ba1fe48c15e3dfb0638e685ea9a21b8447a54eb2962c6768f43018e5c@34.79.3.199:30303,enode://9d86d92fb38a429330546fe1aefce264e1f55c5d40249b63153e7df744005fa3c1e2da295e307041fd30ab1c618715f362c932c28715bc20bed7ae4fc76dea81@34.77.144.164:30303,enode://c82c31f21dd5bbb8dc35686ff67a4353382b4017c9ec7660a383ccb5b8e3b04c6d7aefe71203e550382f6f892795728570f8190afd885efcb7b78fa398608699@34.76.202.74:30303,enode://3bad5f57ad8de6541f02e36d806b87e7e9ca6d533c956e89a56b3054ae85d608784f2cd948dc685f7d6bbd5a2f6dd1a23cc03e529ea370dd72d880864a2af6a3@104.199.93.87:30303,enode://1decf3b8b9a0d0b8332d15218f3bf0ceb9606b0efe18f352c51effc14bbf1f4f3f46711e1d460230cb361302ceaad2be48b5b187ad946e50d729b34e463268d2@35.240.26.148:30303


Restart=always
RestartSec=10
StandardOutput=journal
<strong>StandardError=journal
</strong>SyslogIdentifier=celo-op-geth

# Resource limits
LimitNOFILE=65536


[Install]
WantedBy=multi-user.target
</code></pre>

### Create OP-NODE Service

```bash
sudo nano /etc/systemd/system/celol2-op-node.service
```

```bash
[Unit]
Description=Celo L2 op-node
After=network.target

[Service]
Type=exec
User=root
ExecStart=/usr/local/bin/op-node \
    --l1=https://ethereum-rpc.publicnode.com \
    --l2=http://localhost:8551 \
    --rpc.addr=0.0.0.0 \
    --rpc.port=9545 \
    --l2.jwt-secret=/opt/celo/chainconfig/jwt.txt \
    --l1.trustrpc \
    --l1.rpckind=basic \
    --l1.beacon=https://ethereum-beacon-api.publicnode.com \
    --metrics.enabled \
    --metrics.addr=0.0.0.0 \
    --metrics.port=7300 \
    --syncmode=execution-layer \
    --rollup.config=/opt/celo/chainconfig/rollup.json \
    --p2p.bootnodes=enr:-J64QJipvmFhMq6DVh6RR4HvIiiBtyy1NUg_QlnAAbf18SMqCxCPZtLgUiWED5p0HRVPv69Wth4YPsvdKXSUyh57mWuGAZXRp6HjgmlkgnY0gmlwhCJTtG-Hb3BzdGFja4TsyQIAiXNlY3AyNTZrMaECKPT8t_OMGwEgh_eu8l3LChJXzPHNxMqohYTcJUFhKQaDdGNwgiQGg3VkcIIkBg,enr:-J64QCxBGS49IQbkbwsUuVWt9CkMctMCRe0b-4dqRsLr4QJ1S52urWPUk2uhBU5uerRGpxWTZZW5FtJC-9gSBHN3cSiGAZXRp4rbgmlkgnY0gmlwhCKph0CHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaECqQd8PgMCBpVMXH8izBajLLUBMRKqiYXjV1-t2niEpQiDdGNwgiQGg3VkcIIkBg,enr:-J64QLG71bmmljNbLFx3qim6zXohKA3jbK_4C4d1cwixI-7VMoBIlnM6kWZVvvdWcbjTQ6QXB1LAO39eZWC4Heztj1-GAZXRpzUGgmlkgnY0gmlwhCKpySSHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDApsAenpWrLqo6lDsYs2ieUhL84Q_rhZG9pBWb3hKylCDdGNwgiQGg3VkcIIkBg,enr:-J64QKFU-u1x1gt3WmNP88EDUMQ316ymbzdGy83QjkBDqVSsJBn6-nipuqYQDeHYoLBLVJUMdyAiwxVbbDm14qQSf5qGAZXRppmIgmlkgnY0gmlwhCJTfzOHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEC88lrc6V3LF77SNWjO_GT5YCA2Ca6fwPp1b3vIMBjSk-DdGNwgiQGg3VkcIIkBg,enr:-J64QIXTVl0Opbdn20TSrkzpIZ4xQ54bERRlTmSeZ05dFLdlSbuRY7yn5tJeTPzsSldTw5V5E0qjEQcsfr20vMjTUDyGAZXRpiWygmlkgnY0gmlwhCPjrx6Hb3BzdGFja4TsyQIAiXNlY3AyNTZrMaED2qWtZdFrywlnz0eNnyBUS_G23mF2NORS3_e5RyefQfSDdGNwgiQGg3VkcIIkBg,enr:-J64QFAsbeR4xRSyVyQOk7bILUCoMjI2EnbZvo4UAK3842HMYw41-UZXdnQJH8lwvzWn7qsY3Vu73NuxzxWKn4XB5wiGAZXRpYPAgmlkgnY0gmlwhCJSxmKHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDx51ZbXcmg4flmWldI-lBwUwiB0UFLqZkKnHvffMaE4eDdGNwgiQGg3VkcIIkBg,enr:-J64QFQSrL3mfG-i64T-5DgVE5V9dGKC5A0JrEvD6CRpZvuLK3feg4bPaqFWfqXyNN_6IgY2z1Jkr4Mf2Zx-GdWlWquGAZXQkMdSgmlkgnY0gmlwhCImtd-Hb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDQVEzYHXdCOtsdb_WOFXopL1v0Pka5KgbFJMPJnHhau6DdGNwgiQGg3VkcIIkBg,enr:-J64QAp3g1m-5uX-_mBXWyo6ZQqAlnRcAt11Xwy0-ZzqaSrDSlg4adyOz6v9flzLgxYkVvXI50nJGs8GjLgT5bwDLtyGAZXQrD69gmlkgnY0gmlwhCJMJgaHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaECq5mdt1EmXHFLFxNE3hly7XQ0gWLeRloERPVuULjP0EiDdGNwgiQGg3VkcIIkBg,enr:-J64QFCZs1ePThNEsRxIIzbfDxYfap1nEyuPPpSUeeWOoPFWOp0zSEPwLEtXhG1eH-ipsB5CgtaVzcXOyT9hKeAeVVaGAZXQkaZ3gmlkgnY0gmlwhCO7ajaHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDnYbZL7OKQpMwVG_hrvziZOH1XF1AJJtjFT5990QAX6ODdGNwgiQGg3VkcIIkBg,enr:-J64QJ9LY8m9AjNgujuVT0juX8T6PHKojZEIqd-7_vhBasfiT2xUUJoUfWga_xVJGFECFcN6hPKB4TjihmYFxHXelwOGAZXQkclrgmlkgnY0gmlwhCJMELeHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDyCwx8h3Vu7jcNWhv9npDUzgrQBfJ7HZgo4PMtbjjsEyDdGNwgiQGg3VkcIIkBg,enr:-J64QGJFPZzLj2GLFgB4JhTde7rXChMNFERNbzrwYYTG7CY2SCSggFrU3VXczzWBvOoJWdbOMOzPuCI2klknGjruUxeGAZXQkf1LgmlkgnY0gmlwhGjHJzuHb3BzdGFja4TsyQIAiXNlY3AyNTZrMaEDO61fV62N5lQfAuNtgGuH5-nKbVM8lW6JpWswVK6F1giDdGNwgiQGg3VkcIIkBg,enr:-J64QEXleDl25w0qEG__wmDgwnzB0F5zapu00D_jM4qkCbA3WIcLC8rXPm8dcrKdZNBuNXJOtNE6c2_ZDkuQMvIuhjCGAZXQwDjFgmlkgnY0gmlwhCKMdU-Hb3BzdGFja4TsyQIAiXNlY3AyNTZrMaECHezzuLmg0LgzLRUhjzvwzrlgaw7-GPNSxR7_wUu_H0-DdGNwgiQGg3VkcIIkBg


Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=celo-op-node

# Resource limits
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
```

***Enable and Start the Services***

```bash
# Reload systemd daemon
sudo systemctl daemon-reload

# Enable services to start on boot
sudo systemctl enable celo-op-geth
sudo systemctl enable celo-op-node


# Start op-geth and op-node first
sudo systemctl start celo-op-geth
sudo systemctl start celo-op-node
```

### Check Service Status

```bash
# Check all Celo services
sudo systemctl status celo-op-geth
sudo systemctl status celo-op-node

# View logs 
sudo journalctl -f -u celo-op-geth-n 100
sudo journalctl -f -u celo-op-node -n 100
```

```bash
curl -X POST -H "Content-Type: application/json" \ --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \ http://localhost:8545
```

Result

```bash
# if the sync is complete, the above command will return this
{"jsonrpc":"2.0","id":1,"result":false}
```

Check the current block number

```bash
curl -X POST -H "Content-Type: application/json" \ --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ http://localhost:8545
```

Result

```bash
{"jsonrpc":"2.0","id":1,"result":"0x24ffbfb"}
```

## References

{% embed url="<https://docs.celo.org/cel2/operators/migrate-node#troubleshooting>" %}

{% embed url="<https://docs.celo.org/cel2/notices/l2-migration>" %}

{% embed url="<https://docs.celo.org/cel2/operators/run-node#mainnet-1>" %}

{% embed url="<https://github.com/celo-org/celo-l2-node-docker-compose>" %}


# Chapel (BNB Testnet)


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

<table><thead><tr><th align="center">CPU</th><th align="center">OS</th><th width="254" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">8+ cores CPU</td><td align="center">Debian 12/Ubuntu 22.04</td><td align="center">=> 16 GB RAM</td><td align="center"><p>=1TB+</p><p> (NVMe)</p></td></tr></tbody></table>

{% hint style="info" %}
*The BSC Testnet Chapel archive node has a size of 463GB on March 17th, 2025*
{% endhint %}

## Setup of BSC Erigon

{% hint style="warning" %}
This guide covers the installation of `BSC Erigon V3`, which is Erigon V3's fork managed by Node-Real. It has built-in snapshot download function and allows to sync BSC Testnet Chapel archive Node in effecteively 48 hours. It is important to keep in mind that the client is still under development and you need to be prepared to face difficulties during synchronization or other techincal issues
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y libgtest-dev libomp-dev libgmp-dev git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq g++ curl libssl-dev screen apache2-utils build-essential
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH and peers

```bash
sudo ufw allow 22/tcp
sudo ufw allow 30303 #p2p port
sudo ufw allow 42069 #torrent port
```

Allow remote RPC connections with the Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545 #http api port
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8546 #ws port
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw status verbose
</strong></code></pre>

### Install GO

{% hint style="info" %}
Go version 1.22+ is required
{% endhint %}

```bash
sudo wget https://go.dev/dl/go1.22.4.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.22.4.linux-amd64.tar.gz && rm go1.22.4.linux-amd64.tar.gz

echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

source /root/.bashrc

#verify Go installation
go version
```

### Build Erigon RPC Node

```bash
git clone --recurse-submodules https://github.com/node-real/bsc-erigon.git

cd bsc-erigon
```

#### Check for the latest actual release at <https://github.com/node-real/bsc-erigon/releases>

This guide has been tested and successfully synced the node with ***v1.3.2-beta2***:

```bash
git checkout v1.3.2-beta2

make erigon
```

#### Create Data directory and jwt secret file

```bash
cd ..

mkdir -p /root/data/bsc-erigon/

openssl rand -hex 32 | tr -d "\n" > /root/data/bsc-erigon/jwt.hex
```

#### Create Systemd service for BSC Erigon

```bash
sudo nano /etc/systemd/system/bsc-erigon.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

{% hint style="danger" %}
Replace {IP} with the actual address of the server in order to explicitly set the external IP address that the node should advertise to peers in a P2P network
{% endhint %}

```bash
[Unit]
Description=BSC Chapel Erigon Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=500000

WorkingDirectory=/root/chapel/bsc-erigon/
ExecStart=/root/chapel/bsc-erigon/build/bin/erigon \
        --private.api.addr=127.0.0.1:9090 \
        --chain chapel \
        --prune.mode=archive \
        --torrent.download.rate=1g \
        --torrent.download.slots=400 \
        --batchSize=2g \
        --bsc.blobSidecars.no-pruning=true \
        --txpool.disable \
        --metrics \
        --metrics.addr=0.0.0.0 \
        --metrics.port=6060 \
        --pprof \
        --pprof.addr=0.0.0.0 \
        --pprof.port=6061 \
        --authrpc.jwtsecret=/root/data/bsc-erigon/jwt.hex \
        --authrpc.port=8551 \
        --datadir=/root/data/bsc-erigon/ \
        --http.addr=0.0.0.0 \
        --http.port=8545 \
        --http.api=eth,debug,net,trace,web3,erigon,bsc,admin \
        --http.vhosts=any \
        --http.corsdomain=* \
        --ws \
        --ws.port=8546 \
        --torrent.port=42069 \
        --nat=extip:{IP} \
        --db.pagesize=16k \
        --db.size.limit=4t \
        --port=30303
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target
```

#### Launch BSC Erigon

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable bsc-erigon.service #enable bsc-erigon.service at system startup

sudo systemctl start bsc-erigon.service #start bsc-erigon.service

sudo nano /etc/systemd/system/bsc-erigon.service #make changes in bsc-erigon.service file
```

### Monitor the logs for errors

```bash
journalctl -u bsc-erigon.service -f -n 100 #follow logs of bsc-erigon.service
```

#### During the initialization, first you are expected to see logs of a snapshot download process:

```bash
[INFO] [03-14|03:34:50.959] [1/9 OtterSync] Downloading              progress="(3639/3639 files) 32.14% - 132.0GB/410.5GB" time-left=1hrs:25m total-time=33m0s download-rate=55.6MB/s completion-rate=55.6MB/s alloc=7.3GB sys=16.2GB
[INFO] [03-14|03:34:50.960] [p2p] GoodPeers                          eth68=5
[INFO] [03-14|03:34:51.027] [snapshots] no progress yet              files=282 list=idx/v1-logtopics.256-288.ef,accessor/v1-tracesfrom.128-192.efi,history/v1-code.0-64.v,accessor/v1-receipt.0-64.vi,domain/v1-code.300-302.bt,...
[INFO] [03-14|03:34:52.303] [mem] memory stats                       Rss=77.8GB Size=0B Pss=77.8GB SharedClean=3.6MB SharedDirty=0B PrivateClean=67.9GB PrivateDirty=9.9GB Referenced=73.4GB Anonymous=9.6GB Swap=117.0MB alloc=7.4GB sys=16.2GB
[INFO] [03-14|03:35:10.959] [1/9 OtterSync] Downloading              progress="(3639/3639 files) 32.39% - 132.9GB/410.5GB" time-left=1hrs:32m total-time=33m20s download-rate=51.0MB/s completion-rate=51.1MB/s alloc=7.7GB sys=16.2GB
[INFO] [03-14|03:35:11.055] [snapshots] no progress yet              files=281 list=domain/v1-storage.288-296.bt,accessor/v1-receipt.288-296.efi,accessor/v1-accounts.64-128.efi,domain/v1-commitment
```

{% hint style="danger" %}
If the download progress shows 0% for too long, try restarting the client. Once the snapshot has been fully downloaded and applied by the client, the node will start syncing process and will reach a chainhead in under 48 hrs
{% endhint %}

#### Run *`curl`* command in the terminal to check the status of your node <a href="#run-curl-command-in-the-terminal-to-check-the-status-of-your-node" id="run-curl-command-in-the-terminal-to-check-the-status-of-your-node"></a>

```bash
curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545
```

When it returns `false` , your node is fully synchronized with the network

### References <a href="#references" id="references"></a>

{% embed url="<https://github.com/node-real/bsc-erigon/issues/441>" %}

{% embed url="<https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/archive_node/>" %}


# Docker

Authors: \[ Ankur | Dapplooker]

## System Requirements

<table data-full-width="false"><thead><tr><th>CPU</th><th>OS</th><th>RAM</th><th>DISK</th></tr></thead><tbody><tr><td>8 vCPU</td><td>Ubuntu 22.04</td><td>16 GB</td><td>500 GB </td></tr></tbody></table>

{% hint style="success" %}
*The Chapel node has a size of 463 GB on March 25, 2025.*
{% endhint %}

## Pre-requisite

Before starting, clean the setup then update and upgrade. Install following:

* Docker

### **Commands**

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io ufw -y jq -y
```

{% endcode %}

## Firewall Settings

### Check status & enable UFW&#x20;

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong>sudo ufw status verbose
</code></pre>

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP, and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

## Setup Instructions&#x20;

### Pull Docker Image

Pull the image from the GitHub container registry (ghr):

```bash
docker pull ghcr.io/node-real/bsc-erigon:v1.3.2-beta2
```

{% hint style="info" %}
Get latest version: <https://github.com/node-real/bsc-erigon/pkgs/container/bsc-erigon>
{% endhint %}

### Create docker compose file

Create project directory

```bash
mkdir /mnt/erigon-bsc/
```

Create *docker-compose.yml* file

```yaml
version: '3.8'

services:
  bsc-erigon:
    container_name: bsc-erigon
    image: ghcr.io/node-real/bsc-erigon:v1.3.2-beta2
    restart: on-failure
    user: root
    volumes:
      - /mnt/erigon-bsc:/root/data/bsc-erigon
    ports:
      - "8545:8545"   # HTTP RPC
      - "8546:8546"   # WebSocket
      - "30303:30303" # P2P TCP
      - "30303:30303/udp" # P2P UDP
      - "42069:42069" # Torrent Port
      - "6060:6060"   # Metrics
      - "6061:6061"   # PProf Debugging
      - "9090:9090"   # Private API
      - "8551:8551"   # Auth RPC
    command:
      - --private.api.addr=127.0.0.1:9090
      - --chain=chapel
      - --prune.mode=archive
      - --torrent.download.rate=1g
      - --torrent.download.slots=400
      - --batchSize=2g
      - --bsc.blobSidecars.no-pruning=true
      - --txpool.disable
      - --metrics
      - --metrics.addr=0.0.0.0
      - --metrics.port=6060
      - --pprof
      - --pprof.addr=0.0.0.0
      - --pprof.port=6061
      - --authrpc.jwtsecret=/root/data/bsc-erigon/jwt.hex
      - --authrpc.port=8551
      - --datadir=/root/data/bsc-erigon/
      - --http.addr=0.0.0.0
      - --http.port=8545
      - --http.api=eth,debug,net,trace,web3,erigon,bsc,admin
      - --http.vhosts=any
      - --http.corsdomain=*
      - --ws
      - --ws.port=8546
      - --torrent.port=42069
      - --nat=extip:157.90.180.249
      - --db.pagesize=16k
      - --db.size.limit=3t
      - --port=30303
    ulimits:
      nofile:
        soft: 500000
        hard: 500000
```

### Start the Node

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

## Monitoring

### Monitor Logs of Docker Container&#x20;

```bash
docker ps 
docker logs bsc-erigon
```

{% hint style="warning" %}
Might need to restart the container if snapshot download gets stuck for a longer duration. Total time required to sync is \~28 hr
{% endhint %}

## Sync Status

### Latest Block

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8545
```

*Response should look like:*

```json
{"jsonrpc":"2.0","id":1,"result":"0x2f19521"}
```

### References

{% embed url="<https://docs.bnbchain.org/bnb-smart-chain/developers/node_operators/archive_node/>" %}

{% embed url="<https://testnet.bscscan.com/>" %}


# Ethereum


# Erigon


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

|      CPU      |           OS           |      RAM     |                DISK                |
| :-----------: | :--------------------: | :----------: | :--------------------------------: |
| 16+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | <p>=3.5TB</p><p> (SSD or NVMe)</p> |

{% hint style="info" %}
*The Ethereum Mainnet archive node has a size of 3.1TB on September 11th, 2024*
{% endhint %}

## Setup production Erigon

{% hint style="success" %}
This guide covers the installation of`Erigon`, an implementation of Ethereum (execution layer), on the efficiency frontier, **Archive Node** by default, and `Lighthouse`(with historical blobs required for most L2 chains), as a Consensus Layer.
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y libgtest-dev libomp-dev libgmp-dev git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq g++ curl libssl-dev screen apache2-utils build-essential
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH and peers

```bash
sudo ufw allow 22/tcp
sudo ufw allow 30303
```

Allow remote RPC connections with Blast Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
sudo ufw allow from ${REMOTE.HOST.IP} to any port 5052
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw status verbose
</strong></code></pre>

### Install GO

{% hint style="info" %}
Go version 1.21+ is required
{% endhint %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

source /root/.bashrc

#verify Go installation
go version
```

### Build Erigon RPC Node

```bash
git clone --recurse-submodules https://github.com/ledgerwatch/erigon.git

cd erigon 

git checkout v2.60.6

make erigon
```

#### Create Data directory and jwt secret file

```bash
cd ..

mkdir erigon_data && cd erigon_data

sudo openssl rand -hex -out /root/erigon_data/jwtsecret 32
```

#### Create Systemd service for Erigon

```bash
sudo nano /etc/systemd/system/erigon.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Erigon Service
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/erigon/build/bin/
ExecStart=/root/erigon/build/bin/erigon \
    --chain=mainnet \
    --port=30303 \
    --http.port=8545 \
    --torrent.port=42069 \
    --torrent.download.rate=1024mb \
    --private.api.addr=127.0.0.1:9090 \
    --http \
    --ws \
    --http.api=eth,debug,net,trace,web3,erigon \
    --http.addr=0.0.0.0 \
    --http.corsdomain='*' \
    --metrics \
    --metrics.port=6060 \
    --metrics.addr=0.0.0.0 \
    --authrpc.jwtsecret=/root/erigon_data/jwt.hex \
    --datadir=/root/erigon_data \
    --rpc.gascap=5000000000 \
    --rpc.returndata.limit=1100000 \
    --pprof \
    --pprof.addr=0.0.0.0 \
    --pprof.port=6070

[Install]
WantedBy=multi-user.target
```

#### Launch Erigon

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable erigon.service #enable erigon service at system startup

sudo systemctl start erigon.service #start erigon

sudo nano /etc/systemd/system/erigon.service #make changes in erigon.service file
```

### Build Lighthouse

Go to the [Releases](https://github.com/sigp/lighthouse/releases) page and select the latest release:

```bash
cd /root/

mkdir lighthouse_data

mkdir lighthouse && cd lighthouse

wget https://github.com/sigp/lighthouse/releases/download/v5.3.0/lighthouse-v5.3.0-x86_64-unknown-linux-gnu.tar.gz

tar -xzf lighthouse-v5.3.0-x86_64-unknown-linux-gnu.tar.gz #Extract the tar.gz archive

chmod +x /root/lighthouse/ #Grant execute permissions to the files in the directory
```

#### Create systemd file for Lighthouse

```bash
sudo nano /etc/systemd/system/lighthouse.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Lighthouse Beacon Node
After=network.target

[Service]
User=root
WorkingDirectory=/root/lighthouse/
ExecStart=/root/lighthouse/lighthouse beacon_node \
    --network mainnet \
    --datadir /root/lighthouse_data \
    --http \
    --http-address 0.0.0.0 \
    --http-port 5052 \
    --execution-endpoint http://127.0.0.1:8551 \
    --checkpoint-sync-url https://sync-mainnet.beaconcha.in \
    --execution-jwt /root/erigon_data/jwt.hex \
    --disable-deposit-contract-sync \
    --prune-blobs false
Restart=on-failure
LimitNOFILE=1000000

[Install]
WantedBy=default.target
```

#### Launch Lighthouse

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable lighthouse.service #enable Lighthouse service at system startup

sudo systemctl start lighthouse.service #start Lighthouse

sudo nano /etc/systemd/system/lighthouse.service #make changes in lighthouse.service file
```

### Monitor the logs for errors

```bash
journalctl -u erigon.service -f -n 100 #follow logs of erigon.service

journalctl -u lighthouse -f -n 100 #follow logs of lighthouse.service
```

During the synchonization, you are expected to get following log messages from`erigon`:

```bash
[INFO] [09-06|02:52:15.496] [4/12 Execution] Executed blocks         number=9421994 blk/s=112.3 tx/s=9589.1 Mgas/s=906.5 gasState=0.38 batch=246.4MB alloc=6.4GB sys=16.7GB
[INFO] [09-06|02:52:29.871] [] Flushed buffer file                   name=erigon-sortable-buf-4268134305
[INFO] [09-06|02:52:30.358] [] Flushed buffer file                   name=erigon-sortable-buf-140271917
[INFO] [09-06|02:52:30.405] [] Flushed buffer file                   name=erigon-sortable-buf-3356874711
[INFO] [09-06|02:52:43.500] Committed State                          gas reached=221060403580 gasTarget=549755813888 block=9423228 time=16.113674309s committedToDb=true
[INFO] [09-06|02:52:45.488] [4/12 Execution] Executed blocks         number=9423456 blk/s=48.7 tx/s=5474.7 Mgas/s=412.4 gasState=0.00 batch=3.1MB alloc=5.7GB sys=16.7GB
```

And `Lighthouse`:

{% code fullWidth="false" %}

```bash
Sep 06 01:05:36.659 INFO New block received                      root: 0x9bf6a56781caf6b6e57cb6a0cead5e9ada0c417a36d4dd3d6924d07e5993935b, slot: 9896726
Sep 06 01:05:41.000 WARN Head is optimistic                      execution_block_hash: 0x613050be274505439dda4867d07840bd2e2e6e9ba0cddd96aada49449861bbb2, info: chain not fully verified, block and attestation production disabled until execution engine syncs, service: slot_notifier
```

{% endcode %}

### Run *`curl`* command in the terminal to check the status of your node

<pre class="language-bash"><code class="lang-bash"><strong>curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545
</strong></code></pre>

Expected output during synchronization:

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"currentBlock":"0x0","highestBlock":"0x137477f","stages":[{"stage_name":"Snapshots","block_number":"0x137477f"},{"stage_name":"Headers","block_number":"0x137477f"},{"stage_name":"BorHeimdall","block_number":"0x0"},{"stage_name":"BlockHashes","block_number":"0x137477f"},{"stage_name":"Bodies","block_number":"0x137477f"},{"stage_name":"Senders","block_number":"0x137477f"},{"stage_name":"Execution","block_number":"0x90b383"},{"stage_name":"Translation","block_number":"0x0"},{"stage_name":"HashState","block_number":"0x0"},{"stage_name":"IntermediateHashes","block_number":"0x0"},{"stage_name":"AccountHistoryIndex","block_number":"0x0"},{"stage_name":"StorageHistoryIndex","block_number":"0x0"},{"stage_name":"LogIndex","block_number":"0x0"},{"stage_name":"CallTraces","block_number":"0x0"},{"stage_name":"TxLookup","block_number":"0x0"},{"stage_name":"Finish","block_number":"0x0"}]}}
```

{% endcode %}

When it returns `false` then your node is fully synchronized with the network

## References

{% embed url="<https://github.com/erigontech/erigon>" %}

{% embed url="<https://lighthouse-book.sigmaprime.io/intro.html>" %}

{% embed url="<https://github.com/sigp/lighthouse>" %}


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="133" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">Higher clock speed over core count</td><td align="center">Ubuntu 22.04</td><td align="center">>=16GB</td><td align="center">>=3TB (NVMe recommended)</td></tr></tbody></table>

## Erigon  🦦  Lighthouse 🕯️

Official Docs <https://erigon.gitbook.io/>&#x20;

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Erigon directory

The first command, `mkdir erigon`, will create a new directory named erigon in the current location. The second command, `cd erigon`, will change your current working directory to the newly created erigon directory. Now you are inside the erigon directory and can start storing docker-compose and related files in it.

```bash
mkdir erigon
cd erigon
```

### Generate JWT token

Generate a 32-byte random hexadecimal value using OpenSSL, removes any newline characters, and then save the result into the file "jwt.hex" located in the erigon directory.

```bash
openssl rand -hex 32 | tr -d "\n" > "./jwt.hex"
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    traefik_letsencrypt: {}
    erigon_data: {}
    lighthouse_data: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################             ERIGON CONTAINER               #######################
###################################################################################### 

  erigon:
    image: thorax/erigon:v2.48.1
    container_name: erigon
    restart: unless-stopped
    expose:
      - "8545" #rpc
      - "8551" #auth
      - "6060" #metrics
      - "9090" #api
    ports:
      - 30303:30303 #p2p
      - 30303:30303/udp #p2p
      - 30304:30304 #p2p
      - 30304:30304/udp #p2p
      - 42069:42069 #torrent
      - 42069:42069/udp #torrent
      - 4000:4000/udp #lightclient discovery
      - 4001:4001 #lightclient tcp
    networks:
      - monitor-net
    command: >
      --chain mainnet
      --authrpc.jwtsecret=/jwt
      --authrpc.port=8551
      --authrpc.addr=0.0.0.0
      --authrpc.vhosts=*
      --http
      --http.addr=0.0.0.0
      --http.port=8545
      --http.compression
      --http.vhosts=*
      --http.corsdomain=*
      --http.api=eth,debug,net,trace,web3,erigon
      --private.api.addr=0.0.0.0:9090 
      --ws --ws.compression
      --metrics --metrics.addr=0.0.0.0 
      --metrics.port=6060
      --pprof
      --pprof.addr=0.0.0.0
      --pprof.port=6070
      --torrent.download.rate 1024mb
      --rpc.returndata.limit=1000000
    volumes:
      - erigon_data:/home/erigon/.local/share/erigon
      - ./jwt.hex:/jwt:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.erigon-stripprefix.stripprefix.prefixes=/eth-mainnet"
      - "traefik.http.services.erigon.loadbalancer.server.port=8545"
      - "traefik.http.routers.erigon.entrypoints=websecure"
      - "traefik.http.routers.erigon.tls.certresolver=myresolver"
      - "traefik.http.routers.erigon.rule=Host(`$DOMAIN`) && PathPrefix(`/eth-mainnet`)"
      - "traefik.http.routers.erigon.middlewares=arbitrum-stripprefix, ipwhitelist"

######################################################################################
#####################            LIGHTHOUSE CONTAINER               ##################
###################################################################################### 

  lighthouse:
    image: sigp/lighthouse:v4.3.0
    container_name: lighthouse
    restart: unless-stopped
    expose:
      - "5052/tcp" #http api
      - "5054/tcp" #metrics
    ports:
     - "9000:9000/tcp" # peering
     - "9000:9000/udp"
    networks:
     - monitor-net
    command: >
      lighthouse bn
      --http --http-address 0.0.0.0
      --execution-endpoint=http://erigon:8551
      --metrics --metrics-address 0.0.0.0
      --execution-jwt=/jwt.hex
      --checkpoint-sync-url=https://sync-mainnet.beaconcha.in
    volumes:
      - lighthouse_data:/data
      - ./jwt.hex:/jwt.hex:ro
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Erigon

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

### Monitor Logs

Use `docker logs` to monitor your erigon and lighthouse nodes. The `-f` flag ensures you are following the log output

```
docker logs erigon -f
docker logs lighthouse -f
```

## Test Erigon RPC 🧪

{% hint style="danger" %}
Erigon and Consensus client must be synced before testing.
{% endhint %}

{% code overflow="wrap" %}

```bash
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1", true],"id":1}' http://{DOMAIN}/eth-mainnet
```

{% endcode %}

{% hint style="warning" %}
This should be your result.
{% endhint %}

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0x3ff800000","extraData":"0x476574682f76312e302e302f6c696e75782f676f312e342e32","gasLimit":"0x1388","gasUsed":"0x0","hash":"0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x05a56e2d52c817161883f50c441c3228cfe54d9f","mixHash":"0x969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59","nonce":"0x539bd4979fef1ec4","number":"0x1","parentHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x219","stateRoot":"0xd67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3","timestamp":"0x55ba4224","totalDifficulty":"0x7ff800000","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}}
```

{% endcode %}


# Reth


# Baremetal

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">Higher clock speed over core count</td><td align="center">Ubuntu 22.04</td><td align="center">8GB+</td><td align="center">At least 2.1TB (TLC NVMe recommended)</td></tr></tbody></table>

## Reth 🦀

Official Docs <https://paradigmxyz.github.io/reth/intro.html>

### Pre-requisites

Update, upgrade, and clean the system, and then install essential development tools (build-essential), firewall management (ufw), and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt-get install -y build-essential ufw git libclang-dev pkg-config
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow P2P connections with Erigon, Consensus peers and SSH

```bash
sudo ufw allow 30303
sudo ufw allow 9001
sudo ufw allow 22/tcp
```

Allow P2P connections with Reth, Consensus peers and SSH

```bash
sudo ufw allow 30303
sudo ufw allow 9001
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Execution Client

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9656
```

{% hint style="danger" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

### Install rust

The rustup installer provides an easy way to update the Rust compiler

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

Please add the Cargo path to your system's `PATH` environment variable, and then test to ensure that Cargo is working correctly.

```bash
echo "export PATH="$PATH:/root/.local/bin:/root/.cargo/env"" >> /root/.bashrc
source /root/.bashrc
cargo --version #test
```

### Create reth directory

Create a new directory named reth within the "/root/.local/share" directory, providing a location for storing data related to Reth.

```
mkdir /root/.local/share/reth
```

### Generate JWT token

Generate a 32-byte random hexadecimal value using OpenSSL, removes any newline characters, and then save the result into the file "jwt.hex" located in the "/root/.local/share/reth/" directory.

```bash
openssl rand -hex 32 | sudo tee /root/.local/share/reth/jwt.hex > /dev/null
```

### Build Reth

Clone the reth repository from GitHub, navigate to the reth directory, then build the project with `cargo build`.

```
git clone https://github.com/paradigmxyz/reth
cd reth
RUSTFLAGS="-C target-cpu=native" cargo build --profile maxperf
```

### Configure Reth

```
sudo echo "[Unit]
Description=Reth Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/.local/share/reth/
ExecStart=/root/reth/target/maxperf/reth \
        --datadir=/root/.local/share/reth/datadir \
        --chain mainnet \
        --authrpc.jwtsecret=/root/.local/share/reth/jwt.hex \
        --authrpc.port=9663 \
        --http \
        --http.addr=0.0.0.0 \
        --http.port=9656 \
        --http.corsdomain=* \
        --http.api=eth,debug,net,trace,web3,erigon \
        --ws \
        --metrics=6060
        
KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/reth.service
```

### Run Reth

Reload the systemd manager configuration, start the Reth service, and enable it to start automatically on system boot, ensuring that the Reth Mainnet Service is active and will be automatically started upon system startup.

```bash
sudo systemctl daemon-reload
sudo systemctl start reth
sudo systemctl enable reth
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Reth service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu reth
```

## Consensus Clients&#x20;

{% hint style="danger" %}
For Reth to operate, it requires the use of a consensus client. It is crucial to consider client diversity while doing so. -> <https://clientdiversity.org/>
{% endhint %}

## Lodestar 🤠

Official Docs <https://chainsafe.github.io/lodestar/>

### Install yarn and nodeJS

```bash
#yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update -y && sudo apt install yarn -y
#nodeJS
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
```

### Create Lodestar Directory

Create a new directory named lodestar within the "/root/.local/share" directory, providing a location for storing data related to Lodestar.

```bash
mkdir /root/.local/share/lodestar
```

### Build Lodestar

Clone the lodestar repository from GitHub, navigate to the lodestar directory, switch to the stable branch, and then build the project with yarn.

```bash
git clone https://github.com/chainsafe/lodestar.git
cd lodestar
git checkout stable
yarn install
yarn run build
```

### Configure Lodestar

Append a systemd service configuration for the Lodestar Mainnet Service to the "/etc/systemd/system/lodestar.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Lodestar Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/lodestar/
ExecStart=/root/lodestar/lodestar beacon \
  --datadir=/root/.local/share/lodestar \
  --network=mainnet \
  --rest \
  --rest.port=6061 \
  --metrics \
  --metrics.port=6062 \
  --port 9001 \
  --checkpointSyncUrl=https://sync-mainnet.beaconcha.in \
  --execution.urls=http://127.0.0.1:9663 \
  --jwt-secret=/root/.local/share/reth/jwt.hex

KillSignal=SIGHUP  

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/lodestar.service
```

### Run Lodestar

Reload the systemd manager configuration, restart the Lodestar and Reth services, and enable the Lodestar service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Lodestar service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart lodestar reth
sudo systemctl enable lodestar
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Lodestar service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu lodestar
```

## Lighthouse 🕯️

Official Docs <https://lighthouse-book.sigmaprime.io/>

### Create Lighthouse Directory

Create a new directory named lighthouse within the "/root/.local/share" directory, providing a location for storing data related to Lighthouse.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/lighthouse
</strong></code></pre>

### Build Lighthouse

Clone the lighthouse repository from GitHub, navigate to the lighthouse directory, switch to the stable branch, and then build the project with make.

```bash
git clone https://github.com/sigp/lighthouse.git
cd lighthouse
git checkout stable
make
```

### Configure Lighthouse

Append a systemd service configuration for the Lighthouse Mainnet Service to the "/etc/systemd/system/lighthouse.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=LightHouse Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/lighthouse/
ExecStart=/root/lighthouse/target/release/lighthouse bn \
        --datadir=/root/.local/share/lighthouse \
        --network=mainnet \
        --http \
        --http-port=6061 \
        --metrics \
        --metrics-port=6062 \
        --port=9001 \
        --checkpoint-sync-url=https://sync-mainnet.beaconcha.in \
        --execution-endpoint=http://127.0.0.1:9663 \
        --execution-jwt=/root/.local/share/reth/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/lighthouse.service
```

### Run Lighthouse

Reload the systemd manager configuration, restart the Lighthouse and Reth services, and enable the Lighthouse service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Lighthouse service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart lighthouse reth
sudo systemctl enable lighthouse
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Lighthouse service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu lighthouse
```

## Nimbus ☁️

Official Docs <https://nimbus.guide/index.html>

### Install cmake

```bash
sudo apt -y install cmake
```

### Create Nimbus Directory

Create a new directory named nimbus within the "/root/.local/share" directory, providing a location for storing data related to Nimbus.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/nimbus
</strong></code></pre>

### Build Nimbus

Clone the Nimbus repository from GitHub, navigate to the nimbus directory, switch to the latest stable release, and then build the project with `make`

```bash
git clone https://github.com/status-im/nimbus-eth2
cd nimbus-eth2
git checkout stable
make -j4 nimbus_beacon_node
```

{% hint style="info" %}
You can increase `-j4` (`-j32`) with higher or lower integer depending on your host machine ram to decrease build time. Omit `-j4` on systems with 4GB of memory or less.
{% endhint %}

### Configure Nimbus

Append a systemd service configuration for the Nimbus Mainnet Service to the "/etc/systemd/system/nimbus.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Nimbus Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/nimbus-eth2/
ExecStart=/root/nimbus-eth2/build/nimbus_beacon_node trustedNodeSync \
        --data-dir=/root/.local/share/nimbus \
        --network=mainnet \
        --rest=true \
        --rest-port=6061 \
        --metrics \
        --metrics-port=6062 \
        --tcp-port=9001 --udp-port=9001 \
        --trusted-node-url=https://sync-mainnet.beaconcha.in \
        --web3-url=http://127.0.0.1:9663 \
        --jwt-secret=/root/.local/share/reth/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/nimbus.service
```

### Run Nimbus

Reload the systemd manager configuration, restart the Nimbus and Reth services, and enable the Nimbus service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Nimbus service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart nimbus erigon
sudo systemctl enable nimbus
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Nimbus service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu nimbus
```

## Teku 🍷

Official Docs <https://docs.teku.consensys.net/get-started>

### Install the required Java runtime&#x20;

```bash
sudo apt -y install openjdk-17-jre
```

### Create Teku Directory

Create a new directory named teku within the "/root/.local/share" directory, providing a location for storing data related to Teku.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/teku
</strong></code></pre>

### Build Teku

Clone the teku repository from GitHub, navigate to the teku directory, switch to the latest release, and then build the project with with the Gradle wrapper `gradlew`, as follows.

```bash
git clone https://github.com/Consensys/teku.git
cd teku
git checkout <latest release tag>
./gradlew distTar installDist
```

### Configure Teku

Append a systemd service configuration for the Teku Mainnet Service to the "/etc/systemd/system/teku.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Teku Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
Environment="JAVA_OPTS=-Xmx5g"
Environment="TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError"
WorkingDirectory=/root/teku/
ExecStart=/root/teku/build/install/teku/bin/teku \
        --network=mainnet \
        --data-path=/root/.local/share/teku \
        --rest-api-enabled=true \
        --rest-api-port=6061 \
        --metrics-enabled=true \
        --metrics-port=6062 \
        --p2p-port=9001 \
        --initial-state=https://sync-mainnet.beaconcha.in \
        --ee-endpoint=http://127.0.0.1:9663 \
        --ee-jwt-secret-file=/root/.local/share/reth/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/teku.service
```

### Run Teku

Reload the systemd manager configuration, restart the Teku and Reth services, and enable the Teku service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Teku service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart teku reth
sudo systemctl enable teku
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Teku service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu teku
```

## Test Reth RPC 🧪

{% hint style="danger" %}
Reth and Consensus client must be synced before testing.
{% endhint %}

{% code overflow="wrap" %}

```bash
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1", true],"id":1}' http://localhost:9656
```

{% endcode %}

{% hint style="warning" %}
This should be your result.
{% endhint %}

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0x3ff800000","extraData":"0x476574682f76312e302e302f6c696e75782f676f312e342e32","gasLimit":"0x1388","gasUsed":"0x0","hash":"0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x05a56e2d52c817161883f50c441c3228cfe54d9f","mixHash":"0x969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59","nonce":"0x539bd4979fef1ec4","number":"0x1","parentHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x219","stateRoot":"0xd67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3","timestamp":"0x55ba4224","totalDifficulty":"0x7ff800000","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}}
```

{% endcode %}


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="133" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">Higher clock speed over core count</td><td align="center">Ubuntu 22.04</td><td align="center">8GB+</td><td align="center">At least 2.1TB (TLC NVMe recommended)</td></tr></tbody></table>

## Reth 🦀 + Lighthouse 🕯️

Official Docs <https://paradigmxyz.github.io/reth/intro.html>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Reth directory

The first command, `mkdir reth`, will create a new directory named reth in the current location. The second command, `cd reth`, will change your current working directory to the newly created reth directory. Now you are inside the "reth" directory and can start storing docker-compose and related files in it.

```bash
mkdir reth
cd reth
```

### Generate JWT token

Generate a 32-byte random hexadecimal value using OpenSSL, removes any newline characters, and then save the result into the file "jwt.hex" located in the reth directory.

```bash
openssl rand -hex 32 | sudo tee ~/reth/jwt.hex > /dev/null
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    traefik_letsencrypt: {}
    reth_data: {}
    reth_logs: {}
    lighthouse_data: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################             RETH CONTAINER               #######################
###################################################################################### 

  reth:
    image: ghcr.io/paradigmxyz/reth:v0.1.0-alpha.4
    container_name: reth
    restart: unless-stopped
    expose:
      - "8545" #rpc
      - "8551" #auth
      - "9001" #metrics
    ports:
      - "30303:30303" # peering
    command: >
      node
      --chain mainnet
      --metrics 0.0.0.0:9091
      --log.persistent
      --log.directory /root/rethlogs
      --authrpc.addr 0.0.0.0
      --authrpc.port 8551
      --authrpc.jwtsecret /root/jwt/jwt.hex
      --http --http.addr 0.0.0.0 --http.port 8545
      --http.api "eth,net,web3"
    volumes:
      - reth_data:/root/.local/share/reth/mainnet/db
      - reth_logs:/root/rethlogs
      - ./jwt.hex:/root/jwt/jwt.hex:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.reth-stripprefix.stripprefix.prefixes=/eth-mainnet"
      - "traefik.http.services.reth.loadbalancer.server.port=8545"
      - "traefik.http.routers.reth.entrypoints=websecure"
      - "traefik.http.routers.reth.tls.certresolver=myresolver"
      - "traefik.http.routers.reth.rule=Host(`$DOMAIN`) && PathPrefix(`/eth-mainnet`)"
      - "traefik.http.routers.reth.middlewares=arbitrum-stripprefix, ipwhitelist"

######################################################################################
#####################            LIGHTHOUSE CONTAINER               ##################
###################################################################################### 

  lighthouse:
    image: sigp/lighthouse
    container_name: lighthouse
    restart: unless-stopped
    expose:
      - "5052/tcp" #rpc
      - "5053/tcp"
      - "5054/tcp" #metrics
    ports:
     - "9000:9000/tcp" # peering
     - "9000:9000/udp"
    command: >
      lighthouse bn
      --http --http-address 0.0.0.0
      --execution-endpoint http://reth:8551
      --metrics --metrics-address 0.0.0.0
      --execution-jwt /root/jwt/jwt.hex
      --checkpoint-sync-url https://mainnet.checkpoint.sigp.io
    volumes:
      - lighthouse_data:/root/.lighthouse
      - ./jwt.hex:/root/jwt/jwt.hex:ro
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Reth

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

### Monitor Logs

Use `docker logs` to monitor your reth and lighthouse nodes. The `-f` flag ensures you are following the log output

```
docker logs reth -f
docker logs lighthouse -f
```

## Test Reth RPC 🧪

{% hint style="danger" %}
Reth and Consensus client must be synced before testing.
{% endhint %}

{% code overflow="wrap" %}

```bash
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1", true],"id":1}' http://{DOMAIN}/eth-mainnet
```

{% endcode %}

{% hint style="warning" %}
This should be your result.
{% endhint %}

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0x3ff800000","extraData":"0x476574682f76312e302e302f6c696e75782f676f312e342e32","gasLimit":"0x1388","gasUsed":"0x0","hash":"0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x05a56e2d52c817161883f50c441c3228cfe54d9f","mixHash":"0x969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59","nonce":"0x539bd4979fef1ec4","number":"0x1","parentHash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x219","stateRoot":"0xd67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3","timestamp":"0x55ba4224","totalDifficulty":"0x7ff800000","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}}
```

{% endcode %}


# Ethereum Sepolia


# Erigon


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements <a href="#system-requirements" id="system-requirements"></a>

| **CPU**       | **OS**                 | **RAM**      | **DISK**           |
| ------------- | ---------------------- | ------------ | ------------------ |
| 16+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | =1TB+(SSD or NVMe) |

{% hint style="info" %}
*The Ethereum Sepolia archive node has a size of 1TB on November 15th, 2024*
{% endhint %}

## Setup Production Erigon <a href="#setup-production-erigon" id="setup-production-erigon"></a>

{% hint style="success" %}
This guide covers the installation of`Erigon`, an implementation of Ethereum (execution layer), on the efficiency frontier, **Archive Node** by default, and `Lighthouse`, as a Consensus Layer.
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y libgtest-dev libomp-dev libgmp-dev git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq g++ curl libssl-dev screen apache2-utils build-essential
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH and peers

```bash
sudo ufw allow 22/tcp
sudo ufw allow 30303
sudo ufw allow 9001
```

Allow remote RPC connections with the Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
sudo ufw allow from ${REMOTE.HOST.IP} to any port 5052
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw status verbose
</strong></code></pre>

### Install GO

{% hint style="info" %}
Go version 1.21+ is required
{% endhint %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

source /root/.bashrc

#verify Go installation
go version
```

### Build Erigon RPC Node

```bash
git clone --recurse-submodules https://github.com/ledgerwatch/erigon.git

cd erigon 

git checkout v2.60.10

make erigon
```

#### Create Data directory and jwt secret file

```bash
cd ..

mkdir erigon-sepolia_data && cd erigon-sepolia_data

sudo openssl rand -hex -out /root/erigon-sepolia_data/jwtsecret 32
```

#### Create Systemd service for Erigon

```bash
sudo nano /etc/systemd/system/erigon-sepolia.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Erigon Sepolia Service
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/erigon/build/bin/
ExecStart=/root/erigon/build/bin/erigon \
    --chain=sepolia \
    --port=30303 \
    --http.port=8545 \
    --torrent.port=42069 \
    --torrent.download.rate=80mb \
    --private.api.addr=127.0.0.1:9090 \
    --http \
    --ws \
    --http.api=eth,debug,net,trace,web3,erigon \
    --http.addr=0.0.0.0 \
    --http.corsdomain='*' \
    --metrics \
    --metrics.port=6060 \
    --metrics.addr=0.0.0.0 \
    --authrpc.jwtsecret=/root/erigon-sepolia_data/jwt.hex \
    --datadir=/root/erigon-sepolia_data \
    --rpc.gascap=5000000000 \
    --rpc.returndata.limit=1100000 \
    --pprof \
    --pprof.addr=0.0.0.0 \
    --pprof.port=6070

[Install]
WantedBy=multi-user.target
```

#### Launch Erigon

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable erigon-sepolia.service #enable erigon-sepolia.service at system startup

sudo systemctl start erigon-sepolia.service #start erigon-sepolia.service

sudo nano /etc/systemd/system/erigon-sepolia.service #make changes in erigon-sepolia.service file
```

### Build Lighthouse

Go to the [Releases](https://github.com/sigp/lighthouse/releases) page and select the latest release:

```bash
cd /root/

mkdir lighthouse-sepolia_data

mkdir lighthouse-sepolia && cd lighthouse-sepolia

wget https://github.com/sigp/lighthouse/releases/download/v5.3.0/lighthouse-v5.3.0-x86_64-unknown-linux-gnu.tar.gz

tar -xzf lighthouse-v5.3.0-x86_64-unknown-linux-gnu.tar.gz #Extract the tar.gz archive

chmod +x /root/lighthouse-sepolia/ #Grant execute permissions to the files in the directory
```

#### Create systemd file for Lighthouse

```bash
sudo nano /etc/systemd/system/lighthouse-sepolia.service
```

Paste the configs and save by entering `ctrl+X` and `Y+ENTER`:

```bash
[Unit]
Description=Lighthouse-sepolia Beacon Node
After=network.target

[Service]
User=root
WorkingDirectory=/root/lighthouse-sepolia/
ExecStart=/root/lighthouse-sepolia/lighthouse beacon_node \
    --network sepolia \
    --datadir /root/lighthouse-sepolia_data \
    --http \
    --http-address 0.0.0.0 \
    --http-port 5052 \
    --execution-endpoint http://127.0.0.1:8551 \
    --checkpoint-sync-url https://sepolia.beaconstate.info \
    --execution-jwt /root/erigon-sepolia_data/jwt.hex \
    --disable-deposit-contract-sync \
    --prune-blobs false
Restart=on-failure
LimitNOFILE=1000000

[Install]
WantedBy=default.target
```

#### Launch Lighthouse

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable lighthouse-sepolia.service #enable lighthouse-sepolia service at system startup

sudo systemctl start lighthouse-sepolia.service #start lighthouse-sepolia

sudo nano /etc/systemd/system/lighthouse-sepolia.service #make changes in lighthouse-sepolia.service file
```

### Monitor the logs for errors

```bash
journalctl -u erigon-sepolia.service -f -n 100 #follow logs of erigon-sepolia.service

journalctl -u lighthouse-sepolia.service -f -n 100 #follow logs of lighthouse-sepolia.service
```

During the synchonization, you are expected to get following log messages from`erigon`:

```bash
[INFO] [09-06|02:52:15.496] [4/12 Execution] Executed blocks         number=9421994 blk/s=112.3 tx/s=9589.1 Mgas/s=906.5 gasState=0.38 batch=246.4MB alloc=6.4GB sys=16.7GB
[INFO] [09-06|02:52:29.871] [] Flushed buffer file                   name=erigon-sortable-buf-4268134305
[INFO] [09-06|02:52:30.358] [] Flushed buffer file                   name=erigon-sortable-buf-140271917
[INFO] [09-06|02:52:30.405] [] Flushed buffer file                   name=erigon-sortable-buf-3356874711
[INFO] [09-06|02:52:43.500] Committed State                          gas reached=221060403580 gasTarget=549755813888 block=9423228 time=16.113674309s committedToDb=true
[INFO] [09-06|02:52:45.488] [4/12 Execution] Executed blocks         number=9423456 blk/s=48.7 tx/s=5474.7 Mgas/s=412.4 gasState=0.00 batch=3.1MB alloc=5.7GB sys=16.7GB
```

And `Lighthouse`:

{% code fullWidth="false" %}

```bash
Sep 06 01:05:36.659 INFO New block received                      root: 0x9bf6a56781caf6b6e57cb6a0cead5e9ada0c417a36d4dd3d6924d07e5993935b, slot: 9896726
Sep 06 01:05:41.000 WARN Head is optimistic                      execution_block_hash: 0x613050be274505439dda4867d07840bd2e2e6e9ba0cddd96aada49449861bbb2, info: chain not fully verified, block and attestation production disabled until execution engine syncs, service: slot_notifier
```

{% endcode %}

### Run *`curl`* command in the terminal to check the status of your node

<pre class="language-bash"><code class="lang-bash"><strong>curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545
</strong></code></pre>

Expected output during synchronization:

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","id":1,"result":{"currentBlock":"0x0","highestBlock":"0x137477f","stages":[{"stage_name":"Snapshots","block_number":"0x137477f"},{"stage_name":"Headers","block_number":"0x137477f"},{"stage_name":"BorHeimdall","block_number":"0x0"},{"stage_name":"BlockHashes","block_number":"0x137477f"},{"stage_name":"Bodies","block_number":"0x137477f"},{"stage_name":"Senders","block_number":"0x137477f"},{"stage_name":"Execution","block_number":"0x90b383"},{"stage_name":"Translation","block_number":"0x0"},{"stage_name":"HashState","block_number":"0x0"},{"stage_name":"IntermediateHashes","block_number":"0x0"},{"stage_name":"AccountHistoryIndex","block_number":"0x0"},{"stage_name":"StorageHistoryIndex","block_number":"0x0"},{"stage_name":"LogIndex","block_number":"0x0"},{"stage_name":"CallTraces","block_number":"0x0"},{"stage_name":"TxLookup","block_number":"0x0"},{"stage_name":"Finish","block_number":"0x0"}]}}
```

{% endcode %}

When it returns `false` then your node is fully synchronized with the network

## References <a href="#references" id="references"></a>

{% embed url="<https://github.com/erigontech/erigon>" %}

{% embed url="<https://github.com/sigp/lighthouse>" %}

{% embed url="<https://lighthouse-book.sigmaprime.io/intro.html>" %}


# Geth


# Docker

Author: \[ jLeopoldA ]

## System Requirements

| CPU      | OS                  | RAM       | DISK      |
| -------- | ------------------- | --------- | --------- |
| 4+ Cores | Ubunutu 24.04.1 LTS | 16GB+ RAM | 3.5TB SSD |

{% hint style="info" %}
The Ethereum Sepolia Archive Node has a size of 3.2TB as of 2/11/2025
{% endhint %}

## Pre-Requisites

{% hint style="info" %}
This method of setting up an Ethereum Sepolia Archive Node uses Docker, Docker-Compose, Geth (Execution Layer) and Prysm (Consensus Layer / Beacon Node).
{% endhint %}

### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
```

### Set Up Firewall

#### Set Explicit Default Firewall Rules

```bash
sudo ufw default deny incoming 
sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow RPC Connections with Geth / Sepolia

```bash
sudo ufw allow 8545
sudo ufw allow 8546
```

#### Allow P2P Connections for Geth and Prysm

```bash
# Required Ports for Geth (Execution Layer)
# Ethereum P2P networking
sudo ufw allow 30303/tcp && sudo ufw allow 30303/udp
sudo ufw allow 8551/tcp # Authentication RPC

# Required Prysm (Consensus Layer)
sudo ufw allow 13000/tcp # P2P networking
sudo ufw allow 12000/udp # Discovery protocol
sudo ufw allow 4000
```

#### Enable Firewall

```bash
sudo ufw enable
```

#### Check Status / Current Rules of UFW

```bash
sudo ufw status verbose
```

### Install Docker & Docker-Compose

#### Install Docker

```bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install Docker Packages including Docker Compose
 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
# Verify Docker Engine Installation
sudo docker run hello-world
```

## Build Ethereum Sepolia Archive Node

### Create Directory

```bash
mkdir -p /root/sepolia
cd /root/sepolia
```

### Create jwt.hex

```bash
openssl rand -hex 32 | tr -d "\n" > jwt.hex
```

### Create docker-compose.yml

```bash
nano docker-compose.yml

# Copy and paste the below
services:
  beacon-node:
    image: gcr.io/prysmaticlabs/prysm/beacon-chain:stable
    container_name: beacon-node
    restart: unless-stopped
    volumes:
      - $HOME/.eth2:/data
      - /root/sepolia/jwt.hex:/root/sepolia/jwt.hex:ro
    ports:
      - "4000:4000"
      - "13000:13000"
      - "12000:12000/udp"
    command:
      - --datadir=/data
      - --jwt-secret=/root/sepolia/jwt.hex
      - --rpc-host=0.0.0.0
      - --http-host=0.0.0.0
      - --monitoring-host=0.0.0.0
      - --execution-endpoint=http://geth:8551
      - --sepolia
      - --checkpoint-sync-url=https://sepolia.beaconstate.info
      - --genesis-beacon-api-url=https://beaconstate.info
    networks:
      -  blockchain-network

  geth:
    image: ethereum/client-go:stable
    restart: unless-stopped
    volumes:
      - ./data:/root/.ethereum
      - /root/sepolia/jwt.hex:/root/sepolia/jwt.hex:ro
    ports:
      - "8545:8545"
      - "8546:8546"
      - "8551:8551"
      - "30303:30303"
    command: [
      "--sepolia",
      "--syncmode=full",
      "--gcmode=archive",
      "--authrpc.addr=0.0.0.0",
      "--authrpc.port=8551",
      "--authrpc.vhosts=*",
      "--authrpc.jwtsecret=/root/sepolia/jwt.hex",
      "--http",
      "--http.addr=0.0.0.0",
      "--http.port=8545",
      "--http.api=eth,net,engine,admin",
      "--ws",
      "--ws.addr=0.0.0.0",
      "--ws.port=8546",
      "--ws.api=eth,net,web3"
    ]
    networks:
      -  blockchain-network

networks:
  blockchain-network:
    driver: bridge
```

Press "Ctrl + X". Press "y" when prompted and then "Enter".

### Run Archive Node with Ethereum Sepolia

To run your node - enter the below:

```bash
# Run this from within /root/sepolia
docker compose up -d
```

## Interact with Sepolia Archive Node

### Check Logs

#### Check Logs of Geth / Sepolia

```bash
docker compose logs sepolia-geth-1
```

Logs will slightly resemble the image below.

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

#### Check logs of Prysm

```bash
docker logs beacon-node
```

Logs will look similar to the image below.

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

#### Stop Node

```bash
# To stop Geth / Sepolia Archive Node
docker stop sepolia-geth-1

# To stop Prysm (Beacon Node)
docker stop beacon-node
```

## Query Sepolia Archive Node

{% hint style="info" %}
The Ethereum Sepolia Archive Node has a sync time of about 4 days.
{% endhint %}

### Check Sync Status

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_syncing", "params":[], "id":1}' http://localhost:8545

```

When node is finished syncing the response from the above command should resemble the below.

```bash
{"jsonrpc":"2.0","id":1,"result":false}
```

### Check Block Number

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}' http://localhost:8545

# Response should have a different "result" value.
{"jsonrpc":"2.0","id":1,"result":"0x754ee0"}
```


# Fantom


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4c/8t</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 13TB SSD/NVME</td></tr></tbody></table>

## Fantom 👻

Official Docs \
<https://docs.fantom.foundation/node/run-an-api-node#run-transaction-tracing-api-node>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Fantom directory

The first command, `mkdir fantom`, will create a new directory named fantom in the current location. The second command, `cd fantom`, will change your current working directory to the newly created fantom directory. Now you are inside the fantom directory and can start storing docker-compose and related files in it.

```bash
mkdir fantom
cd fantom
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, reth.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    fantom_data: {}
    genesis_data: {}
    traefik_letsencrypt: {}
    

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################            FANTOM ARCHIVE CONTAINER      #######################
###################################################################################### 

  fantom:
    image: kw1k/opera:1.1.2-rc.6
    container_name: fantom
    restart: unless-stopped
    expose:
      - "18545" # RPC
      - "18546" # WS
    ports:
      - "5050:5050" # P2P
    networks:
      - monitor-net
    command:
      --genesis=/genesis/mainnet-5577-full-mpt.g
      --config=/usr/local/bin/config.toml
      --port=5050
      --maxpeers=200
      --datadir=/root/data
      --http
      --http.addr=0.0.0.0
      --http.port=18545
      --http.corsdomain="*"
      --http.vhosts="*"
      --ws
      --ws.addr=0.0.0.0
      --ws.port=18546
      --ws.origins="*"
      --nousb
      --db.preset=pbl-1
      --tracenode
      --http.api=eth,web3,net,ftm,trace
    volumes:
      - fantom_data:/root/data
      - genesis_data:/genesis
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.fantom.loadbalancer.server.port=18545"
      - "traefik.http.routers.fantom.entrypoints=websecure"
      - "traefik.http.routers.fantom.tls.certresolver=myresolver"
      - "traefik.http.routers.fantom.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.fantom.middlewares=ipwhitelist"
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Fantom Node

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

### Monitor Logs

Use `docker logs` to monitor your fantom node. The `-f` flag ensures you are following the log output

```
docker logs fantom -f
```


# Fuse


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

|   CPU  |           OS           |                  RAM                  |     DISK     |
| :----: | :--------------------: | :-----------------------------------: | :----------: |
| 4 vCPU | Debian 12/Ubuntu 22.04 | <p>8GB min</p><p>16GB Recommended</p> | 2.5TB+ (SSD) |

{% hint style="info" %}
*The Fuse archival node has a size of 2.5TB on Septmber 3rd, 2024*
{% endhint %}

### Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config unzip
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Fuse node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545 8546
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Allow P2P Connections

```bash
sudo ufw allow 30303/tcp
sudo ufw allow 30303/udp
```

Enable Firewall

```bash
sudo ufw enable
```

To check the status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Building a Node on Fuse with Nethermind client

{% hint style="success" %}
Since **08.2022** Fuse is moving from OE client to [Nethermind](https://nethermind.io/). To bootstrap Fuse archive node this guide covers the steps on how to build Nethermind from source and configure it to run for Fuse Network
{% endhint %}

### Install .NET SDK

```bash
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt update
sudo apt install -y apt-transport-https
sudo apt update
sudo apt install -y dotnet-sdk-8.0
```

### Download the Latest Nethermind Release Binary <a href="#the-release-binary" id="the-release-binary"></a>

```bash
wget "$(curl -s https://api.github.com/repos/NethermindEth/nethermind/releases/latest \
        | grep "browser_download_url" \
        | grep "linux-x64.zip" \
        | cut -d '"' -f 4)" -O nethermind-latest-linux-x64.zip
```

Use `unzip` to extract downloaded archive

```bash
unzip nethermind-latest-linux-x64.zip
```

### Configuing Nethermind client

#### Increase the maximum number of open files

```bash
sudo bash -c 'echo "nethermind soft nofile 100000" > /etc/security/limits.d/nethermind.conf' 
sudo bash -c 'echo "nethermind hard nofile 100000" >> /etc/security/limits.d/nethermind.conf'
```

#### Create chainspec file for Fuse

```bash
mkdir -p /root/fuse-archive/chainspec

nano /root/fuse-archive/chainspec/fuse.json
```

Copy/Paste the following contents into the file:

```json
{
  "name": "FuseNetwork",
  "engine": {
    "authorityRound": {
      "params": {
        "stepDuration": "5",
        "blockReward": "0x0",
        "blockRewardContractAddress": "0x63D4efeD2e3dA070247bea3073BCaB896dFF6C9B",
        "blockRewardContractTransition": 100,
        "validators": {
          "multi": {
            "0": {
              "list": ["0xd9176e84898a0054680aec3f7c056b200c3d96c3"]
            },
            "100": {
              "safeContract": "0x3014ca10b91cb3D0AD85fEf7A3Cb95BCAc9c0f79"
            }
          }
        }
      }
    }
  },
  "params": {
    "gasLimitBoundDivisor": "0x400",
    "maximumExtraDataSize": "0x20",
    "minGasLimit": "0x1388",
    "networkID": "0x07a",
    "eip155Transition": 0,
    "validateChainIdTransition": 0,
    "eip140Transition": 0,
    "eip211Transition": 0,
    "eip214Transition": 0,
    "eip658Transition": 0,
    "eip150Transition": "0x0",
    "eip160Transition": "0x0",
    "eip161abcTransition": "0x0",
    "eip161dTransition": "0x0",
    "eip98Transition": "0x7fffffffffffff",
    "eip145Transition": "0x38ada7",
    "eip1014Transition": "0x38ada7",
    "eip1052Transition": "0x38ada7",
    "eip1283Transition": "0xd29240",
    "eip1344Transition": "0xd29240",
    "eip1706Transition": "0xd29240",
    "eip1884Transition": "0xd29240",
    "eip2028Transition": "0xd29240",
    "eip2929Transition": "0xd29240",
    "eip2930Transition": "0xd29240",
    "eip1559Transition": "0x1D653E8",
    "eip2565Transition": "0x1D653E8",
    "eip3198Transition": "0x1D653E8",
    "eip3529Transition": "0x1D653E8",
    "eip3541Transition": "0x1D653E8",
    "eip1559BaseFeeMinValueTransition": "0x1D653E8",
    "eip3651TransitionTimestamp": "0x66A78440",
    "eip3855TransitionTimestamp": "0x66A78440",
    "eip3860TransitionTimestamp": "0x66A78440",
    "eip1153TransitionTimestamp": "0x66A78440",
    "eip5656TransitionTimestamp": "0x66A78440",
    "eip6780TransitionTimestamp": "0x66A78440",
    "eip1559BaseFeeMaxChangeDenominator": "0x8",
    "eip1559ElasticityMultiplier": "0x2",
    "eip1559BaseFeeInitialValue": "0x3b9aca00",
    "eip1559BaseFeeMinValue": "0x2540be400",
    "maxCodeSize": 24576,
    "maxCodeSizeTransition": "0x0"
  },
  "genesis": {
    "seal": {
      "authorityRound": {
        "step": "0x0",
        "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
      }
    },
    "difficulty": "0x20000",
    "baseFeePerGas": "0x2540BE400",
    "gasLimit": "0x989680"
  },
  "nodes": [
    "enode://60ca021ca7a60c5fedeb39344d6ef282c6c8574c87bf492dcef7ed8dd9611c5a33da2b286f12eb81554c403718565a749d5028c9bcfc1d5b90b8d105ac04da4b@35.205.73.124:30303",
    "enode://550041c1883866ee537ddf220c0ea84b614bce27e9adb8de85b3b86bd745d7ed9575043a78fabe192f1f0ceee71a343f1d5b35f09e6bb41f24ac69bfe214f414@34.76.228.61:30303"
  ],
  "accounts": {
    "0x0000000000000000000000000000000000000001": {
      "balance": "1",
      "builtin": {
        "name": "ecrecover",
        "pricing": {
          "linear": {
            "base": 3000,
            "word": 0
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000002": {
      "balance": "1",
      "builtin": {
        "name": "sha256",
        "pricing": {
          "linear": {
            "base": 60,
            "word": 12
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000003": {
      "balance": "1",
      "builtin": {
        "name": "ripemd160",
        "pricing": {
          "linear": {
            "base": 600,
            "word": 120
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000004": {
      "balance": "1",
      "builtin": {
        "name": "identity",
        "pricing": {
          "linear": {
            "base": 15,
            "word": 3
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000005": {
      "builtin": {
        "name": "modexp",
        "pricing": {
          "0": {
            "price": {
              "modexp": {
                "divisor": 20
              }
            }
          },
          "0xd29240": {
            "info": "EIP-2565: ModExp Gas Cost.",
            "price": {
              "modexp2565": {}
            }
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000006": {
      "builtin": {
        "name": "alt_bn128_add",
        "pricing": {
          "0": {
            "price": {
              "alt_bn128_const_operations": {
                "price": 500
              }
            }
          },
          "0xd29240": {
            "info": "EIP-1108 Istanbul HF",
            "price": {
              "alt_bn128_const_operations": {
                "price": 150
              }
            }
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000007": {
      "builtin": {
        "name": "alt_bn128_mul",
        "pricing": {
          "0": {
            "price": {
              "alt_bn128_const_operations": {
                "price": 4000
              }
            }
          },
          "0xd29240": {
            "info": "EIP-1108 Istanbul HF",
            "price": {
              "alt_bn128_const_operations": {
                "price": 6000
              }
            }
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000008": {
      "builtin": {
        "name": "alt_bn128_pairing",
        "pricing": {
          "0": {
            "price": {
              "alt_bn128_pairing": {
                "base": 100000,
                "pair": 80000
              }
            }
          },
          "0xd29240": {
            "info": "EIP-1108 Istanbul HF",
            "price": {
              "alt_bn128_pairing": {
                "base": 45000,
                "pair": 34000
              }
            }
          }
        }
      }
    },
    "0x0000000000000000000000000000000000000009": {
      "builtin": {
        "name": "blake2_f",
        "pricing": {
          "0xd29240": {
            "info": "EIP-152 Istanbul HF",
            "price": {
              "blake2_f": {
                "gas_per_round": 1
              }
            }
          }
        }
      }
    },
    "0xd9176e84898a0054680aec3f7c056b200c3d96c3": {
      "balance": "300000000000000000000000000"
    }
  }
}
```

`Ctrl + X and Y` to exit and confirm saving changes to a file

#### Create an empty config file for Fuse

```bash
mkdir -p /root/fuse-archive/config

nano /root/fuse-archive/config/empty.cfg
```

Copy/Paste the following contents into the file:

```json
{
}
```

#### Create Data Directory to store chain data for Fuse blockchain

```bash
mkdir /root/fuse-archive/fuse_data
```

#### Configure systemd Service

Ensure that you grant execute permission to the binary file:

```bash
sudo chmod +x /root/fuse-archive/Nethermind.Runner
```

Create a systemd service file:

```bash
sudo nano /etc/systemd/system/nethermind.service
```

Add the following content:

```bash
[Unit]
Description=Nethermind Node
Documentation=https://docs.nethermind.io
After=network.target

[Service]
User=root
Environment=DOTNET_BUNDLE_EXTRACT_BASE_DIR=/root/fuse-archive/fuse-data/basedir
ExecStart=/root/fuse-archive/Nethermind.Runner \
        --datadir=/root/fuse-archive/fuse-data/datadir/ \
        --config=/root/fuse-archive/config/empty.cfg \
        --Init.DiscoveryEnabled=true \
        --Init.WebSocketsEnabled=true \
        --Init.StoreReceipts=true \
        --Init.ChainSpecPath=/root/fuse-archive/chainspec/fuse.json \
        --Init.BaseDbPath=/root/fuse-archive/fuse-data/basedir \
        --Init.GenesisHash=0x6e778e9491576a28bd06fac93844d8494be1f153e60ba7d29b4b51d991d4f830 \
        --Network.DiscoveryPort=30303 \
        --Network.P2PPort=30303 \
        --Network.LocalIp=0.0.0.0 \
        --Network.ExternalIp=0.0.0.0 \
        --JsonRpc.Enabled=true \
        --JsonRpc.Timeout=20000 \
        --JsonRpc.Host=0.0.0.0 \
        --JsonRpc.Port=9656 \
        --JsonRpc.WebSocketsPort=9756 \
        --JsonRpc.JwtSecretFile=/root/fuse-archive/jwt.hex \
        --Receipt.TxLookupLimit=0 \
        --Metrics.NodeName=fuse_archive \
        --Bloom.IndexLevelBucketSizes="[ 16, 16, 16, 16 ]" \
        --Pruning.Mode=none \
        --Mining.MinGasPrice=1000000000 \
        --Merge.Enabled=false \
        --TraceStore.Enabled=true \
        --TraceStore.BlocksToKeep=0 \
        --TraceStore.TraceTypes=Trace,Rewards \
        --Sync.FastSync=false
Restart=on-failure
LimitNOFILE=1000000
KillSignal=SIGKILL
[Install]
WantedBy=multi-user.target
```

`Ctrl + X and Y` to exit and confirm saving changes to a file

#### Reload systemd and Enable the Service

```bash
systemctl enable nethermind #enable nethermind service at system startup

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start nethermind #start nethermind

sudo systemctl stop nethermind #stop nethermind
```

{% hint style="info" %}
To check or modify `nethermind.service` parameters simply run

`sudo nano /etc/systemd/system/nethermind.service`

Ctrl+X and Y to save changes
{% endhint %}

### View Logs for Debugging

```bash
journalctl -f -u nethermind  #follow logs of nethermind service
```

*The logs should look like below and indicate that your node syncs and is expected to reach a chainhead in \~2-3 days*

{% hint style="success" %}
`28 Jun 01:13:08 | Finalizing validators for transition signalled within contract at block 473632 after block 473633 (0xba9913...ff8838).`

`28 Jun 01:13:08 | Applying validator set change before block 473634 (0xae6e4c...881217).`

`28 Jun 01:13:08 | Downloaded 473,680 / 30,284,955 ( 1.56 %) | current 102 Blk/s | total 156 Blk/s`

`28 Jun 01:13:09 | Processed 473428... 473681 | 193.72 ms | slot 2,151 ms |⛽ Gas gwei: 0.00 .. 0.00 (0.00) .. 0.00`

`28 Jun 01:13:09 | - Blocks 254 0.14 MGas | 6 txs | calls 1,835 ( 0) | sload 4,835 | sstore 735 | create 0`

`28 Jun 01:13:09 | - Block throughput 0.74 MGas/s | 30.97 t/s | 1311.17 Blk/s | recover 0 | process 7`

`28 Jun 01:13:09 | Signal for transition within contract at block 473732 (0x89197a...464a90). New list of 2 : [0xc736793ff31e04807cbf20b39d50ac7a04a4bdad, 0xd9176e84898a0054680aec3f7c056b200c3d96c3].`
{% endhint %}

## References

{% embed url="<https://docs.nethermind.io/get-started/installing-nethermind/>" %}

{% embed url="<https://github.com/fuseio/fuse-network/blob/master/README.md#archival-node>" %}

{% embed url="<https://docs.fuse.io/developers/run-or-access-fuse-nodes>" %}

{% embed url="<https://github.com/fuseio/nethermind-client/tree/production/src/Nethermind/Nethermind.Runner/configs>" %}


# Gnosis


# Erigon


# Baremetal

Authors: \[Vince | Nodeify, Payne | Stake🦑Squid]

## System Requirements

<table><thead><tr><th align="center">CPU</th><th width="147" align="center">OS</th><th width="119" align="center">RAM</th><th align="center">Storage</th></tr></thead><tbody><tr><td align="center">6 Cores / 12 Threads</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 3 TiB NVMe SSD</td></tr></tbody></table>

## Erigon 🦦

Official Docs <https://erigon.gitbook.io/>

### Pre-requisites

Update, upgrade, and clean the system, and then install essential development tools (build-essential), firewall management (ufw), and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt-get install -y build-essential ufw git cmake
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow P2P connections with Erigon, Consensus peers and SSH

```bash
sudo ufw allow 30303
sudo ufw allow 9001
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Execution Client

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9656
```

{% hint style="danger" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```
sudo ufw enable
```

### Install go

Download the Go programming language distribution archive, extracts it to the "/usr/local" directory, and then removes the downloaded archive, effectively installing Go version 1.20.6 on the system.

```bash
wget https://go.dev/dl/go1.20.6.linux-amd64.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go1.20.6.linux-amd64.tar.gz && \
rm go1.20.6.linux-amd64.tar.gz
```

Please add the Go executable path to your system's `PATH` environment variable, and then test to ensure that Go is working correctly.

```bash
echo "export PATH="$PATH:/root/.foundry/bin:/usr/local/go/bin"" >> /root/.bashrc
source /root/.bashrc
go version #test
```

### Create Erigon Directory

Create a new directory named erigon within the "/root/.local/share" directory, providing a location for storing data related to Erigon.

```bash
mkdir /root/.local/share/erigon
```

### Generate JWT token

Generate a 32-byte random hexadecimal value using OpenSSL, removes any newline characters, and then save the result into the file "jwt.hex" located in the "/root/.local/share/erigon/" directory.

```bash
openssl rand -hex 32 | sudo tee /root/.local/share/erigon/jwt.hex > /dev/null
```

### Build Erigon

Clone the Erigon repository from GitHub, including its submodules, changes the current directory to the Erigon directory, checks out the latest release tag, and then compile the project using the "make" build system.

```bash
git clone --recurse-submodules https://github.com/ledgerwatch/erigon.git
cd erigon
git checkout <latest release tag>
make
```

### Configure Erigon

Append a systemd service configuration for the Erigon Gnosis Mainnet Service to the "/etc/systemd/system/erigon.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Erigon Gnosis Mainnet Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/.local/share/erigon/
ExecStart=/root/erigon/build/bin/erigon \
        --datadir=/root/.local/share/erigon/datadir \
        --ethash.dagdir=/root/.local/share/erigon/datadir/ethash \
        --chain gnosis \
        --authrpc.jwtsecret=/root/.local/share/erigon/jwt.hex \
        --authrpc.port=9663 \
        --http \
        --http.addr=0.0.0.0 \
        --http.port=9656 \
        --http.compression \
        --http.vhosts=* \
        --http.corsdomain=* \
        --http.api=eth,debug,net,trace,web3,erigon \
        --private.api.addr=0.0.0.0:9092 \
        --ws --ws.compression \
        --metrics --metrics.addr=0.0.0.0 --metrics.port=6060 \
        --torrent.download.rate 1024mb \
        --rpc.returndata.limit=1000000
KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/erigon.service
```

### Run Erigon

Reload the systemd manager configuration, start the Erigon service, and enable it to start automatically on system boot, ensuring that the Erigon Gnosis Mainnet Service is active and will be automatically started upon system startup.

```bash
sudo systemctl daemon-reload
sudo systemctl start erigon
sudo systemctl enable erigon
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Erigon service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu erigon
```

## Consensus Clients

{% hint style="danger" %}
For Erigon to operate, it requires the use of a consensus client. It is crucial to consider client diversity while doing so. -> <https://clientdiversity.org/>
{% endhint %}

## Lodestar 🤠

Official Docs <https://chainsafe.github.io/lodestar/>

### Install yarn and nodeJS

```bash
#yarn
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update -y && sudo apt install yarn -y
#nodeJS
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
```

### Create Lodestar Directory

Create a new directory named lodestar within the "/root/.local/share" directory, providing a location for storing data related to Lodestar.

```bash
mkdir /root/.local/share/lodestar
```

### Build Lodestar

Clone the lodestar repository from GitHub, navigate to the lodestar directory, switch to the stable branch, and then build the project with yarn.

```bash
git clone https://github.com/chainsafe/lodestar.git
cd lodestar
git checkout stable
yarn install
yarn run build
```

### Configure Lodestar

Append a systemd service configuration for the Lodestar Gnosis Service to the "/etc/systemd/system/lodestar.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Lodestar Gnosis Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/lodestar/
ExecStart=/root/lodestar/lodestar beacon \
  --datadir=/root/.local/share/lodestar \
  --network=gnosis \
  --rest \
  --rest.port=6061 \
  --metrics \
  --metrics.port=6062 \
  --port 9001 \
  --checkpointSyncUrl=https://checkpoint.gnosischain.com/ \
  --execution.urls=http://127.0.0.1:9663 \
  --jwt-secret=/root/.local/share/erigon/jwt.hex

KillSignal=SIGHUP  

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/lodestar.service
```

### Run Lodestar

Reload the systemd manager configuration, restart the Lodestar and Erigon services, and enable the Lodestar service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Lodestar service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart lodestar erigon
sudo systemctl enable lodestar
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Lodestar service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu lodestar
```

## Lighthouse 🕯️

Official Docs <https://lighthouse-book.sigmaprime.io/>

### Install rust

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

Please add the Rust executable path to your system's `PATH` environment variable, and then test to ensure that Rust is working correctly.

```bash
echo "export PATH="$PATH:/root/.local/bin:/root/.cargo/env"" >> /root/.bashrc
source /root/.bashrc
cargo --version #test
```

### Create Lighthouse Directory

Create a new directory named "lighthouse" within the "/root/.local/share" directory, providing a location for storing data related to Lighthouse.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/lighthouse
</strong></code></pre>

### Build Lighthouse

Clone the lighthouse repository from GitHub, navigate to the lighthouse directory, switch to the stable branch, and then build the project with the gnosis feature enabled using the "make" build system.

```bash
git clone https://github.com/sigp/lighthouse.git
cd lighthouse
git checkout stable
FEATURES=gnosis make
```

### Configure Lighthouse

Append a systemd service configuration for the Lighthouse Gnosis Service to the "/etc/systemd/system/lighthouse.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=LightHouse Gnosis Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/lighthouse/
ExecStart=/root/lighthouse/target/release/lighthouse bn \
        --datadir=/root/.local/share/lighthouse \
        --network=gnosis \
        --http \
        --http-port=6061 \
        --metrics \
        --metrics-port=6062 \
        --port=9001 \
        --checkpoint-sync-url=https://checkpoint.gnosischain.com/ \
        --execution-endpoint=http://127.0.0.1:9663 \
        --execution-jwt=/root/.local/share/erigon/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/lighthouse.service
```

### Run Lighthouse

Reload the systemd manager configuration, restart the Lighthouse and Erigon services, and enable the Lighthouse service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Lighthouse service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart lighthouse erigon
sudo systemctl enable lighthouse
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Lighthouse service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu lighthouse
```

## Nimbus ☁️

Official Docs <https://nimbus.guide/index.html>

### Install cmake

```bash
sudo apt -y install cmake
```

### Create Nimbus Directory

Create a new directory named nimbus within the "/root/.local/share" directory, providing a location for storing data related to Nimbus.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/nimbus
</strong></code></pre>

### Build Nimbus

Clone the Nimbus repository from GitHub, navigate to the nimbus directory, switch to the latest stable release, and then build the project with `make`

```bash
git clone https://github.com/status-im/nimbus-eth2
cd nimbus-eth2
git checkout stable
make -j4 nimbus_beacon_node
```

{% hint style="info" %}
You can increase `-j4` (`-j32`) with higher or lower integer depending on your host machine ram to decrease build time. Omit `-j4` on systems with 4GB of memory or less.
{% endhint %}

### Alternatively, extract the binary from the precompiled docker images:

```bash
mkdir -p /root/nimbus-eth2/build/
sudo docker cp $(sudo docker run -it -d ghcr.io/gnosischain/gnosis-nimbus-eth2:latest):/home/user/nimbus_beacon_node /root/nimbus-eth2/build/
```

### Configure Nimbus

Append a systemd service configuration for the Nimbus Gnosis Service to the "/etc/systemd/system/nimbus.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Nimbus Gnosis Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/nimbus-eth2/
ExecStart=/root/nimbus-eth2/build/nimbus_beacon_node trustedNodeSync \
        --data-dir=/root/.local/share/nimbus \
        --network=gnosis \
        --rest=true \
        --rest-port=6061 \
        --metrics \
        --metrics-port=6062 \
        --tcp-port=9001 --udp-port=9001 \
        --trusted-node-url=https://checkpoint.gnosischain.com/ \
        --web3-url=http://127.0.0.1:9663 \
        --jwt-secret=/root/.local/share/erigon/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/nimbus.service
```

### Run Nimbus

Reload the systemd manager configuration, restart the Nimbus and Erigon services, and enable the Nimbus service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Nimbus service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart nimbus erigon
sudo systemctl enable nimbus
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Nimbus service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu nimbus
```

## Teku 🍷

Official Docs <https://docs.teku.consensys.net/get-started>

### Install the required Java runtime

```bash
sudo apt -y install openjdk-17-jre
```

### Create Teku Directory

Create a new directory named teku within the "/root/.local/share" directory, providing a location for storing data related to Teku.

<pre class="language-bash"><code class="lang-bash"><strong>mkdir /root/.local/share/teku
</strong></code></pre>

### Build Teku

Clone the teku repository from GitHub, navigate to the teku directory, switch to the latest release, and then build the project with with the Gradle wrapper `gradlew`, as follows.

```bash
git clone https://github.com/Consensys/teku.git
cd teku
git checkout <latest release tag>
./gradlew distTar installDist
```

### Configure Teku

Append a systemd service configuration for the Teku Gnosis Service to the "/etc/systemd/system/teku.service" file, specifying its description, dependencies, and executable parameters for proper execution and monitoring.

```bash
sudo echo "[Unit]
Description=Teku Gnosis Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
Environment="JAVA_OPTS=-Xmx5g"
Environment="TEKU_OPTS=-XX:-HeapDumpOnOutOfMemoryError"
WorkingDirectory=/root/teku/
ExecStart=/root/teku/build/install/teku/bin/teku \
        --network=gnosis \
        --data-path=/root/.local/share/teku \
        --rest-api-enabled=true \
        --rest-api-port=6061 \
        --metrics-enabled=true \
        --metrics-port=6062 \
        --p2p-port=9001 \
        --initial-state=https://checkpoint.gnosischain.com \
        --ee-endpoint=http://127.0.0.1:9663 \
        --ee-jwt-secret-file=/root/.local/share/erigon/jwt.hex

KillSignal=SIGHUP                                                                                                                                                                                          

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/teku.service
```

### Run Teku

Reload the systemd manager configuration, restart the Teku and Erigon services, and enable the Teku service to start automatically on system boot. This ensures that both services are running with the latest configuration and that the Teku service will be automatically started upon system startup.

```bash
systemctl daemon-reload
systemctl restart teku erigon
sudo systemctl enable teku
```

### Monitor Logs

Use journalctl to display real-time log messages and continuously follow the log output of the Teku service, allowing you to monitor its activity and troubleshoot any issues as they occur.

```bash
sudo journalctl -fu teku
```

## Test Erigon RPC 🧪

{% hint style="danger" %}
Erigon and Consensus client must be synced before testing.
{% endhint %}

{% code overflow="wrap" %}

```bash
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x1", true],"id":1}' http://localhost:9656
```

{% endcode %}

{% hint style="warning" %}
This should be your result.
{% endhint %}

{% code overflow="wrap" %}

```bash
{"jsonrpc":"2.0","result":{"author":"0xcace5b3c29211740e595850e80478416ee77ca21","difficulty":"0xffffffffffffffffffffffffeda7455a","extraData":"0xde830201018f5061726974792d457468657265756d86312e32392e30826c69","gasLimit":"0x989680","gasUsed":"0x0","hash":"0x96059ccf6d5b78b7f30795cd9661f77a117b94ae458020e9010d5a9968376be4","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xcace5b3c29211740e595850e80478416ee77ca21","number":"0x1","parentHash":"0x4f1dd23188aab3a76b463e4af801b52b1248ef073c648cbdc4c9333d3da79756","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","signature":"0xc35e9f8ac05c69d8c36af2cb8b7bb3beda5945e8367fec758c459d32f9ddc183206bad888ebd7addaa6e3f00593100a628c5e86ca80ebe48d4fc831dd36f825d01","size":"0x249","stateRoot":"0x40cf4430ecaa733787d1a65154a3b9efb560c95d9e324a23b97f0609b539133b","step":307804837,"totalDifficulty":"0xffffffffffffffffffffffffeda9455a","timestamp":"0x5bbba539","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]},"id":1}
```

{% endcode %}


# Iotex


# Baremetal

Author: \[ jLeopoldA ]

## System Requirements

| CPU                    | OS       | RAM   | DISK                |
| ---------------------- | -------- | ----- | ------------------- |
| Debian 12/Ubuntu 22.04 | 8+ Cores | 32GB+ | 10TB+ (SSD or NVMe) |

{% hint style="info" %}
The Iotex Archive Node has a size of 5.5TB as of 3/5/2025
{% endhint %}

{% hint style="warning" %}
The Iotex Archive Node requires an L1 Ethereum RPC
{% endhint %}

## Pre-Requisites

#### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
sudo apt install -y git gcc make --fix-missing
```

#### Install GO

```bash
curl -LO https://go.dev/dl/go1.21.8.linux-amd64.tar.gz
sudo tar xzf go1.21.8.linux-amd64.tar.gz -C /usr/local && rm go1.21.8.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc

# Check Installation
go version
```

## Firewall Configuration

#### Set Explicit Firewall Rules

```bash
sudo ufw default deny incoming 
sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow Connections for Iotex

```bash
sudo ufw allow 4689
sudo ufw allow 8080
sudo ufw allow 14014
sudo ufw allow 16014
sudo ufw allow 15014
```

#### Enable Firewall Rules

```bash
sudo ufw enable
```

#### Check Status of Firewall Rules (UFW)

```bash
sudo ufw status verbose
```

## Set up Iotex Configuration and Data

#### Create Directories

```bash
# Make Directory for Iotex Server and Data
mkdir -p /var/lib/iotex
mkdir -p /var/lib/iotex/etc
mkdir -p /var/lib/iotex/data
mkdir -p /var/lib/iotex/log

# Make Directory for Configuration
mkdir -p /root/configuration
```

#### Download trie.db.patch & poll.db

```bash
curl https://raw.githubusercontent.com/iotexproject/iotex-bootstrap/master/trie.db.patch > /var/lib/iotex/data/trie.db.patch
curl https://storage.googleapis.com/blockchain-golden/poll.mainnet.db > /var/lib/iotex/data/poll.db
```

### Create Configuration

#### Download genesis.yaml

```bash
curl https://raw.githubusercontent.com/iotexproject/iotex-bootstrap/master/genesis_mainnet.yaml > /root/configuration/genesis.yaml
```

#### Create general\_config.yaml

This portion requires an L1\_RPC within the configuration.  Specifically, the object route of chain > committee > gravityChainAPIs

```bash
echo "
---
network:
  # externalHost: SET YOUR EXTERNAL IP HERE (e.g., 12.34.56.78)
  externalPort: 4689
  bootstrapNodes:
    - /dns4/bootnode-0.mainnet.iotex.one/tcp/4689/p2p/12D3KooWPfQDF8ASjd4r7jS9e7F1wn6zod7Mf4ERr8etoY6ctQp5
    - /dns4/bootnode-1.mainnet.iotex.one/tcp/4689/p2p/12D3KooWN4TQ1CWRA7yvJdQCdti1qARLXXu2UEHJfycn3XbnAnRh
    - /dns4/bootnode-2.mainnet.iotex.one/tcp/4689/p2p/12D3KooWSiktocuUke16bPoW9zrLawEBaEc1UriaPRwm82xbr2BQ
    - /dns4/bootnode-3.mainnet.iotex.one/tcp/4689/p2p/12D3KooWEsmwaorbZX3HRCnhkMPjMAHzwu3om1pdGrtVm2QaM35n
    - /dns4/bootnode-4.mainnet.iotex.one/tcp/4689/p2p/12D3KooWHRcgNim4Nau73EEu7aKJZRZPZ21vQ7BE3fG6vENXkduB
    - /dns4/bootnode-5.mainnet.iotex.one/tcp/4689/p2p/12D3KooWGeHkVDQQFxXpTX1WpPhuuuWYTxPYDUTmaLWWSYx5rmUY

chain:
  # If you are a delegate, make sure producerPrivKey is the key for the
  # operator address you have registered.
  # producerPrivKey: SET YOUR PRIVATE KEY HERE (e.g.,
  # 96f0aa5e8523d6a28dc35c927274be4e931e74eaa720b418735debfcbfe712b8)
  enableStakingIndexer: true
  chainDBPath: "/var/lib/iotex/data/chain.db"
  trieDBPatchFile: "/var/lib/iotex/data/trie.db.patch"
  trieDBPath: "/var/lib/iotex/data/archive.db"
  stakingPatchDir: "/var/lib/iotex/data"
  indexDBPath: "/var/lib/iotex/data/index.db"
  blobStoreDBPath: "/var/lib/iotex/data/blob.db"
  bloomfilterIndexDBPath: "/var/lib/iotex/data/bloomfilter.index.db"
  candidateIndexDBPath: "/var/lib/iotex/data/candidate.index.db"
  stakingIndexDBPath: "/var/lib/iotex/data/staking.index.db"
  contractStakingIndexDBPath: "/var/lib/iotex/data/contractstaking.index.db"
  enableArchiveMode: true
  maxCacheSize: 1000
  committee:
    gravityChainAPIs:
      # Please change the Infura key to your key (e.g.,
      # https://mainnet.infura.io/v3/YOUR_KEY)
       - {YOUR_L1_RPC_HERE}
    numOfRetries: 20
    paginationSize: 255
    cacheSize: 1000
  gravityChainDB:
    dbPath: "/var/lib/iotex/data/poll.db"
    numRetries: 8

actPool:
  minGasPrice: "1000000000000"
  store:
    datadir: "/var/lib/iotex/data/actpool.cache"

api:
  gasStation:
    defaultGas: 1000000000000

consensus:
  scheme: ROLLDPOS
  rollDPoS:
    fsm:
      unmatchedEventTTL: 3s
      unmatchedEventInterval: 100ms
      acceptBlockTTL: 4s
      acceptProposalEndorsementTTL: 2s
      acceptLockEndorsementTTL: 2s
    delay: 10s
    consensusDBPath: "/var/lib/iotex/data/consensus.db"

blockSync:
  interval: 2s
  bufferSize: 400
  maxRepeat: 3
  repeatDecayStep: 3

log:
  zap:
    level: info
    encoding: json
    disableStacktrace: true
    outputPaths: ["stderr", "stdout"]
    errorOutputPaths: ["stderr"]
  stderrRedirectFile: /var/lib/iotex/log/s.log
  stdLogRedirect: true
" > /root/configuration/general_config.yaml
```

### Download Necessary Data Files

#### Download iotex-data

```bash
cd /var/lib/iotex

# Multiple Data Files (Block, Blob Storage, Indexing Files)
nohup curl -LO https://storage.googleapis.com/blockchain-golden/archive/iotex-data.tar.gz & disown

# Check the status of download
tail -f /var/lib/iotex/nohup.out

# When done downloading - unpack.
tar -xzf iotex-data.tar.gz
```

#### Download State Database

```bash
cd /var/lib/iotex/data

# Download State / Address Database
nohup curl -LO https://storage.googleapis.com/blockchain-golden/archive/archive.db & disown

# The State Database download will take a long time as it is uncompressed
# Check the status of State Database download
tail -f /var/lib/iotex/data/nohup.out
```

{% hint style="warning" %}
Wait for your data to finish downloading before proceeding to the next step.
{% endhint %}

## Set up Iotex Chain

#### Clone Repository and Build Binary

```bash
# Clone the Repository
cd /root
git clone https://github.com/iotexproject/iotex-core.git
cd iotex-core

# Checkout the Archive node branch
git checkout origin/archive

# Build binary
make build

# Copy Server
cp ./bin/server /var/lib/iotex/server
```

### Set up Iotex as a System Service

#### Create System Service File

```bash
echo "[Unit]
Description=Iotex Node
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/var/lib/iotex
ExecStart=/var/lib/iotex/server \
	-config-path=/root/configuration/general_config.yaml \
	-genesis-path=/root/configuration/genesis.yaml 
	-plugin=gateway &
KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/iotex.service
```

#### Start System Service

```bash
sudo systemctl daemon-reload # Reload SystemCtl
sudo systemctl start iotex.service # Start Service
sudo systemctl stop iotex.service # Stop Service
sudo systemctl status iotex.service # Check status
```

## Query Node

#### Check Logs of Node

````bash
journalctl -fu iotex.service -o cat

# The response should resemble the below
```
{"level":"info","ts":"2025-02-18T18:34:18.829+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734123}
{"level":"info","ts":"2025-02-18T18:34:18.949+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734124}
{"level":"info","ts":"2025-02-18T18:34:19.078+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734125}
{"level":"info","ts":"2025-02-18T18:34:19.156+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734126}
{"level":"info","ts":"2025-02-18T18:34:19.305+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734127}
{"level":"info","ts":"2025-02-18T18:34:19.430+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734128}
{"level":"info","ts":"2025-02-18T18:34:19.641+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734129}
{"level":"info","ts":"2025-02-18T18:34:20.047+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734130}
{"level":"info","ts":"2025-02-18T18:34:20.157+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734131}
{"level":"info","ts":"2025-02-18T18:34:20.222+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734132}
{"level":"info","ts":"2025-02-18T18:34:20.312+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734133}
{"level":"info","ts":"2025-02-18T18:34:20.904+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734134}
{"level":"info","ts":"2025-02-18T18:34:20.992+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734135}
{"level":"info","ts":"2025-02-18T18:34:21.120+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734136}
{"level":"info","ts":"2025-02-18T18:34:21.252+0100","caller":"chainservice/builder.go:628","msg":"Successfully committed block.","ioAddr":"io1p2xu7xve7nqp85rvyrmqgy9yd3pjuy2xe7ejtr","height":33734137}
```
````

#### Check Sync Status

```bash
curl -H "Content-Type: application/json" -X POST --data \
'{"jsonrpc":"2.0", "method":"eth_syncing", "params":[], "id":1}' \
http://localhost:15014
```

#### Check Block Number

```bash
curl -H "Content-Type: application/json" -X POST --data \
'{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}' \
http://localhost:15014

# Response should look similar to the below
{"jsonrpc":"2.0","id":1,"result":"0x202c35d"}
```

### References <a href="#references" id="references"></a>

{% embed url="<https://github.com/iotexproject/iotex-bootstrap/blob/master/archive-node.md>" %}


# Linea


# Baremetal

Authors: \[man4ela | catapulta.eth]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU                      | OS           | RAM       | DISK   |
| ------------------------ | ------------ | --------- | ------ |
| A fast CPU with 4+ cores | Ubuntu 22.04 | 16GB+ RAM | 2.5TB+ |

{% hint style="info" %}
The Linea archive node was 2.5 TB on September 11.2024
{% endhint %}

## 🔲 Linea

* [Official Docs](https://docs.linea.build/build-on-linea/run-a-node#step-3-1)

## Pre-Requisites

<pre class="language-bash"><code class="lang-bash">sudo apt update -y &#x26;&#x26; sudo apt upgrade -y &#x26;&#x26; sudo apt autoremove -y

<strong>sudo apt install -y build-essential bsdmainutils aria2 dtrx screen clang cmake curl httpie jq nano wget
</strong>
</code></pre>

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Linea Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

<pre class="language-bash"><code class="lang-bash">#Download the Go programming language distribution archive

<strong>wget https://golang.org/dl/go1.21.6.linux-amd64.tar.gz
</strong><strong>
</strong>#Extract it to the /usr/local directory and install Go v1.21.6 on the system

sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz
<strong>
</strong><strong>#add the Go executable path to your system's PATH environment variable, 
</strong><strong>
</strong><strong>echo 'export PATH=/usr/local/go/bin:$PATH' >> ~/.bashrc
</strong>
source ~/.bashrc

#test to ensure that Go is working correctly

go version
</code></pre>

### Setup the Geth client to run Linea

<pre class="language-bash"><code class="lang-bash">git clone https://github.com/ethereum/go-ethereum.git

cd go-ethereum

#Reportedly most stable version to run Linea node 1.13.4-stable-3f907d6a

git checkout v1.13.15
make geth

cd

#Create directory for database

mkdir linea-datadir

cd linea-datadir

#Download Genesis file

wget https://docs.linea.build/files/geth/mainnet/genesis.json

#Bootstrap the node:

cd /root/go-ethereum

<strong>./build/bin/geth --datadir /root/linea-datadir/ init /root/linea-datadir/genesis.json
</strong></code></pre>

### Create service to run Linea Node

<pre class="language-bash"><code class="lang-bash"><strong>sudo echo "[Unit]
</strong>Description=Linea Node
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/go-ethereum
ExecStart=/root/go-ethereum/build/bin/geth \
--datadir /root/linea-datadir \
--networkid 59144 \
--rpc.allow-unprotected-txs \
--txpool.accountqueue 50000 \
--txpool.globalqueue 50000 \
--txpool.globalslots 50000 \
--txpool.pricelimit 1000000 \
--txpool.pricebump 1 \
--txpool.nolocals \
--http --http.addr '0.0.0.0' --http.port 8545 --http.corsdomain '*' --http.api 'web3,eth,txpool,net' --http.vhosts='*' \
--ws --ws.addr '0.0.0.0' --ws.port 8545 --ws.origins '*' --ws.api 'web3,eth,txpool,net' \
--bootnodes "enode://069800db9e6e0ec9cadca670994ef1aea2cfd3d88133e63ecadbc1cdbd1a5847b09838ee08d8b5f02a9c32ee13abeb4d4104bb5514e5322c9d7ee19f41ff3e51@3.132.73.210:31002,enode://a8e03a71eab12ec4b47bb6e19169d8e4dc7a58373a2476969bbe463f2dded6003037fa4dd5f71e15027f7fc8d7340956fbbefed67ddd116ac19a7f74da034b61@3.132.73.210:31003,enode://97706526cf79df9d930003644f9156805f6c8bd964fc79e083444f7014ce10c9bdd2c5049e63b58040dca1d4c82ebef970822198cf0714de830cff4111534ff1@18.223.198.165:31004,enode://24e1c654a801975a96b7f54ebd7452ab15777fc635c1db25bdbd4425fdb04e7f4768e9e838a87ab724320a765e41631d5d37758c933ad0e8668693558125c8aa@18.223.198.165:31000,enode://27010891d960f73d272a553f72b6336c6698db3ade98d631f09c764e57674a797be5ebc6829ddbb65ab564f439ebc75215d20aa98b6f351d12ea623e7d139ac3@3.132.73.210:31001,enode://228e1b8a4931e46f383e30721dac21fb8fb4e5e1b32c870e13b25478c82db3dc1cd9e7ceb93d302a766466b55638cc9c5cbfc43aa48fa41ced19baf365951f76@3.1.142.64:31002,enode://c22eb0d40fc3ad5ea710aeddea906567778166bfe18c157955e8c39b23a46c45db18a0fa2ba07f2b64c81178a8c796aec2a29151533920ead06fcdfc6d8d03c6@47.128.192.57:31004,enode://8ce733abe39fd7ae0a278b9893f85c1193c611a3886168690dd843435460f22cc4d61f9e8d0ace7f5905836a665319a31cccdaacdada2acc69972c382ecce7db@3.1.142.64:31003,enode://b7c1b2bed65a855f7a2104aac9a14674dfdf018fdac763415b373b29ce18cdb81d36328ba4e5c9f12629f3a50c3e8f9ee048f22dbdbe93a82813da89c6b81334@51.20.235.126:31004,enode://95270e0550848a72fb141cf27f1c4ea10714edde365b411dc0fa06c81c0f282ce155eb9fa472b6b8bb9ee98395eeaf4c5a7b02a01fe58b37ea98ba152eda4c37@13.50.94.193:31000,enode://72013391755f24f08567b932feeeec4c893c06e0b1fb480890c83bf87fd277ad86a5ab9cb586db9ae9970371a2f8cb0c96f6c9f69045abca0fb801db7f047138@51.20.235.126:31001" \
--syncmode full \
--metrics \
--metrics.addr '0.0.0.0' \
--verbosity 3 \
--gcmode archive
KillSignal=SIGHUP

[Install]
WantedBy=multi-user.target" >> /etc/systemd/system/linea-node.service
</code></pre>

{% hint style="info" %}
To check or modify linea-node.service parameters simply run&#x20;

`sudo nano /etc/systemd/system/linea-node.service`

Ctrl+X and Y to save changes
{% endhint %}

List of actual bootnodes can be found here <https://docs.linea.build/developers/guides/run-a-node/enodes>

### Run Linea

```bash
sudo systemctl daemon-reload
sudo systemctl start linea-node
sudo systemctl enable linea-node
```

## Monitor logs

```bash
sudo journalctl -fu linea-node
```

## References

[Run A Linea Node](https://docs.linea.build/build-on-linea/run-a-node#step-3-1)


# Docker

Author: \[man4ela | catapulta.eth]&#x20;

*Last updated at date: 15 May 2024*

#### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU                      | OS           | RAM   | DISK     |
| ------------------------ | ------------ | ----- | -------- |
| A fast CPU with 4+ cores | Ubuntu 22.04 | 16GB+ | >= 1.5TB |

{% hint style="info" %}
*Note: The Linea archive node consumes 1.5 TB of space on May 14.2024*
{% endhint %}

## 🔲 Linea

* [Official Docs](https://docs.linea.build/build-on-linea/run-a-node#step-3-1)

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Enable Firewall

```bash
sudo ufw enable
```

## Setting up a domain name to access RPC

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://youtu.be/QcNBLSSn8Vg>" %}

### Create Linea directory

The first command, `mkdir Linea`, will create a new directory named Linea in the current location. The second command, `cd Linea`, will change your current working directory to the newly created base directory. Now you are inside the base directory and can start storing docker-compose and related files in it.

```bash
mkdir Linea
cd Linea
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain should be something like rpc.mywebsite.com, e.g. linea.infradao.org
WHITELIST={YOUR_REMOTE_MACHINE_IP} #the server's IP itself and comma separated list of IP's allowed to connect to RPC (e.g. Indexer)
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

#### Make configuration directory

```bash
mkdir config

cd config
```

#### Download genesis.json

```bash
curl -LO https://docs.linea.build/files/geth/mainnet/genesis.json
```

### Create docker-compose.yml

*Return to Linea directory*

```bash
cd ~/linea
```

*Create and paste the following into the docker-compose.yml*

```bash
sudo nano docker-compose.yml
```

```bash
version: '3.9'

networks:
  monitor-net:
    driver: bridge

volumes:
  traefik_letsencrypt: {}
  linea-mainnet: {}

services:

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=${EMAIL}"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=${WHITELIST}"

  init:
    image: ethereum/client-go:v1.13.4
    container_name: linea-init
    command:
      - init
      - /genesis.json
    volumes:
      - ./config/genesis.json:/genesis.json:ro
      - linea-mainnet:/root/.ethereum

  node:
    image: ethereum/client-go:v1.13.4
    container_name: linea-mainnet
    restart: unless-stopped
    depends_on:
      init:
        condition: service_completed_successfully
    command:
      - --networkid=59144
      - --gcmode=archive
      - --syncmode=full
      - --rpc.allow-unprotected-txs
      - --txpool.accountqueue=50000
      - --txpool.globalqueue=50000
      - --txpool.globalslots=50000
      - --txpool.pricelimit=1000000
      - --txpool.pricebump=1
      - --txpool.nolocals
      - --http
      - --http.addr=0.0.0.0
      - --http.port=8545
      - --http.corsdomain=*
      - --http.api=admin,web3,eth,txpool,net
      - --http.vhosts=*
      - --ws
      - --ws.addr=0.0.0.0
      - --ws.port=8546
      - --ws.origins=*
      - --ws.api=web3,eth,txpool,net
      - --metrics
      - --metrics.addr=0.0.0.0
      - --metrics.port=6060
      - --bootnodes=enode://ca2f06aa93728e2883ff02b0c2076329e475fe667a48035b4f77711ea41a73cf6cb2ff232804c49538ad77794185d83295b57ddd2be79eefc50a9dd5c48bbb2e@3.23.106.165:30303,enode://eef91d714494a1ceb6e06e5ce96fe5d7d25d3701b2d2e68c042b33d5fa0e4bf134116e06947b3f40b0f22db08f104504dd2e5c790d8bcbb6bfb1b7f4f85313ec@3.133.179.213:30303,enode://cfd472842582c422c7c98b0f2d04c6bf21d1afb2c767f72b032f7ea89c03a7abdaf4855b7cb2dc9ae7509836064ba8d817572cf7421ba106ac87857836fa1d1b@3.145.12.13:30303
      - --verbosity=3
    ports:
      - "30303:30303"
      - "30303:30303/udp"
      - "8545:8545"
      - "8546:8546"
      - "6060:6060"
    volumes:
      - ./config/genesis.json:/genesis.json:ro
      - linea-mainnet:/root/.ethereum
    networks:
      - monitor-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.linea-stripprefix.stripprefix.prefixes=/linea-mainnet"
      - "traefik.http.routers.linea.service=linea"
      - "traefik.http.services.linea.loadbalancer.server.port=8545"
      - "traefik.http.routers.linea.entrypoints=websecure"
      - "traefik.http.routers.linea.tls.certresolver=myresolver"
      - "traefik.http.routers.linea.rule=Host(`${DOMAIN}`)"
      - "traefik.http.routers.linea.middlewares=ipwhitelist"

```

{% hint style="info" %}
Note: Bootnodes need to be updated from time to time. Actual bootnodes can be found here <https://docs.linea.build/developers/guides/run-a-node/enodes>
{% endhint %}

### Run Linea Node

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

### Monitor Logs

Use `docker logs` to monitor your Linea node. The `-f` flag ensures you are following the log output

```bash
docker logs linea-mainnet -f --tail 100
```

Allow a few minutes for the Linea node to connect with peers. Once it starts syncing, the logs should look like this:

```
Feb 26 01:14:36 tiberian-infradao geth[118326]: INFO [02-26|01:14:36.231] Looking for peers                        peercount=0 tried=131 static=0
Feb 26 01:14:40 tiberian-infradao geth[118326]: INFO [02-26|01:14:40.661] Imported new chain segment               number=1 hash=78df32..d51eac blocks=1 txs=1 mgas=0.021 elapsed=1.487ms     mgasps=14.115 age=7mo3w3d snapdiffs=133.00B triedirty=0.00B
Feb 26 01:14:40 tiberian-infradao geth[118326]: INFO [02-26|01:14:40.776] Imported new chain segment               number=118 hash=9d4545..f40fa6 blocks=117 txs=128 mgas=42.794 elapsed=82.126ms    mgasps=521.076 age=7mo2w3d snapdiffs=26.73KiB triedirty=0.00B
```

## Test Linea RPC

You can call the JSON-RPC API methods to confirm the node is running. For example, call [`eth_syncing`](https://besu.hyperledger.org/public-networks/reference/api#eth_syncing) to return the synchronization status. For example the starting, current, and highest block, or `false` if not synchronizing (or if the head of the chain has been reached)

```bash
curl https://{YOUR_DOMAIN} \
        -X POST \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'
```


# Mode


# Baremetal

Authors: \[man4ela | catapulta.eth]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU          | OS                     | RAM          | DISK               |
| ------------ | ---------------------- | ------------ | ------------------ |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | 1TB+ (SSD or NVMe) |

{% hint style="info" %}
*The Mode Mainnet archive node has a size of 544GB on October 11th, 2024*
{% endhint %}

## Mode

{% hint style="success" %}
Mode operates within the Optimism *Superchain* ecosystem. It is powered by the [OP Stack](https://stack.optimism.io/), in collaboration with Optimism, leveraging the scalability and security of Optimism's Layer 2 infrastructure.

In this guide, we are walking through the process of setting up a Mode Mainnet archive node using Optimism's `op-geth and op-node`.
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint with **`all historical blobs data`** (e.g. Lighthouse) ready. <mark style="color:red;">A beacon endpoint meeting this criteria is essential for syncing to start.</mark>

<mark style="color:orange;">**Hint:**</mark> <https://console.chainstack.com/user/account/create> has a free plan enough to sync a node
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget aria2 gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Mode Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

Allow remote P2P connections with Mode Node

```bash
sudo ufw allow 9222
sudo ufw allow 30303
sudo ufw allow 30305
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

<pre class="language-bash"><code class="lang-bash"><strong>sudo ufw enable
</strong></code></pre>

To check the status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Install dependencies

#### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install GO

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

#to verify Go installation
go version

#If it returns Command 'go' not found simply run 
echo 'export PATH=$PATH:/usr/local/go/bin:/root/.local/bin' >> /root/.bashrc

#and then apply changes with

source /root/.bashrc
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

<pre class="language-bash"><code class="lang-bash">source /root/.bashrc
<strong>
</strong><strong>foundryup
</strong></code></pre>

### Install node and yarn

```bash
nvm install 18.12.0 && npm install --global yarn && nvm use 18.12.0 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependencies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

## Build the Rollup Node (op-node)

#### Create database directory and jwt secret file

```bash
mkdir mode && cd mode

mkdir -p  /root/data/mode/mode-op-node/

mkdir -p  /root/data/mode/mode-op-geth/ && cd /root/data/mode/mode-op-geth/

openssl rand -hex 32 | tr -d "\n" > /root/data/mode/mode-op-geth/jwt.hex
```

#### Download genesis.json and rollup.json files

```bash
cd #to return to /root/ directory

git clone https://github.com/mode-network/node

cd node

export CONDUIT_NETWORK=mode-mainnet-0

./download-config.py $CONDUIT_NETWORK

#move genesis.json and rollup.json into op-geth directory 

mv /root/node/networks/mode-mainnet-0/genesis.json /root/node/networks/mode-mainnet-0/rollup.json /root/data/mode/mode-op-geth/
```

#### Build op-node

```bash
cd /root/mode/

git clone https://github.com/ethereum-optimism/optimism.git

cd optimism

git checkout v1.9.3

make op-node

# The binary is built at /root/zora/optimism/op-node/bin/op-node
```

### Create systemd service for op-node

```bash
sudo nano /etc/systemd/system/mode-op-node.service
```

#### Paste the following configs replacing `{L1 RPC},{L1 BEACON RPC},{SERVER IP}` with own values

Save by entering `ctrl+X` and `Y+ENTER`

```bash
[Unit]
Description=Mode OP Node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/mode/mode-op-node/
Environment=OP_NODE_L1_ETH_RPC={L1 RPC}
Environment=OP_NODE_L2_ENGINE_AUTH=/root/data/mode/mode-op-geth/jwt.hex
Environment=OP_NODE_L2_ENGINE_RPC=http://0.0.0.0:8551
Environment=OP_NODE_LOG_LEVEL=info
Environment=OP_NODE_METRICS_ADDR=0.0.0.0
Environment=OP_NODE_METRICS_ENABLED=true
Environment=OP_NODE_METRICS_PORT=7300
Environment=OP_NODE_P2P_BOOTNODES=enode://cd3730ae0a02324d4f529b1a0b492a4047552025c48dc8c9d6685af386dbe8de7780cb35567f76b9542537e96b9a5b160bee79edbd15fefa5a90371c12e57bed@34.127.98.251:9222?discport=30301,enode://d25ce99435982b04d60c4b41ba256b84b888626db7bee45a9419382300fbe907359ae5ef250346785bff8d3b9d07cd3e017a27e2ee3cfda3bcbb0ba762ac9674@bootnode.conduit.xyz:0?discport=30301,enode://2d4e7e9d48f4dd4efe9342706dd1b0024681bd4c3300d021f86fc75eab7865d4e0cbec6fbc883f011cfd6a57423e7e2f6e104baad2b744c3cafaec6bc7dc92c1@34.65.43.171:0?discport=30305,enode://9d7a3efefe442351217e73b3a593bcb8efffb55b4807699972145324eab5e6b382152f8d24f6301baebbfb5ecd4127bd3faab2842c04cd432bdf50ba092f6645@34.65.109.126:0?discport=30305"
Environment=OP_NODE_P2P_AGENT=conduit
Environment=OP_NODE_P2P_NAT=true
Environment=OP_NODE_P2P_ADVERTISE_IP={SERVER IP}
Environment=OP_NODE_P2P_LISTEN_IP=0.0.0.0
Environment=OP_NODE_P2P_LISTEN_TCP_PORT=9222
Environment=OP_NODE_P2P_LISTEN_UDP_PORT=9222
Environment=OP_NODE_ROLLUP_CONFIG=/root/data/mode/mode-op-geth/rollup.json
Environment=OP_NODE_RPC_ADDR=0.0.0.0
Environment=OP_NODE_RPC_PORT=7545
Environment=OP_NODE_SNAPSHOT_LOG=/tmp/op-node-snapshot-log
Environment=OP_NODE_VERIFIER_L1_CONFS=4
Environment=OP_NODE_L1_TRUST_RPC=true
Environment=OP_NODE_L1_BEACON={L1 BEACON RPC}
Environment=OP_NODE_OVERRIDE_CANYON=1704992401
Environment=OP_NODE_OVERRIDE_DELTA=1708560000
Environment=OP_NODE_OVERRIDE_ECOTONE=1710374401
Environment=OP_NODE_OVERRIDE_FJORD=1720627201
Environment=OP_NODE_OVERRIDE_GRANITE=1726070401

ExecStart=/root/mode/optimism/op-node/bin/op-node \
                --l1={L1 RPC} \
                --l2=http://0.0.0.0:8551 \
                --l1.beacon-archiver={L1 BEACON RPC} \
                --l1.trustrpc=true
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target

```

## Build the Execution Engine (op-geth)

#### Build op-geth

```bash
cd /root/mode/

git clone https://github.com/ethereum-optimism/op-geth.git

cd  op-geth

git checkout v1.101408.0

make geth

# The binary is built at /root/github/op-geth/build/bin/geth
```

### Create systemd service for op-geth

```bash
sudo nano /etc/systemd/system/mode-op-geth.service
```

Paste the following configs:

```bash
[Unit]
Description=Mode OP GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000

WorkingDirectory=/root/mode/op-geth/build/bin/
Environment=GETH_GENESIS_FILE_PATH=/root/data/mode/mode-op-geth/genesis.json
Environment=GETH_ROLLUP_SEQUENCERHTTP=https://rpc-mode-mainnet-0.t.conduit.xyz
Environment=GETH_GCMODE=archive
Environment=HOST_IP=0.0.0.0
Environment=P2P_PORT=30303
Environment=WS_PORT=8546
Environment=OP_NODE_L2_ENGINE_AUTH=/root/data/mode/mode-op-geth/jwt.hex
Environment=GETH_OVERRIDE_CANYON=1704992401
Environment=GETH_OVERRIDE_DELTA=1708560000
Environment=GETH_OVERRIDE_ECOTONE=1710374401
Environment=GETH_OVERRIDE_FJORD=1720627201
Environment=GETH_OVERRIDE_GRANITE=1726070401

ExecStart=/root/mode/op-geth/build/bin/geth \
        --datadir=/root/data/mode/mode-op-geth/ \
        --verbosity=3 \
        --state.scheme=hash \
        --http \
        --http.corsdomain="*" \
        --http.vhosts="*" \
        --http.addr=0.0.0.0 \
        --http.port=8545 \
        --http.api=web3,debug,eth,net,engine \
        --authrpc.addr=0.0.0.0 \
        --authrpc.port=8551 \
        --authrpc.vhosts="*" \
        --authrpc.jwtsecret=/root/data/mode/mode-op-geth/jwt.hex \
        --ws \
        --ws.addr=0.0.0.0 \
        --ws.port=8546 \
        --ws.origins="*" \
        --ws.api=debug,eth,net,engine \
        --metrics \
        --metrics.addr=0.0.0.0 \
        --metrics.port=7200 \
        --syncmode=full \
        --gcmode=archive \
        --nat=extip:0.0.0.0 \
        --rollup.sequencerhttp=https://rpc-mode-mainnet-0.t.conduit.xyz \
        --port=30303 \
        --op-network=mode-mainnet \

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target
```

Save by entering `ctrl+X` and `Y+ENTER`

#### Initialize op-geth

```bash
/root/mode/op-geth/build/bin/geth init --datadir=/root/data/mode/mode-op-geth --state.scheme hash /root/data/mode/mode-op-geth/genesis.json// Some code
```

## Launch Mode

#### Start op-geth

{% hint style="info" %}
It's usually simpler to begin with starting`op-geth` before you start `op-node`. You can start `op-geth` even if `op-node` isn't running yet, but `op-geth` won't get any blocks until `op-node` starts.
{% endhint %}

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable mode-op-geth.service #enable mode-op-geth service at system startup

sudo systemctl start mode-op-geth.service #start mode-op-geth

sudo nano /etc/systemd/system/mode-op-geth.service #make changes in mode-op-geth.service file
```

#### Start op-node

{% hint style="info" %}
Once you've started `op-geth`, you can start `op-node`. `op-node` will connect to `op-geth` and begin synchronizing the Mode network. `op-node` will begin sending block payloads to `op-geth` when it derives enough blocks from Ethereum
{% endhint %}

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl enable mode-op-node.service #enable mode-op-node service at system startup

sudo systemctl start mode-op-node.service #start mode-op-node

sudo nano /etc/systemd/system/mode-op-node.service #make changes in mode-op-node.service file
```

### Monitor the logs for errors

```bash
sudo journalctl -fu mode-op-node.service #follow logs of mode-op-node.service

sudo journalctl -fu mode-op-geth.service #follow logs of mode-op-geth.service
```

You are expected to get following log messages from `op-node`

{% code overflow="wrap" %}

```bash
t=2024-09-18T03:23:58+0200 lvl=info msg="generated attributes in payload queue" txs=1 timestamp=1686723279
t=2024-09-18T03:23:58+0200 lvl=info msg="Inserted block" hash=0xa320a436f3f0aba175d8a5a29df758e791cac7ef9b159c07d623fbc9cfdcee7e number=14720 state_root=0x868445e40d3f282c735d768e07966ce153d4539057dd0cd602f531b2b1f96af6 timestamp=1686723279 parent=0xbcf66c21b09dbf880aa803016432407b38f86bf7bbc4d10bebee4f988f6525d1 prev_randao=0x057fd8e4e0b088b42d7a8c6ef2aeaeeb59da6f56cbff2ee34b13fa1fd5aa45ed fee_recipient=0x4200000000000000000000000000000000000011 txs=1 last_in_span=true derived_from=0xda5525e81c1267b4b0adb46ad23483d6eb67cc39aeadd289a618afed237f2687:17476348
Sep 18 03:23:58 Podaga op-node[33764]: t=2024-09-18T03:23:58+0200 lvl=info msg="Found next batch" batch_type=SingularBatch batch_timestamp=1686723281 parent_hash=0xa320a436f3f0aba175d8a5a29df758e791cac7ef9b159c07d623fbc9cfdcee7e batch_epoch=0x4b12a6767d5f8362ed09c2b1e6e371b4737eeec2f66632427143cc4687b62bff:17476337 txs=0 compression_algo=zlib
```

{% endcode %}

The expected log messages from `op-geth:`

```bash
INFO [09-25|18:05:58.867] Chain head was updated                   number=13,351,729 hash=9370fe..c97646 root=7893dd..996e12 elapsed="259.761µs"  age=4d17h41m
INFO [09-25|18:05:58.885] Starting work on payload                 id=0x033de8416465dcbc
INFO [09-25|18:05:58.902] Imported new potential chain segment     number=13,351,730 hash=c104d3..5e623b blocks=1 txs=3   mgas=2.563  elapsed=15.108ms     mgasps=169.673  age=4d17h41m  snapdiffs=3.4  triedirty=0.00B
```

### Run *`curl`* command in the terminal to check the status of your node

```bash
curl -H "Content-type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' http://localhost:8545
```

If it returns `false` then your node is fully synchronized with the network

#### Sync speed depends on your L1 node, as the majority of the chain is derived from data submitted to the L1.&#x20;

#### You can check your syncing status using the `optimism_syncStatus` RPC on the `op-node`

```bash
command -v jq  &> /dev/null || { echo "jq is not installed" 1>&2 ; }
echo Latest synced block behind by: \
$((($( date +%s )-\
$( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:7545 |
   jq -r .result.unsafe_l2.timestamp))/60)) minutes
```

### References

{% embed url="<https://docs.mode.network/>" %}

{% embed url="<https://github.com/mode-network/rollup-node>" %}


# Docker

Authors: \[Vikash Choubey | Dapplooker]

### System Requirements

| **CPU** | **OS**    | **RAM** | **DISK**   |
| ------- | --------- | ------- | ---------- |
| 8 vCPU  | Ubuntu 22 | 16GB    | 1TB+ (SSD) |

> *The Mode Mainnet archive node has a size of* 562G *on October 21st, 2024*

## Mode

{% hint style="success" %}
Mode operates within Optimism *Superchain* ecosystem. It is powered by the [OP Stack](https://stack.optimism.io/), leveraging the scalability and security of Optimism's Layer 2 infrastructure.

In this guide, we are walking through the process of setting up a Mode Mainnet archive node using Optimism's `op-geth and op-node`.
{% endhint %}

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint with **`all historical blobs data`** (e.g. Lighthouse) ready. <mark style="color:red;">A beacon endpoint meeting this criteria is essential for syncing to start.</mark>

<mark style="color:orange;">**Hint:**</mark> <https://console.chainstack.com/user/account/create> has a free plan enough to sync a node
{% endhint %}

## Pre-Requisites

To run the archive node using Docker, we need the following installed:

* Docker
* Python3
* git

#### Commands:

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

## Firewall Setting: <a href="#set-explicit-default-ufw-rules" id="set-explicit-default-ufw-rules"></a>

### Set explicit default UFW rules <a href="#set-explicit-default-ufw-rules" id="set-explicit-default-ufw-rules"></a>

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP and HTTPS <a href="#allow-ssh-http-and-https" id="allow-ssh-http-and-https"></a>

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Allow Remote connection: <a href="#setup-process" id="setup-process"></a>

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545 
sudo ufw allow from ${REMOTE.HOST.IP} to any port 7545
```

### Firewall Basic commands:

```
sudo ufw enable
```

## Running the node

### Clone repo:

```bash
cd /mnt/
git clone git@github.com:mode-network/rollup-node.git
```

### Set Environment variable

```bash
export CONDUIT_NETWORK=mode-mainnet-0
```

### Download network configuration with

```bash
cd /mnt/rollup-node
./download-config.py $CONDUIT_NETWORK
cp .env.example .env
```

### Update Environment Variable (.env):

```
OP_NODE_L1_ETH_RPC=
OP_NODE_L1_BEACON=
CONDUIT_NETWORK=mode-mainnet-0
```

### Create Data Directory:

You can create a data directory wherever you want. For this tutorial, we have created it at `/mnt/mode-data`

### Update Docker Compose file:

```yaml
services:
  op-geth: # this is Optimism's geth client
    ...
    volumes:
      - /mnt/mode-data:/data # enable to have persistency between restarts
      ...

```

### Example Docker Compose:

```yaml
version: '3.8'

services:
  op-geth: # this is Optimism's geth client
    pull_policy: always
    build:
      context: .
      dockerfile: op-geth.Dockerfile
    ports:
      - 8545:8545       # RPC
      - 8546:8546       # websocket
      - 30303:30303     # P2P TCP (currently unused)
      - 30303:30303/udp # P2P UDP (currently unused)
      - 7301:6060       # metrics
    env_file:
      - .env.default
      - networks/${CONDUIT_NETWORK:?set network}/.env
      - .env
    volumes:
      #- ./geth-data/:/data # enable to have persistency between restarts
      - ./networks/${CONDUIT_NETWORK:?set network}/genesis.json:/genesis.json
  op-node:
    pull_policy: always
    build:
      context: .
      dockerfile: op-node.Dockerfile
    depends_on:
      - op-geth
    ports:
      - 7545:8545     # RPC
      - 9222:9222     # P2P TCP
      - 9222:9222/udp # P2P UDP
      - 7300:7300     # metrics
      - 6060:6060     # pprof
    env_file:
      - .env.default
      - networks/${CONDUIT_NETWORK:?set network}/.env
      - .env
    volumes:
      - ./networks/${CONDUIT_NETWORK:?set network}/rollup.json:/rollup.json
      - ./networks/${CONDUIT_NETWORK:?set network}/genesis.json:/genesis.json
```

### Start Services Containers:

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

### Check Status:

Below is the command for the request:

```bash
curl -d '{"id":0,"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false]}' -H "Content-Type: application/json" http://localhost:8545 | jq .
```

You will see a response like:

```json
{
  "jsonrpc": "2.0",
  "id": 0,
  "result": {
    "baseFeePerGas": "0xfc",
    "blobGasUsed": "0x0",
    "difficulty": "0x0",
    "excessBlobGas": "0x0",
    "extraData": "0x",
    "gasLimit": "0x1c9c380",
    "gasUsed": "0xab57",
    "hash": "0xe479844f85d8dd6008b4aa9352ff3e3d0fa550235bf10bf4ae0c6e893dc13704",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "miner": "0x4200000000000000000000000000000000000011",
    "mixHash": "0x93aa8ce0f2f44eabacbb94058b5780cb6d645d457adba101540c6382ccf15f57",
    "nonce": "0x0000000000000000",
    "number": "0xdfaab9",
    "parentBeaconBlockRoot": "0x4f90158e2222808d53cad04b9b49ce98b3b52d311ec31b8234879a0fa81ab98c",
    "parentHash": "0x339d3321322b0f5f70bd69a0bf124025f9b980cd3b02b71b61e221c731521f54",
    "receiptsRoot": "0xf02f480a926e6a825c18788f6442060b973a4bb60ad88dbff3018b4982a1a071",
    "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
    "size": "0x347",
    "stateRoot": "0x017662cd279f827fcf1eef1c8c362bd4e7c069b36eb9d13a0e92bedbef94e16c",
    "timestamp": "0x6715d511",
    "totalDifficulty": "0x0",
    "transactions": [
      "0xaf0ce001508b96ce0d38bb8b14480487a788181e74690b513920513e50f033d6"
    ],
    "transactionsRoot": "0x35ccc1581f44d178fb5d0059d8a8ee6198117deab115e020591a7979c1dcbc1a",
    "uncles": [],
    "withdrawals": [],
    "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
  }
}
```

## Sync Status:

```bash
command -v jq  &> /dev/null || { echo "jq is not installed" 1>&2 ; }
echo Latest synced block behind by: \
$((($( date +%s )-\
$( curl -s -d '{"id":0,"jsonrpc":"2.0","method":"optimism_syncStatus"}' -H "Content-Type: application/json" http://localhost:7545 |
   jq -r .result.unsafe_l2.timestamp))/60)) minutes
```

## References:

{% embed url="<https://docs.mode.network/>" %}

{% embed url="<https://github.com/mode-network/rollup-node>" %}


# Moonbeam


# Baremetal

Authors: \[man4ela | catapulta.eth]

## System Requirements

|                CPU               |           OS           |  RAM  |    DISK    |
| :------------------------------: | :--------------------: | :---: | :--------: |
| 8 Cores (Fastest per core speed) | Debian 12/Ubuntu 22.04 | 16 GB | 1TB+ (SSD) |

{% hint style="info" %}
*The Moonbeam tracing node has a size of 1.5TB on May 2, 2024*
{% endhint %}

## Run a tracing node

{% hint style="success" %}
Geth's `debug` and `txpool` APIs and OpenEthereum's `trace` module provide non-standard RPC methods for getting a deeper insight into transaction processing. Supporting these RPC methods is important because many protocols, such as [The Graph](https://thegraph.com/), rely on them to index blockchain data.

To use the supported RPC methods, you need to run a **tracing node.** This guide covers the steps of how to set up and sync a tracing node on Moonbeam.
{% endhint %}

### Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Moonbeam node (*The default port for parachains is `9944` and `9945` for the embedded relay chain*)

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9944 9945
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

## Building a Node on Moonbeam

Download the Latest Release Binary

Check [release binary](https://github.com/moonbeam-foundation/moonbeam/releases) page and take the following steps to download the latest version:

Create a directory to store the binary and chain data (you might need `sudo`)

```
mkdir /var/lib/moonbeam-data
```

Use `wget` to grab the latest [release binary](https://github.com/moonbeam-foundation/moonbeam/releases) and output it to the directory created in the previous step:

```bash
wget https://github.com/moonbeam-foundation/moonbeam/releases/download/v0.37.2/moonbeam \
-O /var/lib/moonbeam-data/moonbeam
```

To verify that you have downloaded the correct version, you can run the following command in your terminal

```bash
sha256sum /var/lib/moonbeam-data/moonbeam
```

You should receive the following output:

`71242b8cdf2b97fba4aadb7d6050e0b46eaacafae6bcde9b5f5534aff620d144`

### Setup the Wasm Overrides (required for a tracing node) <a href="#setup-the-wasm-overrides" id="setup-the-wasm-overrides"></a>

You'll need to create a directory for the Wasm runtime overrides and obtain them from the [Moonbeam Runtime Overrides repository](https://github.com/moonbeam-foundation/moonbeam-runtime-overrides) on GitHub

```bash
git clone https://github.com/moonbeam-foundation/moonbeam-runtime-overrides.git
```

Move the Wasm overrides into your on-chain data directory:

```bash
mv moonbeam-runtime-overrides/wasm /var/lib/moonbeam-data
```

Delete the override files for the networks that you aren't running

```bash
rm /var/lib/moonbeam-data/wasm/moonriver-runtime-* &&  rm /var/lib/moonbeam-data/wasm/moonbase-runtime-*
```

Set permissions for the overrides

```bash
chmod +x /var/lib/moonbeam-data/wasm/*
```

### Create the Configuration File <a href="#create-the-configuration-file" id="create-the-configuration-file"></a>

The next step is to create the systemd configuration file, you'll need to:

* Replace`INSERT_YOUR_NODE_NAME` in two different places with the preffered name (it specifies a human-readable name for the node, which can be seen on [telemetry](https://telemetry.polkadot.io/), if enabled)
* **`--db-cache`** specifies the memory the database cache is limited to use. It is recommended to set it to 50% of the actual RAM your server has. For example, for 128 GB RAM, the value must be set to `64000`. The minimum value is `2000`, but it is below the recommended specs
* Double-check that the binary is in the proper path as described below (*ExecStart*)
* Double-check the base path if you've used a different directory
* Name the file `/etc/systemd/system/moonbeam.service`

Ensure that you grant execute permission to the binary file

```bash
sudo chmod +x /var/lib/moonbeam-data/moonbeam
```

```bash
sudo nano /etc/systemd/system/moonbeam.service
```

Copy/Paste and edit `INSERT_YOUR_NODE_NAME` and `--db-cache` according to your parameters:

```bash
[Unit]
Description="Moonbeam service"
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=root
SyslogIdentifier=moonbeam
SyslogFacility=local7
KillSignal=SIGHUP
ExecStart=/var/lib/moonbeam-data/moonbeam \
--rpc-port 9944 \
--execution wasm \
--wasm-execution compiled \
--state-pruning archive \
--trie-cache-size 1073741824 \
--runtime-cache-size 64 \
--ethapi debug,trace,txpool \
--wasm-runtime-overrides /var/lib/moonbeam-data/wasm \
--unsafe-rpc-external \
--rpc-cors all \
--db-cache 64000 \
--base-path /var/lib/moonbeam-data \
--chain moonbeam \
--name "INSERT_YOUR_NODE_NAME" \
-- \
--name "INSERT_YOUR_NODE_NAME (Embedded Relay)"

[Install]
WantedBy=multi-user.target
```

***Ctrl+X and Y to save changes***

{% hint style="info" %}
*`--rpc-port`* sets the unified port for both HTTP and WS connections. The default port for parachains is `9944` and `9945` for the embedded relay chain
{% endhint %}

{% hint style="info" %}
We run an RPC endpoint so we must use the `--unsafe-rpc-external` flag to run the Moonbeam node with external access to the RPC ports
{% endhint %}

```bash
systemctl enable moonbeam.service #enable moonbeam service at system startup

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start moonbeam.service #start moonbeam

sudo systemctl stop moonbeam.service #stop moonbeam
```

{% hint style="info" %}
To check or modify `moonbeam.service` parameters simply run&#x20;

`sudo nano /etc/systemd/system/moonbeam.service`

Ctrl+X and Y to save changes
{% endhint %}

```bash
journalctl -f -u moonbeam.service  #follow logs of moonbeam service
```

{% hint style="success" %}

```
The logs should look like the below example and indicate that your node syncs and is expected to reach chainhead in 3-4 days

Syncing 27.0 bps, target=#6051603 (30 peers), best: #3053702 (0xe669…1876), finalized #918931 (0x6587…f763), ⬇ 484.9kiB/s ⬆ 0.5kiB/s
```

{% endhint %}

### Maintain Your Node <a href="#maintain-your-node" id="maintain-your-node"></a>

As Moonbeam development continues, it will sometimes be necessary to upgrade your node software.

{% hint style="warning" %}
IMPORTANT NOTE: Make sure you update your tracing runtime overrides each time there is a new runtime upgrade, otherwise you won't be able to support the trace/debug/txpool API properly
{% endhint %}

#### For trace/debug/txpool API support

```bash
cd /root/moonbeam-runtime-overrides
git fetch && git pull

sudo systemctl stop moonbeam.service

rm -rf /var/lib/moonbeam-data/wasm

mv moonbeam-runtime-overrides/wasm /var/lib/moonbeam-data

rm /var/lib/moonbeam-data/wasm/moonbase-runtime-* &&  rm /var/lib/moonbeam-data/wasm/moonriver-runtime-*

sudo chmod ugo+x /var/lib/moonbeam-data/wasm/*

sudo systemctl restart moonbeam.service
```

To update **moonbeam** client, you can keep your existing chain data in tact, and only update the binary by following these steps:

1. *Stop the systemd service*

```bash
sudo systemctl stop moonbeam.service
```

2. *Remove the old binary file*

```bash
rm /var/lib/moonbeam-data/moonbeam
```

3. *Get the latest version of the* [*Moonbeam release binary on GitHub*](https://github.com/moonbeam-foundation/moonbeam/releases/) *and run the following command to update to that version (ensure to replace `INSERT_NEW_VERSION_TAG`with actual version)*

```bash
wget https://github.com/moonbeam-foundation/moonbeam/releases/download/INSERT_NEW_VERSION_TAG/moonbeam \
-O /var/lib/moonbeam-data/moonbeam
```

4. *Update permissions*

```bash
chmod +x /var/lib/moonbeam-data/moonbeam
```

5. *Start moonbeam service*

```bash
systemctl start moonbeam.service
```

## References

{% embed url="<https://docs.moonbeam.network/node-operators/networks/run-a-node/systemd/#introduction>" %}

{% embed url="<https://docs.moonbeam.network/node-operators/networks/tracing-node/#introduction>" %}


# Docker

Author(s): BK | E\&N/Braindexer and man4ela | catapulta.eth

## System Requirements

|                CPU               |           OS           |  RAM  |             DISK             |
| :------------------------------: | :--------------------: | :---: | :--------------------------: |
| 8 Cores (Fastest per core speed) | Debian 12/Ubuntu 22.04 | 16 GB | 2TB+ (SSD or NVME preffered) |

{% hint style="info" %}
*Moonbeam tracing node has a size of 2TB on December 23, 2024*
{% endhint %}

## Run a tracing node

{% hint style="success" %}
Geth's `debug` and `txpool` APIs and OpenEthereum's `trace` module provide non-standard RPC methods for getting a deeper insight into transaction processing. Supporting these RPC methods is important because many projects, such as [The Graph](https://thegraph.com/), rely on them to index blockchain data.

To use the supported RPC methods, you need to run a **tracing node.** This guide covers the steps on how to setup and sync a tracing node on Moonbeam using Docker.
{% endhint %}

### Pre-Requisites <a href="#pre-requisties" id="pre-requisties"></a>

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
​
sudo apt install -y wget curl screen git ufw// Some code
```

### Setting up Firewall <a href="#setting-up-firewall" id="setting-up-firewall"></a>

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Enable Firewall

```bash
sudo ufw enable
```

## Install Docker

#### Run this command to remove any conflicting docker

```bash
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
```

#### Add Docker's official GPG key:

```bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
```

#### Add the repository to ppt sources:

```bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
sudo apt-get update
```

#### Install docker

```bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Test docker is working
sudo docker run hello-world

#Install docker compose

sudo apt-get update
sudo apt-get install docker-compose-plugin

# Test the docker version
docker compose version
```

## Setting up a domain name to access RPC

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://youtu.be/QcNBLSSn8Vg>" %}

**Create Moonbeam directory**

The first command, `mkdir moonbeam`, will create a new directory named moonbeam in the current location. The second command, `cd moonbeam`, will change your current working directory to the newly created base directory. Now you are inside the base directory and can start storing docker-compose and related files in it.

```bash
mkdir moonbeam && cd moonbeam
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

<pre class="language-bash"><code class="lang-bash"><strong>EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
</strong>DOMAIN={YOUR_DOMAIN} #Domain should be something like rpc.mywebsite.com, e.g. moonbeam.infradao.org
WHITELIST={YOUR_REMOTE_MACHINE_IP} #the server's IP itself and comma separated list of IP's allowed to connect to RPC (e.g. Indexer)
</code></pre>

{% hint style="info" %}
`Ctrl + x` and `y` to save file
{% endhint %}

### Make Database directory and set necessary permissions

```bash
mkdir /var/lib/moonbeam-data/

sudo chown -R $(id -u):$(id -g) /var/lib/moonbeam-data
```

### Create a directory for WASM overrides:

```bash
mkdir /var/lib/moonbeam-data/moonbeam

sudo chown -R $(id -u):$(id -g) /var/lib/moonbeam-data/moonbeam
```

### Create docker-compose.yml

{% hint style="info" %}
Instead of the standard `moonbeamfoundation/moonbeam` docker image, you will use the `moonbeamfoundation/moonbeam-tracing` image.&#x20;

The latest supported version can be found on the Docker Hub for the moonbeam-tracing image from these repos: <https://hub.docker.com/r/moonbeamfoundation/moonbeam-tracing/tags>
{% endhint %}

*Create and paste the following into the docker-compose.yml*

```bash
sudo nano docker-compose.yml
```

{% hint style="warning" %}
Note that you have to:

* Replace `INSERT_YOUR_NODE_NAME` in two different places. This name can be whatever you want it to be named. For InfraDAO, you can use the name of the server
* Replace `INSERT_RAM_IN_MB` for 50% of the actual RAM your server has. For example, for 32 GB RAM, the value must be set to `16000`. The minimum value is `2000`, but it is below the recommended specs
* For an overview of the flags used in the following start-up commands, plus additional commonly used flags, please refer to the [Flags](https://docs.moonbeam.network/node-operators/networks/run-a-node/flags) page of our documentation
  {% endhint %}

```bash
version: '3.9'

networks:
  monitor-net:
    driver: bridge

volumes:
  traefik_letsencrypt: {}
  moonbeam-data: {}

services:

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=${EMAIL}"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.moonbeam-ipallowlist.ipallowlist.sourcerange=${WHITELIST}"

  moonbeam:
    image: moonbeamfoundation/moonbeam-tracing:v0.42.1-3400-latest
    user: root
    container_name: moonbeam
    volumes:
      - "/var/lib/moonbeam-data:/data"
    restart: unless-stopped
    command:
      - --base-path=/data
      - --chain=moonbeam
      - --name="INSERT_YOUR_NODE_NAME"
      - --rpc-port=9944
      - --rpc-cors=all
      - --unsafe-rpc-external
      - --state-pruning=archive
      - --trie-cache-size=1073741824
      - --db-cache=64000
      - --ethapi=debug,trace,txpool
      - --wasm-runtime-overrides=/moonbeam/moonbeam-substitutes-tracing
      - --runtime-cache-size=64
      - --
      - --name="INSERT_YOUR_NODE_NAME (Embedded Relay)"
    expose:
      - 9944 # rpc + ws parachain
      - 9945 # rpc + ws relay chain
      - 22057 # p2p parachain
      - 51555 # p2p relay chain
      - 9615 # prometheus parachain
      - 9616 # prometheus relay chain
    ports:
      - "9944:9944" # rpc + ws parachain
      - "9945:9945" # rpc + ws relay chain
      - "22057:22057"
      - "51555:51555"
    networks:
      - monitor-net
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.moonbeam.middlewares=moonbeam-ipallowlist"
    - "traefik.http.routers.moonbeam.rule=Host(`$DOMAIN`)"
    - "traefik.http.routers.moonbeam.entrypoints=websecure"
    - "traefik.http.routers.moonbeam.tls.certresolver=myresolver"
    - "traefik.http.services.moonbeam.loadbalancer.server.port=9944"// Some code
```

### Monitor logs for errors

```bash
docker logs moonbeam -f --tail 100
```

The expected output after successful launch should look like this:

```bash
2024-12-24 00:50:53 Moonbeam Parachain Collator
2024-12-24 00:50:53 ✌️  version 0.42.1-1432b45b797
2024-12-24 00:50:53 ❤️  by PureStake, 2019-2024
2024-12-24 00:50:53 📋 Chain specification: Moonbeam
2024-12-24 00:50:53 🏷  Node name: "InfraDAO B"
2024-12-24 00:50:53 👤 Role: FULL
2024-12-24 00:50:53 💾 Database: RocksDb at /data/chains/moonbeam/db/full
2024-12-24 00:50:54 Parachain Account: 5Ec4AhPVjsshXjh8ynp6MwaJTJBnen3pkHiiyDhHfie5VWkN
2024-12-24 00:50:54 Is collating: no
2024-12-24 00:53:51 [🌗] Found wasm override. version=moonbeam-3101 (moonbeam-0.tx2.au3) file=/moonbeam/moonbeam-substitutes-tracing/moonbeam-runtime-3101-substitute-tracing.wasm
2024-12-24 00:53:51 [🌗] Found wasm override. version=moonbeam-2600 (moonbeam-0.tx2.au3) file=/moonbeam/moonbeam-substitutes-tracing/moonbeam-runtime-2600-substitute-tracing.wasm
```

```bash
2024-12-24 00:54:38 [🌗] ⚙️  Syncing, target=#8873589 (6 peers), best: #7954971 (0x9ffd…e535), finalized #7954817 (0xbe30…f908), ⬇ 10.1MiB/s ⬆ 13.6kiB/s
2024-12-24 00:54:43 [Relaychain] ⚙️  Syncing 31.8 bps, target=#23974979 (8 peers), best: #23054735 (0xe5bd…0b0d), finalized #23054486 (0x0b99…0fd6), ⬇ 15.5MiB/s ⬆ 94.4kiB/s
2024-12-24 00:54:43 [🌗] ⚙️  Syncing 82.2 bps, target=#8873590 (6 peers), best: #7955382 (0x7551…156c), finalized #7954817 (0xbe30…f908), ⬇ 1.8MiB/s ⬆ 1.5kiB/s
2024-12-24 00:54:48 [Relaychain] ⚙️  Syncing 28.4 bps, target=#23974979 (8 peers), best: #23054877 (0x8c1a…c76c), finalized #23054848 (0x8eac…3a21), ⬇ 2.0MiB/s ⬆ 138.9kiB/s
```

### Test Moonbeam RPC

You can call the JSON-RPC API methods to confirm the node is running. For example, call [`eth_syncing`](https://besu.hyperledger.org/public-networks/reference/api#eth_syncing) to return the synchronization status. It will return the starting, current, and highest block, or `false` if not synchronizing (or if the head of the chain has been reached)

Replace `https://{YOUR_DOMAIN}` with actual domain name you set an A record for: &#x20;

```bash
curl https://{YOUR_DOMAIN} \
        -X POST \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'
```

#### Expected out:

```bash
{"jsonrpc":"2.0","result":{"startingBlock":"0x0","currentBlock":"0x85a337","highestBlock":"0x876c87","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}
```

## References

* **Moonbeam Tracing Node Docs**: <https://docs.moonbeam.network/node-operators/networks/tracing-node/>
* **Moonbeam Full Node Docs**: <https://docs.moonbeam.network/node-operators/networks/run-a-node/docker/>
* **Moonbeam Tracing Node Docker**: <https://hub.docker.com/r/moonbeamfoundation/moonbeam-tracing/tags>


# Moonriver


# Baremetal

Authors: \[man4ela | catapulta.eth]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

Comment

| CPU                              | OS                     | RAM   | DISK       |
| -------------------------------- | ---------------------- | ----- | ---------- |
| 8 Cores (Fastest per core speed) | Debian 12/Ubuntu 22.04 | 16 GB | 2TB+ (SSD) |

{% hint style="info" %}
*The Moonriver tracing node has a size of 1.8TB on January 30, 2025*
{% endhint %}

### Run a tracing node <a href="#run-a-tracing-node" id="run-a-tracing-node"></a>

{% hint style="success" %}
Geth's `debug` and `txpool` APIs and OpenEthereum's `trace` module provide non-standard RPC methods for getting a deeper insight into transaction processing. Supporting these RPC methods is important because many projects, such as [The Graph](https://thegraph.com/), rely on them to index blockchain data.

To use the supported RPC methods, you need to run a **tracing node.** This guide covers the steps on how to setup and sync a tracing node on Moonriver.
{% endhint %}

### Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Moonriver node (*The default port for parachains is `9944` and `9945` for the embedded relay chain*)

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 9944 9945
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

## Building a Node on Moonriver

Download the Latest Release Binary

Check [release binary](https://github.com/moonbeam-foundation/moonbeam/releases) page and take the following steps to download the latest version:

Create a directory to store the binary and chain data (you might need `sudo`)

```bash
mkdir /var/lib/moonriver-data
```

Use `wget` to grab the latest [release binary](https://github.com/moonbeam-foundation/moonbeam/releases) and output it to the directory created in the previous step:

```bash
wget https://github.com/moonbeam-foundation/moonbeam/releases/download/v0.42.1/moonbeam \
-O /var/lib/moonriver-data/moonbeam
```

To verify that you have downloaded the correct version, you can run the following command in your terminal

```bash
sha256sum /var/lib/moonriver-data/moonbeam
```

You should receive the following output:

9b645b2fd9e575b26ea727e96dc2a81486a73461bb961ba33ea2136e4c9060d8

### Setup the Wasm Overrides (required for a tracing node) <a href="#setup-the-wasm-overrides" id="setup-the-wasm-overrides"></a>

You'll need to create a directory for the Wasm runtime overrides and obtain them from the [Moonbeam Runtime Overrides repository](https://github.com/moonbeam-foundation/moonbeam-runtime-overrides) on GitHub

```bash
git clone https://github.com/moonbeam-foundation/moonbeam-runtime-overrides.git
```

Move the Wasm overrides into your on-chain data directory:

```bash
mv moonbeam-runtime-overrides/wasm /var/lib/moonriver-data
```

Delete the override files for the networks that you aren't running

```bash
rm /var/lib/moonriver-data/wasm/moonbeam-runtime-* &&  rm /var/lib/moonriver-data/wasm/moonbase-runtime-*
```

Set permissions for the overrides

```bash
chmod +x /var/lib/moonriver-data/wasm/*
```

### Create the Configuration File <a href="#create-the-configuration-file" id="create-the-configuration-file"></a>

The next step is to create the systemd configuration file, you'll need to:

* Replace`INSERT_YOUR_NODE_NAME` in two different places with the preffered name (it specifies a human-readable name for the node, which can be seen on [telemetry](https://telemetry.polkadot.io/), if enabled)
* **`--db-cache`** specifies the memory the database cache is limited to use. It is recommended to set it to 50% of the actual RAM your server has. For example, for 128 GB RAM, the value must be set to `64000`. The minimum value is `2000`, but it is below the recommended specs
* Double-check that the binary is in the proper path as described below (*ExecStart*)
* Double-check the base path if you've used a different directory
* Name the file `/etc/systemd/system/moonriver.service`

Ensure that you grant execute permission to the binary file

```bash
sudo chmod +x /var/lib/moonriver-data/moonbeam
```

```bash
sudo nano /etc/systemd/system/moonriver.service
```

Copy/Paste and edit `INSERT_YOUR_NODE_NAME` and `--db-cache` according to your parameters:

```bash
[Unit]
Description="Moonriver service"
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=root
SyslogIdentifier=moonbeam
SyslogFacility=local7
KillSignal=SIGHUP
ExecStart=/var/lib/moonriver-data/moonbeam \
--rpc-port 9944 \
--execution wasm \
--wasm-execution compiled \
--state-pruning archive \
--trie-cache-size 1073741824 \
--runtime-cache-size 64 \
--ethapi debug,trace,txpool \
--wasm-runtime-overrides /var/lib/moonriver-data/wasm \
--unsafe-rpc-external \
--rpc-cors all \
--prometheus-port 6060 \
--db-cache 64000 \
--base-path /var/lib/moonriver-data \
--chain moonriver \
--name "infradao-moonriver" \
-- \
--name "infradao-moonriver (Embedded Relay)"
```

***Ctrl+X and Y to save changes***

{% hint style="info" %}
*`--rpc-port`* sets the unified port for both HTTP and WS connections. The default port for parachains is `9944` and `9945` for the embedded relay chain
{% endhint %}

{% hint style="info" %}
We run an RPC endpoint so we must use the `--unsafe-rpc-external` flag to run the Moonbeam node with external access to the RPC ports
{% endhint %}

```bash
systemctl enable moonriver.service #enable moonriver service at system startup

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start moonriver.service #start moonriver

sudo systemctl stop moonriver.service #stop moonriver
```

{% hint style="info" %}
To check or modify moonriver`.service` parameters simply run&#x20;

`sudo nano /etc/systemd/system/`moonriver`.service`

Ctrl+X and Y to save changes
{% endhint %}

```bash
journalctl -f -u moonriver.service  #follow logs of moonriver service
```

{% hint style="success" %}

```
The logs should look like below and indicate that your node syncs and is expected to reach chainhead in about a week

Syncing 27.0 bps, target=#6051603 (30 peers), best: #3053702 (0xe669…1876), finalized #918931 (0x6587…f763), ⬇ 484.9kiB/s ⬆ 0.5kiB/s
```

{% endhint %}

### Maintain Your Node <a href="#maintain-your-node" id="maintain-your-node"></a>

As Moonbeam development continues, it will sometimes be necessary to upgrade your node software.

To update moonriver client, you can keep your existing chain data in tact, and only update the binary by following these steps:

1. *Stop the systemd service*

```bash
sudo systemctl stop moonriver.service
```

2. *Remove the old binary file*

```bash
rm /var/lib/moonriver-data/moonbeam
```

3. *Get the latest version of the* [*Moonbeam release binary on GitHub*](https://github.com/moonbeam-foundation/moonbeam/releases/) *and run the following command to update to that version (ensure to replace `INSERT_NEW_VERSION_TAG`with actual version)*

```bash
wget https://github.com/moonbeam-foundation/moonbeam/releases/download/INSERT_NEW_VERSION_TAG/moonbeam \
-O /var/lib/moonriver-data/moonbeam
```

4. *Update permissions*

```bash
chmod +x /var/lib/moonriver-data/moonbeam
```

5. *Start* moonriver *service*

```bash
systemctl start moonriver.service
```

## References

{% embed url="<https://docs.moonbeam.network/node-operators/networks/run-a-node/systemd/#introduction>" %}

{% embed url="<https://docs.moonbeam.network/node-operators/networks/tracing-node/#introduction>" %}


# Docker

Author: Godwin

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU                              | OS                     | RAM   | DISK                         |
| -------------------------------- | ---------------------- | ----- | ---------------------------- |
| 8 Cores (Fastest per core speed) | Debian 12/Ubuntu 22.04 | 16 GB | 2TB+ (SSD or NVME preffered) |

{% hint style="info" %}
*Moonriver tracing node has a size of 1.8TB on January 28, 2025*
{% endhint %}

### Run a tracing node <a href="#run-a-tracing-node" id="run-a-tracing-node"></a>

{% hint style="success" %}
Geth's `debug` and `txpool` APIs and OpenEthereum's `trace` module provide non-standard RPC methods for getting a deeper insight into transaction processing. Supporting these RPC methods is important because many projects, such as [The Graph](https://thegraph.com/), rely on them to index blockchain data.Comment​CommentTo use the supported RPC methods, you need to run a **tracing node.** This guide covers the steps on how to setup and sync a tracing node on Moonbeam using Docker.
{% endhint %}

### Pre-Requisites <a href="#pre-requisties" id="pre-requisties"></a>

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y wget curl screen git ufw
```

## Setting up Firewall

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Enable Firewall

```bash
sudo ufw enable
```

## Install Docker

#### Run this command to remove any conflicting docker

```bash
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
```

#### Add Docker's official GPG key:

```bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
```

#### Add the repository to ppt sources:

```bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
sudo apt-get update
```

#### Install docker

```bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Test docker is working
sudo docker run hello-world

#Install docker compose

sudo apt-get update
sudo apt-get install docker-compose-plugin

# Test the docker version
docker compose version
```

## Setting up a domain name to access RPC

Get the IP address of the host machine, you can use the following command in a terminal or command prompt.

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://youtu.be/QcNBLSSn8Vg>" %}

### Create Moonriver directory

The first command, `mkdir moonriver`, will create a new directory named moonriver in the current location. The second command, `cd moonriver`, will change your current working directory to the newly created base directory. Now you are inside the base directory and can start storing docker-compose and related files in it.

```bash
mkdir moonriver && cd moonriver
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain should be something like rpc.mywebsite.com, e.g. mooonriver.infradao.org
WHITELIST={YOUR_REMOTE_MACHINE_IP} #the server's IP itself and comma separated list of IP's allowed to connect to RPC (e.g. Indexer)
```

{% hint style="info" %}
`Ctrl + x` and `y` to save file
{% endhint %}

### Make Database directory and set necessary permissions

```bash
mkdir /var/lib/moonriver-data/

sudo chown -R $(id -u):$(id -g) /var/lib/moonriver-data
```

### Create a directory for WASM overrides:

```bash
mkdir /var/lib/moonriver-data/moonriver

sudo chown -R $(id -u):$(id -g) /var/lib/moonriver-data/moonriver
```

### Create docker-compose.yml

{% hint style="info" %}
Instead of the standard `moonbeamfoundation/moonbeam` docker image, you will use the `moonbeamfoundation/moonbeam-tracing` image.&#x20;

The latest supported version can be found on the Docker Hub for the moonbeam-tracing image from these repos: <https://hub.docker.com/r/moonbeamfoundation/moonbeam-tracing/tags>
{% endhint %}

*Create and paste the following into the docker-compose.yml*

```bash
sudo nano docker-compose.yml
```

{% hint style="warning" %}
Note that you have to:

* Replace `INSERT_YOUR_NODE_NAME` in two different places. This name can be whatever you want it to be named. For InfraDAO, you can use the name of the server
* Replace `INSERT_RAM_IN_MB` for 50% of the actual RAM your server has. For example, for 32 GB RAM, the value must be set to `16000`. The minimum value is `2000`, but it is below the recommended specs
* For an overview of the flags used in the following start-up commands, plus additional commonly used flags, please refer to the [Flags](https://docs.moonbeam.network/node-operators/networks/run-a-node/flags) page of our documentation
  {% endhint %}

```bash
version: '3.9'


networks:
  monitor-net:
    driver: bridge
  
volumes:
  traefik_letsencrypt: {}
  moonriver-data: {}

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=${EMAIL}"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.moonriver-ipallowlist.ipallowlist.sourcerange=${WHITELIST}"

  moonriver:
    image: moonbeamfoundation/moonbeam-tracing:v0.42.1-3401-latest
    user: root
    container_name: moonriver
    volumes:
      - "/var/lib/moonriver-data:/data"
    restart: unless-stopped
    command:
      - --base-path=/data
      - --chain=moonriver
      - --name="babayaga"
      - --rpc-port=9944
      - --rpc-cors=all
      - --unsafe-rpc-external
      - --state-pruning=archive
      - --trie-cache-size=1073741824
      - --db-cache=64000
      - --ethapi=debug,trace,txpool
      - --wasm-runtime-overrides=/moonriver/moonriver-substitutes-tracing
      - --runtime-cache-size=64
      - --
      - --name="babayaga (Embedded Relay)"
    expose:
      - 9944 # rpc + ws parachain
      - 9945 # rpc + ws relay chain
      - 30333 # p2p parachain
      - 30334 # p2p relay chain
      - 9615 # prometheus parachain
      - 9616 # prometheus relay chain
    ports:
      - "9944:9944" # rpc + ws parachain
      - "9945:9945" # rpc + ws relay chain
      - "30333:30333"
      - "30334:30334"
    networks:
      - monitor-net
    labels:
    - "traefik.enable=true"
    - "traefik.http.routers.moonriver.middlewares=moonbeam-ipallowlist"
    - "traefik.http.routers.moonriver.rule=Host(`$DOMAIN`)"
    - "traefik.http.routers.moonriver.entrypoints=websecure"
    - "traefik.http.routers.moonriver.tls.certresolver=myresolver"
    - "traefik.http.services.moonriver.loadbalancer.server.port=9944"
```

### Monitor logs for errors

```bash
docker logs moonriver -f --tail 100
```

The expected output after successful launch should look like this:

```bash
2025-01-26 11:58:08 [🌗] Found wasm override. version=moonriver-3102 (moonriver-0.tx2.au3) file=/moonbeam/moonriver-substitutes-tracing/moonriver-runtime-3102-substitute-tracing.wasm
2025-01-26 11:58:09 [🌗] Found wasm override. version=moonriver-1002 (moonriver-0.tx2.au3) file=/moonbeam/moonriver-substitutes-tracing/moonriver-runtime-1002-substitute-tracing.wasm
2025-01-26 11:58:09 [Relaychain] 🔨 Initializing Genesis block/state (state: 0xb000…ef6b, header-hash: 0xb0a8…dafe)    
2025-01-26 11:58:09 [Relaychain] 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.    
2025-01-26 11:58:09 [Relaychain] 👶 Creating empty BABE epoch changes on what appears to be first startup.    
2025-01-26 11:58:09 [Relaychain] 🏷  Local node identity is: 12D3KooWNcthaQ9c8SByj2A5uJdtPvU5bJaGNJwVzGDDkdNkn9UW    
2025-01-26 11:58:09 [Relaychain] Running libp2p network backend    
2025-01-26 11:58:09 [Relaychain] 💻 Operating system: linux    
2025-01-26 11:58:09 [Relaychain] 💻 CPU architecture: x86_64    
2025-01-26 11:58:09 [Relaychain] 💻 Target environment: gnu  
```

```bash
2025-01-28 21:21:49 [🌗] ⚙️  Syncing 175.0 bps, target=#10068541 (38 peers), best: #9577251 (0x28f7…734e), finalized #3716815 (0x28cc…7e57), ⬇ 3.5MiB/s ⬆ 0.5kiB/s    
2025-01-28 21:21:50 [Relaychain] ⚙️  Syncing 44.0 bps, target=#26848175 (41 peers), best: #16826836 (0x96a2…eabe), finalized #16826616 (0xba2c…df4e), ⬇ 1.6MiB/s ⬆ 140.9kiB/s    
2025-01-28 21:21:54 [🌗] ⚙️  Syncing 214.8 bps, target=#10068541 (38 peers), best: #9578325 (0xfe6c…a27c), finalized #3716959 (0xff38…fd86), ⬇ 4.0MiB/s ⬆ 1.6kiB/s    
2025-01-28 21:21:55 [Relaychain] ⚙️  Syncing 36.6 bps, target=#26848176 (41 peers), best: #16827019 (0x205c…f14d), finalized #16826912 (0x05d9…fbde), ⬇ 1.1MiB/s ⬆ 110.8kiB/s    
2025-01-28 21:21:59 [🌗] ⚙️  Syncing 140.6 bps, target=#10065658 (39 peers), best: #9579028 (0xc181…c7a0), finalized #3716959 (0xff38…fd86), ⬇ 2.7MiB/s ⬆ 1.1kiB/s    
2025-01-28 21:22:00 [Relaychain] ⚙️  Syncing 43.4 bps, target=#26848176 (41 peers), best: #16827236 (0xb843…e9bd), finalized #16826912 (0x05d9…fbde), ⬇ 1.8MiB/s ⬆ 215.0kiB/s 
```

### Test Moonriver RPC

You can call the JSON-RPC API methods to confirm the node is running. For example, call [`eth_syncing`](https://besu.hyperledger.org/public-networks/reference/api#eth_syncing) to return the synchronization status. It will return the starting, current, and highest block, or `false` if not synchronizing (or if the head of the chain has been reached)

Replace `https://{YOUR_DOMAIN}` with actual domain name or host ip: &#x20;

```bash
curl https://{YOUR_DOMAIN} \
        -X POST \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}'
```

#### Expected out:

```bash
{"jsonrpc":"2.0","result":{"startingBlock":"0x0","currentBlock":"0x920bb1","highestBlock":"0x99a23d","warpChunksAmount":null,"warpChunksProcessed":null},"id":1}
```

{% embed url="<https://docs.moonbeam.network/node-operators/networks/tracing-node/>" %}

{% embed url="<https://docs.moonbeam.network/node-operators/networks/run-a-node/docker/>" %}

{% embed url="<https://hub.docker.com/r/moonbeamfoundation/moonbeam-tracing/tags>" %}


# Optimism


# GETH


# Baremetal

Authors: \[Payne | StakeSquid]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4c/8T</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 8TB</td></tr></tbody></table>

## Pre-requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev apache2-utils build-essential pkg-config 

# Add to PATH
echo "export PATH="$PATH:/root/.foundry/bin:/usr/local/go/bin:/root/.local/bin"" >> /root/.bashrc

source /root/.bashrc

# Install go
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz

# Install nvm
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash 

# Download foundry
curl -L https://foundry.paradigm.xyz | bash

# Install foundry
foundryup

source /root/.bashrc

# Install node and yarn
nvm install 16 && npm install --global yarn && nvm use 16 && npm -g install pnpm

source /root/.bashrc

# Check if go and npm are installed:
go version
nvm -v
npm -v
yarn -v
pnpm -v

# Create directories
mkdir -p /root/github
mkdir -p /root/data/optimism/geth/dtl
mkdir -p /root/data/optimism/geth/l2geth
mkdir -p /root/data/optimism/geth/op-node
mkdir -p /root/data/optimism/geth/op-geth

# Download snapshots
https://docs.optimism.io/builders/node-operators/management/snapshots#op-mainnet

# Verify tree structure
/root/data/optimism/geth ❯ tree -d
.
|-- dtl
|-- l2geth
|   |-- geth
|   |   |-- chaindata
|   |   |   `-- ancient
|   |   |-- chaindata-part1
|   |   |   `-- ancient
|   |   |-- chaindata-part2
|   |   |-- lightchaindata
|   |   `-- nodes
|   `-- keystore
|-- op-geth
|   |-- geth
|   |   |-- blobpool
|   |   |-- chaindata
|   |   |   `-- ancient
|   |   |-- nodes
|   |   `-- triecache
|   `-- keystore
`-- op-node
    |-- opnode_discovery_db
    `-- opnode_peerstore_db

22 directories
```

## DTL

### Building Optimism DTL

```bash
mkdir -p /root/github
mkdir -p /root/data/optimism/geth/dtl

cd /root/github

git clone https://github.com/ethereum-optimism/optimism-legacy.git

cd optimism-legacy

yarn

yarn build
```

### Setting up the Systemd file for DTL

```bash
#######################  !!! EDIT YOUR OWN L1 RPC ENDPOINT !!! ###################

sudo echo "[Unit]
Description=Optimism DTL Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/github/optimism-legacy/packages/data-transport-layer
ExecStart=/bin/bash -c '. /root/.nvm/nvm.sh && /root/.nvm/versions/node/v16.20.2/bin/node /root/.nvm/versions/node/v16.20.2/bin/yarn start'
#EnvironmentFile=/root/github/optimism-legacy/packages/data-transport-layer/.env
Environment=DATA_TRANSPORT_LAYER__ADDRESS_MANAGER=0xdE1FCfB0851916CA5101820A69b13a4E276bd81F \
        DATA_TRANSPORT_LAYER__L1_START_HEIGHT=13596466 \
        DATA_TRANSPORT_LAYER__CONFIRMATIONS=12  \
        DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true \
        DATA_TRANSPORT_LAYER__DB_PATH=/root/data/optimism/geth/dtl/ \
        DATA_TRANSPORT_LAYER__ENABLE_METRICS=true \
        DATA_TRANSPORT_LAYER__ETH_NETWORK_NAME=mainnet \
        DATA_TRANSPORT_LAYER__L2_CHAIN_ID=10 \
        DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000 \
        DATA_TRANSPORT_LAYER__NODE_ENV=production \
        DATA_TRANSPORT_LAYER__POLLING_INTERVAL=500 \
        DATA_TRANSPORT_LAYER__SENTRY_TRACE_RATE=0.05 \
        DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0 \
        DATA_TRANSPORT_LAYER__SERVER_PORT=7878 \
        DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL=1000 \
        DATA_TRANSPORT_LAYER__SYNC_FROM_L1=true \
        DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT=http://IP:PORT \
        DATA_TRANSPORT_LAYER__DEFAULT_BACKEND=l1 \
        DATA_TRANSPORT_LAYER__L1_GAS_PRICE_BACKEND=l1 \
        DATA_TRANSPORT_LAYER__SYNC_FROM_L2=false
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/dtl.service
```

### To verify that DTL is running correctly you can run a command

#### If synchronizing from L1:

```bash
curl -s http://localhost:7878/eth/syncing?backend=l1  | jq .currentTransactionIndex
```

#### If synchronizing from L2:

```bash
curl -s http://localhost:7878/eth/syncing?backend=l2  | jq .currentTransactionIndex
```

## L2-GETH <a href="#optimism-l2-geth" id="optimism-l2-geth"></a>

### Building and preparing L2 GETH

```bash
cd /root/github/optimism-legacy/l2geth

make geth

mkdir -p /root/data/optimism/geth/l2geth/genesis/

# Download the genesis file

wget -O /root/data/optimism/geth/l2geth/genesis/genesis.json https://storage.googleapis.com/optimism/mainnet/genesis-berlin.json

# Set basic envs to load

curl -s "https://gist.githubusercontent.com/trader-payne/0fce05f7a8e7d9c4724fb2a771fff7f1/raw/b91b291445ff41cd4498d322da967167d4430f22/gistfile1.txt" > /root/github/optimism-legacy/packages/data-transport-layer/.env

# Init L2 GETH - this takes a while depending on your machine's specs

set -o allexport; source /root/github/optimism-legacy/packages/data-transport-layer/.env; set +o allexport; /root/github/optimism-legacy/l2geth/build/bin/geth init --datadir=/root/data/optimism/geth/l2geth /root/data/optimism/geth/l2geth/genesis/genesis.json --no-usb

# Import the block signer account

touch $DATADIR/password
echo $BLOCK_SIGNER_PRIVATE_KEY > $DATADIR/block-signer-key

/root/github/optimism-legacy/l2geth/build/bin/geth account import --datadir=$DATADIR --password $DATADIR/password $DATADIR/block-signer-key
```

### Setting up the Systemd file for L2GETH

```bash
sudo echo "[Unit]
Description=Optimism L2 GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/optimism/geth/l2geth/
#EnvironmentFile=/root/github/optimism-legacy/packages/data-transport-layer/.env
Environment=NETWORK_NAME=mainnet \
        NODE_TYPE=archive \
        USING_OVM=true \
        SEQUENCER_CLIENT_HTTP=https://mainnet.optimism.io \
        BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F \
        BLOCK_SIGNER_PRIVATE_KEY=6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27 \
        ETH1_CTC_DEPLOYMENT_HEIGHT=13596466 \
        ETH1_SYNC_SERVICE_ENABLE=false \
        ROLLUP_CLIENT_HTTP=http://0.0.0.0:7878 \
        ROLLUP_MAX_CALLDATA_SIZE=40000 \
        ROLLUP_POLL_INTERVAL_FLAG=1s \
        ROLLUP_VERIFIER_ENABLE=true \
        ROLLUP_DISABLE_TRANSFERS=false \
        ROLLUP_ENABLE_L2_GAS_POLLING=false \
        ROLLUP_GAS_PRICE_ORACLE_OWNER_ADDRESS=0x648E3e8101BFaB7bf5997Bd007Fb473786019159 \
        ROLLUP_BACKEND=l1 \
        GCMODE=archive \
        CACHE=32768 \
        DATADIR=/root/data/optimism/geth/l2geth/ \
        CHAIN_ID=10 \
        NETWORK_ID=10 \
        NO_DISCOVER=true \
        NO_USB=true \
        GASPRICE=0 \
        TARGET_GAS_LIMIT=15000000 \
        RPC_ADDR=0.0.0.0 \
        RPC_API=eth,rollup,net,web3,debug \
        RPC_CORS_DOMAIN=* \
        RPC_ENABLE=true \
        RPC_PORT=9656 \
        RPC_VHOSTS=* \
        WS_ADDR=0.0.0.0 \
        WS_API=eth,rollup,net,web3,debug \
        WS_ORIGINS=* \
        WS=true
ExecStart=/root/github/optimism-legacy/l2geth/build/bin/geth \
        --datadir=/root/data/optimism/geth/l2geth/ \
        --password=/root/data/optimism/geth/l2geth/password \
        --allow-insecure-unlock \
        --unlock=0x00000398232E2064F896018496b4b44b3D62751F \
        --mine \
        --miner.etherbase=0x00000398232E2064F896018496b4b44b3D62751F \
        --vmodule=eth/*=5,miner=4,rpc=5,rollup=4,consensus/clique=1 \
        --cache=32768
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/l2geth.service
```

#### To check if l2geth is running correctly, open another command line window and run these commands:

```bash
/root/optimism/l2geth/build/bin/geth attach --datadir=/root/.local/share/optimism/l2geth/datadir

eth.blockNumber
```

Wait a few seconds and then look at the blocknumber again and exit:

```bash
eth.blockNumber

exit
```

## OP NODE

### Building and preparing OP Node

```bash
mkdir -p /root/data/optimism/geth/op-node/

cd /root/github/

git clone https://github.com/ethereum-optimism/optimism.git

cd optimism

git checkout v1.6.0

nvm install && npm install --global yarn && nvm use node && npm -g install pnpm

pnpm install

pnpm build

make op-node

# The binary is built at /root/github/optimism/op-node/bin/op-node
```

### Setting up the Systemd file for OP Node

```bash
#######################  !!! EDIT YOUR OWN L1 RPC ENDPOINT !!! ###################

echo "[Unit]
Description=Optimism OP Node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000

WorkingDirectory=/root/data/optimism/geth/op-node/
#EnvironmentFile=/root/optimism/packages/data-transport-layer/.env
#Environment=

ExecStart=/root/github/optimism/op-node/bin/op-node \
                --l1=http://ethereum:port \
                --l2=http://0.0.0.0:8551 \
                --network=mainnet \
                --rpc.addr=0.0.0.0 \
                --rpc.port=9545 \
                --l2.jwt-secret=/root/data/optimism/geth/op-geth/jwt.txt \
                --l1.trustrpc \
                --l1.rpckind=erigon \
                --metrics.enabled \
                --metrics.addr=0.0.0.0 \
                --metrics.port=7300
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-node.service
```

## OP-GETH

### Building and preparing OP-GETH

```bash
cd /root/github/

git clone https://github.com/ethereum-optimism/op-geth.git

cd op-geth

git checkout v1.101308.1

make geth

# The binary is built at /root/github/op-geth/build/bin/geth
```

```bash
openssl rand -hex 32 > /root/data/optimism/geth/op-geth/jwt.txt
```

### Setting up the Systemd file for OP GETH

```bash
sudo echo "[Unit]
Description=Optimism OP GETH Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000

WorkingDirectory=/root/github/op-geth/build/bin/
#EnvironmentFile=/root/optimism/packages/data-transport-layer/.env
#Environment=

ExecStart=/root/github/op-geth/build/bin/geth \
		--datadir=/root/data/optimism/geth/op-geth \
		--http \
		--http.corsdomain="*" \
		--http.vhosts="*" \
		--http.addr=0.0.0.0 \
		--http.port=9657 \
		--http.api=web3,debug,eth,txpool,net,engine \
		--ws \
		--ws.addr=0.0.0.0 \
		--ws.port=8546 \
		--ws.origins="*" \
		--ws.api=debug,eth,txpool,net,engine,web3 \
		--metrics \
		--syncmode=full \
		--gcmode=archive \
		--nodiscover \
		--maxpeers=0 \
		--networkid=420 \
		--authrpc.vhosts="*" \
		--authrpc.addr=0.0.0.0 \
		--authrpc.port=8551 \
		--authrpc.jwtsecret=/root/data/optimism/geth/op-geth/jwt.txt \
		--rollup.sequencerhttp="<https://mainnet-sequencer.optimism.io>" \
		--rollup.disabletxpoolgossip=true \
		--rollup.historicalrpc="<http://0.0.0.0:9656>"
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-geth.service
```


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">4c/8T</td><td align="center">Ubuntu 22.04</td><td align="center">>= 16GB</td><td align="center">>= 8TB</td></tr></tbody></table>

## 🔴 Optimism

Official Docs <https://community.optimism.io/docs/developers/bedrock/node-operator-guide/#>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create base directory

The first command, `mkdir optimism`, will create a new directory named optimism in the current location. The second command, `cd optimism`, will change your current working directory to the newly created base directory. Now you are inside the base directory and can start storing docker-compose and related files in it.

```bash
mkdir optimism
cd optimism
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

{% code overflow="wrap" fullWidth="false" %}

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN}
WHITELIST={YOUR_REMOTE_MACHINE_IP}
DATA_TRANSPORT_LAYER__RPC_ENDPOINT={RPC_ENDPOINT_OF_ETHEREUM_L1_NODE} # L1 RPC
NETWORK_NAME={MAINNET}
OP_NODE__RPC_TYPE={BASIC} #default is basic (other options are erigon, alchemy, quicknode, infura, parity, nethermind, debug_geth, any)
```

{% endcode %}

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Make scripts directory

```bash
cd ~/optimism
mkdir scripts
cd scripts #Goto scripts directory
```

### Download all the helper scripts into scripts directory

{% code overflow="wrap" %}

```bash
cat << EOF | wget -i -
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/Dockerfile.bedrock-init
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/init-bedrock.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/init-l2geth.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/start-dtl.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/start-l2geth.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/start-op-geth.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/start-op-node.sh
https://raw.githubusercontent.com/InfraDAO/scripts/main/optimism/utils.sh
EOF
```

{% endcode %}

### Make Scripts Executable

```bash
chmod +x *.sh
```

### Create docker-compose.yml

```bash
cd ~/optimism
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
  dtl_data: {}
  geth_data: {}
  op-geth_data: {}
  shared: {}
  torrent_downloads: {}
  traefik_letsencrypt: {}

services:

######################################################################################
#####################               TRAEFIK CONTAINER           ######################
######################################################################################

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################               OP-GETH CONTAINER           ######################
######################################################################################

  op-geth:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101304.0
    container_name: opgeth
    restart: unless-stopped
    expose:
      - 8545 #http
      - 8546 #ws
    networks:
      - monitor-net
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-geth.sh
    environment:
      - BEDROCK_SEQUENCER_HTTP=https://mainnet-sequencer.optimism.io
      - BEDROCK_DATADIR=/geth
    volumes:
      - ./scripts/:/scripts
      - shared:/shared
      - op-geth_data:/geth
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.optimism.service=optimism" #https
      - "traefik.http.services.optimism.loadbalancer.server.port=8545"
      - "traefik.http.routers.optimism.entrypoints=websecure"
      - "traefik.http.routers.optimism.tls.certresolver=myresolver"
      - "traefik.http.routers.optimism.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.optimism.middlewares=ipwhitelist"

######################################################################################
#####################               OP-NODE CONTAINER           ######################
######################################################################################

  op-node:
    image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.3.0
    container_name: opnode
    restart: unless-stopped
    expose:
      - 9003/tcp
      - 9003/udp
    networks:
      - monitor-net
    stop_grace_period: 5m
    entrypoint: /scripts/start-op-node.sh
    env_file:
      - .env
    volumes:
      - ./scripts/:/scripts
      - shared:/shared

######################################################################################
#####################               DTL CONTAINER               ######################
######################################################################################

  dtl:
    image: ethereumoptimism/data-transport-layer:${IMAGE_TAG__DTL:-latest}
    container_name: dtl
    restart: unless-stopped
    expose:
      - 7878
    networks:
      - monitor-net
    entrypoint: /scripts/start-dtl.sh
    environment:
      - "NODE_TYPE=archive"
      - "DATA_TRANSPORT_LAYER__ADDRESS_MANAGER=0xdE1FCfB0851916CA5101820A69b13a4E276bd81F"
      - "DATA_TRANSPORT_LAYER__L1_START_HEIGHT=13596466"
      - "DATA_TRANSPORT_LAYER__CONFIRMATIONS=12"
      - "DATA_TRANSPORT_LAYER__DANGEROUSLY_CATCH_ALL_ERRORS=true"
      - "DATA_TRANSPORT_LAYER__DB_PATH=/db"
      - "DATA_TRANSPORT_LAYER__ENABLE_METRICS=true"
      - "DATA_TRANSPORT_LAYER__ETH_NETWORK_NAME=${NETWORK_NAME:-mainnet}"
      - "DATA_TRANSPORT_LAYER__L2_CHAIN_ID=10"
      - "DATA_TRANSPORT_LAYER__LOGS_PER_POLLING_INTERVAL=2000"
      - "DATA_TRANSPORT_LAYER__NODE_ENV=production"
      - "DATA_TRANSPORT_LAYER__POLLING_INTERVAL=500"
      - "DATA_TRANSPORT_LAYER__SENTRY_TRACE_RATE=0.05"
      - "DATA_TRANSPORT_LAYER__SERVER_HOSTNAME=0.0.0.0"
      - "DATA_TRANSPORT_LAYER__SERVER_PORT=7878"
      - "DATA_TRANSPORT_LAYER__TRANSACTIONS_PER_POLLING_INTERVAL=1000"
      - "DATA_TRANSPORT_LAYER__DEFAULT_BACKEND=l1"
      - "DATA_TRANSPORT_LAYER__L1_GAS_PRICE_BACKEND=l1"
      - "DATA_TRANSPORT_LAYER__SYNC_FROM_L1=true"
      - "DATA_TRANSPORT_LAYER__SYNC_FROM_L2=false"
      - "DATA_TRANSPORT_LAYER__RPC_ENDPOINT=${DATA_TRANSPORT_LAYER__RPC_ENDPOINT}"
    volumes:
      - dtl_data:/db
      - ./scripts/:/scripts/

######################################################################################
#####################               L2GETH CONTAINER            ######################
######################################################################################

  l2geth:
    image: ethereumoptimism/l2geth:${IMAGE_TAG__L2GETH:-latest}
    container_name: l2geth
    restart: unless-stopped
    expose:
      - 8545 #http
      - 8546 #ws
    networks:
      - monitor-net
    stop_grace_period: 5m
    entrypoint: 
      - /bin/sh
      - -c
      - "/scripts/init-l2geth.sh && /scripts/start-l2geth.sh"
    environment:
      - NODE_TYPE=archive
      - USING_OVM=true
      - SEQUENCER_CLIENT_HTTP=https://mainnet.optimism.io
      - BLOCK_SIGNER_ADDRESS=0x00000398232E2064F896018496b4b44b3D62751F
      - BLOCK_SIGNER_PRIVATE_KEY=6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27
      - BLOCK_SIGNER_PRIVATE_KEY_PASSWORD=pwd
      - ETH1_CTC_DEPLOYMENT_HEIGHT=13596466
      - ETH1_SYNC_SERVICE_ENABLE=true
      - L2GETH_GENESIS_URL=https://storage.googleapis.com/optimism/mainnet/genesis-berlin.json
      - L2GETH_GENESIS_HASH=0x106b0a3247ca54714381b1109e82cc6b7e32fd79ae56fbcc2e7b1541122f84ea
      - ROLLUP_CLIENT_HTTP=http://dtl:7878
      - ROLLUP_MAX_CALLDATA_SIZE=40000
      - ROLLUP_POLL_INTERVAL_FLAG=1s
      - ROLLUP_VERIFIER_ENABLE=true
      - ROLLUP_BACKEND=l1
      - L2GETH_STATE_DUMP_PATH=/geth/l2geth-state
      - DATADIR=/geth
      - CHAIN_ID=10
      - NETWORK_ID=10
      - NO_DISCOVER=true
      - NO_USB=true
      - GASPRICE=0
      - TARGET_GAS_LIMIT=15000000
      - RPC_ADDR=0.0.0.0
      - RPC_API=eth,rollup,net,web3,debug
      - RPC_CORS_DOMAIN=*
      - RPC_ENABLE=true
      - RPC_PORT=8545
      - RPC_VHOSTS=*
      - WS_ADDR=0.0.0.0
      - WS_API=eth,rollup,net,web3,debug
      - WS_ORIGINS=*
      - WS=true
    volumes:
      - geth_data:/geth
      - ./scripts/:/scripts/

######################################################################################
#####################               SNAPSHOT CONTAINER          ######################
######################################################################################

  bedrock-init:
    build:
      context: ./scripts
      dockerfile: Dockerfile.bedrock-init
    entrypoint: /scripts/init-bedrock.sh
    env_file:
      - .env
    networks:
      - monitor-net
    volumes:
      - ./scripts/:/scripts
      - shared:/shared
      - op-geth_data:/geth
      - geth_data:/legacy-geth
      - torrent_downloads:/downloads
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Optimism Node

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

### Monitor Logs

Use `docker logs` to monitor your geth and op nodes. The `-f` flag ensures you are following the log output

```
docker logs opgeth -f --tail 50
docker logs opnode -f --tail 50
```

## Test Optimism RPC 🧪

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

{% endcode %}

{% hint style="warning" %}
Sync speed will be highly dependent on your Layer 1 RPC
{% endhint %}


# Erigon


# Baremetal

Authors: \[payne | stakesquid]

## System Requirements

|      CPU     |           OS           |      RAM     |                         DISK                         |
| :----------: | :--------------------: | :----------: | :--------------------------------------------------: |
| 8+ cores CPU | Debian 12/Ubuntu 22.04 | => 16 GB RAM | <p>2TB+ op-erigon<br><br>3.5TB+ l2geth (legacy) </p> |

{% hint style="info" %}
*Op-erigon reached a size of 2TB by Jan 10, 2025*\
*L2-geth is 3.4TB*
{% endhint %}

## Optimism <mark style="color:blue;">🔵</mark>

{% hint style="warning" %}
Before you start, make sure that you have your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) ready.
{% endhint %}

{% hint style="warning" %}
To serve pre-bedrock eth\_calls, you will also need an l2geth (legacy) node. Instructions for how to set up an l2geth node can be found in [Baremetal](/archive-nodes-101/optimism/geth/baremetal#optimism-l2-geth)
{% endhint %}

## Pre-Requisites

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y

sudo apt install -y git make wget gcc pkg-config libusb-1.0-0-dev libudev-dev jq gcc g++ curl libssl-dev screen apache2-utils build-essential pkg-config
```

{% endcode %}

### Setting up Firewall

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH

```bash
sudo ufw allow 22/tcp
```

Allow remote RPC connections with Optimism Node

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

{% hint style="warning" %}
Not advised to allow all or unknown IP address to RPC port
{% endhint %}

Enable Firewall

```bash
sudo ufw enable
```

## Download a snapshot

Snapshots URL: <https://snapshot.testinprod.io/>

*Create a directory and start downloading an archive in screen session as it takes \~9 hours*

{% code overflow="wrap" %}

```bash
mkdir Optimism && cd Optimism

screen -S archive

aria2c --file-allocation=none -c -x 10 -s 10 "https://datadirs.testinprod.io/op-mainnet-db-120229131.zst"
```

{% endcode %}

```bash
#to return to previous screen and continue installation press 

Ctrl+a+d
```

## Compile Op-node

### Required Software Dependencies

<table><thead><tr><th width="154">Dependency</th><th width="110" align="center">Version</th><th width="233">Version Check Command</th></tr></thead><tbody><tr><td><mark style="color:green;">go</mark></td><td align="center"><code>^1.21</code></td><td><code>go version</code></td></tr><tr><td><mark style="color:orange;">node</mark></td><td align="center"><code>^20</code></td><td><code>node --version</code></td></tr><tr><td><mark style="color:blue;">pnpm</mark></td><td align="center"><code>^8</code></td><td><code>pnpm --version</code></td></tr><tr><td><mark style="color:green;">foundry</mark></td><td align="center"><code>^0.2.0</code></td><td><code>forge --version</code></td></tr><tr><td><mark style="color:orange;">make</mark></td><td align="center"><code>^4</code></td><td><code>make --version</code></td></tr><tr><td><mark style="color:green;">yarn</mark></td><td align="center"><code>1.22.21</code></td><td><code>yarn --version</code></td></tr><tr><td><mark style="color:blue;">nvm</mark></td><td align="center"><code>0.39.3</code></td><td><code>nvm --verison</code></td></tr></tbody></table>

### Install go

{% code overflow="wrap" fullWidth="false" %}

```bash
sudo wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && rm go1.21.6.linux-amd64.tar.gz
```

{% endcode %}

### Install nvm

```bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

### Download foundry

```bash
curl -L https://foundry.paradigm.xyz | bash
```

### Install foundry

```bash
foundryup

source /root/.bashrc
```

### Install node and yarn

```bash
nvm install 16 && npm install --global yarn && nvm use 16 && npm -g install pnpm

source /root/.bashrc
```

### Check if go and all dependancies are installed

```bash
go version
nvm -v
npm -v
yarn -v
pnpm -v
```

### Create directories

```bash
mkdir -p /root/github
mkdir -p /root/data/optimism/op-node
mkdir -p /root/data/optimism/op-erigon
```

### Build op-node

```bash
cd /root/github/

git clone https://github.com/ethereum-optimism/optimism.git

cd optimism

git checkout v1.7.0

nvm install && npm install --global yarn && nvm use node && npm -g install pnpm

pnpm install

pnpm build

make op-node
```

*#The binary is built at /root/github/optimism/op-node/bin/op-node*

### Create systemd service

{% hint style="warning" %}
You'll need your own synced Ethereum L1 RPC URL (e.g. Erigon) and L1 Consensus Layer Beacon endpoint (e.g. Lighthouse) in order to run optimism
{% endhint %}

{% code overflow="wrap" %}

```bash
echo "[Unit]
Description=Optimism OP Node Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/optimism/op-node/
ExecStart=/root/data/github/optimism/op-node/bin/op-node \
        --l1=http://<your_l1_eth_rpc> \
        --l2=http://0.0.0.0:8551 \
        --network=mainnet \
        --rpc.addr=0.0.0.0 \
        --rpc.port=9545 \
        --l2.jwt-secret=/root/data/optimism/erigon/jwt.hex \
        --l1.trustrpc \
        --l1.rpckind=erigon \
        --metrics.enabled \
        --l1.beacon=http://<your_l1_beacon_rpc> \
        --metrics.addr=0.0.0.0 \
        --metrics.port=7300
KillSignal=SIGTERM
[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-node.service
```

{% endcode %}

```bash
sudo nano /etc/systemd/system/op-node.service #make changes in op-node service file

sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-node.service #start op-node

sudo systemctl enable op-node.service #enable op-node service at system startup

sudo journalctl -fu op-node.service #follow logs of op-node service
```

## Compile Erigon

```bash
cd /root/github/

git clone https://github.com/testinprod-io/op-erigon

cd op-erigon

git checkout v2.60.0-0.6.1

make
```

#### Create JWT secret file and download genesis and rollup .json files

```bash
cd /root/data/optimism/erigon

openssl rand -hex 32 > /root/data/optimism/erigon/jwt.txt

```

### Create systemd service

```bash
sudo echo "[Unit]
Description=Erigon Optimism Service
After=network.target
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/data/optimism/erigon/
ExecStart=/root/data/github/op-erigon/build/bin/erigon \
        --datadir=/root/data/optimism/erigon/datadir \
        --ethash.dagdir=/root/data/optimism/erigon/datadir/ethash \
        --authrpc.jwtsecret=/root/data/optimism/erigon/jwt.hex \
        --authrpc.port=8551 \
        --http \
        --http.addr=0.0.0.0 \
        --http.port=9659 \
        --http.compression \
        --http.vhosts=* \
        --http.corsdomain=* \
        --http.api=eth,debug,net,trace,web3,erigon \
        --private.api.addr=0.0.0.0:9094 \
        --ws --ws.compression \
        --metrics --metrics.addr=0.0.0.0 --metrics.port=9698 \
        --torrent.download.rate 80mb \
        --rpc.returndata.limit=1000000 \
        --txpool.gossip.disable=true \
        --chain=op-mainnet \
        --db.size.limit=8TB \
        --nodiscover \
        --rollup.sequencerhttp="https://mainnet-sequencer.optimism.io" \
        --rollup.historicalrpc="http://<your_l2-geth_endpoint>:9656"
KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-erigon.service
```

## Sync using downloaded Snapshot

```bash
screen –r archive

ls #to see the name of downloaded archive

zstd --decompress op-mainnet-db-120229131.zst -o mdbx.dat
```

*#Unzipping takes \~3-4 hrs so you can go touch some grass*

Consider switching screen by pressing`ctrl A+D`to allow a process run in the background

#### After extracting is done move the contents of geth directory into op-erigon data directoy:

```bash
mv mdbx.dat /root/data/op-erigon/datadir/chaindata/
```

### Start op-erigon

```bash
sudo systemctl daemon-reload #refresh systemd configuration when changes made

sudo systemctl start op-erigon.service #start op-erigon

sudo systemctl enable op-erigon.service #enable op-erigon service at system startup

sudo journalctl -fu op-erigon.service #follow logs of op-erigon service
```

{% hint style="info" %}
To check or modify `op-erigon.service` parameters simply run

`sudo nano /etc/systemd/system/op-erigon.service`

Ctrl+X and Y to save changes
{% endhint %}


# Optimism Sepolia


# Docker

Author: \[Godwin]

## System Requirements

| CPU       | OS           | RAM | DISK |
| --------- | ------------ | --- | ---- |
| 4-8 cores | Ubuntu 24.04 | 16  | 5TB  |

{% hint style="info" %}
The Optimism Sepolia Archive Node has a size of 2.3TB as of 3/10/2025.
{% endhint %}

{% hint style="info" %}
Subgraphs using callHandlers requires the RPC client to support the Parity Tracing API. With Optimism sepolia we observe that `erigon` supports the parity tracing API, while `geth` does not.\
\
This guide shows how to set up a `geth` client.&#x20;
{% endhint %}

## Pre-Requisites

#### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
sudo apt install -y git gcc make --fix-missing
```

#### Installl Docker

```bash
# Update and upgrade packages
sudo apt-get update
sudo apt-get upgrade -y

### Docker and docker compose prerequisites
sudo apt-get install -y curl
sudo apt-get install -y gnupg
sudo apt-get install -y ca-certificates
sudo apt-get install -y lsb-release

### Download the docker gpg file to Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

### Add Docker and docker compose support to the Ubuntu's packages list
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
 
### Install docker and docker compose on Ubuntu
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

sudo usermod -aG docker $(whoami)
 
### Verify the Docker and docker compose install on Ubuntu
sudo docker run hello-world
```

## Firewall Configuration

#### Set Explicit Firewall Configuration

```bash
sudo ufw default deny incoming && sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow Connections for OP-NODE & OP-GETH

```bash
sudo ufw allow 8546
sudo ufw allow 9545
sudo ufw allow 8545
sudo ufw allow 3000
```

#### Enable Firewall Rules

```bash
sudo ufw enable
```

#### Check Status of Firewall Rules (UFW)

```bash
sudo ufw status verbose
```

## Clone the Optimism Docker Setup Directory

### Create Directories

```bash
git clone https://github.com/smartcontracts/simple-optimism-node.git
cd simple-optimism-node
```

#### Copy .env.example to .env

```bash
cp .env.example .env
```

## Configure the .env file&#x20;

#### This is a sample of how to configure the .env for op-sepolia node

{% hint style="info" %}
If port 8545 isn't working, you can connect to the default port for the l2 geth execution node port - 9993
{% endhint %}

```bash
###############################################################################
#                                ↓ REQUIRED ↓                                 #
###############################################################################

# Network to run the node on ("op-mainnet" or "op-sepolia")
NETWORK_NAME=op-sepolia

# Type of node to run ("full" or "archive"), note that "archive" is 10x bigger
NODE_TYPE=archive

###############################################################################
#                            ↓ REQUIRED (BEDROCK) ↓                           #
###############################################################################

# L1 node that the op-node (Bedrock) will get chain data from
OP_NODE__RPC_ENDPOINT=<l1-endpoint>

# L1 beacon endpoint, you can setup your own or use Quicknode
OP_NODE__L1_BEACON=<l1-beacon-endpoint>

# Type of RPC that op-node is connected to, see README
OP_NODE__RPC_TYPE=basic

# Reference L2 node to run healthcheck against
HEALTHCHECK__REFERENCE_RPC_PROVIDER=https://sepolia.optimism.io

###############################################################################
#                            ↓ OPTIONAL (BEDROCK) ↓                           #
###############################################################################

# Optional provider to serve legacy RPC requests, see README
OP_GETH__HISTORICAL_RPC=https://mainnet.optimism.io

# Set to "full" to force op-geth to use --syncmode=full
OP_GETH__SYNCMODE=

###############################################################################
#                                ↓ OPTIONAL ↓                                 #
###############################################################################

# Feel free to customize your image tag if you want, uses "latest" by default
# See here for all available images: https://hub.docker.com/u/ethereumoptimism
IMAGE_TAG__L2GETH=
IMAGE_TAG__DTL=
IMAGE_TAG__HEALTCHECK=
IMAGE_TAG__PROMETHEUS=
IMAGE_TAG__GRAFANA=
IMAGE_TAG__INFLUXDB=
IMAGE_TAG__OP_GETH=
IMAGE_TAG__OP_NODE=

# Exposed server ports (must be unique)
# See docker-compose.yml for default values
PORT__L2GETH_HTTP=8545
PORT__L2GETH_WS=
PORT__DTL=
PORT__HEALTHCHECK_METRICS=
PORT__PROMETHEUS=
PORT__GRAFANA=
PORT__INFLUXDB=
PORT__TORRENT_UI=
PORT__TORRENT=
PORT__OP_GETH_HTTP=
PORT__OP_GETH_WS=
PORT__OP_GETH_P2P=
PORT__OP_NODE_P2P=
PORT__OP_NODE_HTTP=
```

You can get more info on the env config in this link - <https://github.com/smartcontracts/simple-optimism-node#mandatory-configurations>

The docker-compose.yml file can be found here

<https://github.com/smartcontracts/simple-optimism-node/blob/main/docker-compose.yml>

### Operating the Node

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

## View the logs

```bash
docker compose logs <CONTAINER_NAME> -f --tail 10
```

### Monitoring

Run progress.sh to estimate remaining sync time and speed.

```bash
./progress.sh
```

```
Chain ID: 11155420
Sampling, please wait
Blocks per minute: 30
Hours until sync completed: ...
```

#### Grafana dashboard

Grafana is exposed at [http://localhost:3000](http://localhost:3000/) and comes with one pre-loaded dashboard ("Simple Node Dashboard").&#x20;

Use the following login details to access the dashboard:

* Username: `admin`
* Password: `optimism`

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

## Query Node

#### Check Sync Status

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_syncing", "params":[], "id":1}' \
http://localhost:8545 or 9993

# If node is done syncing - the response should resemble the below.
{"jsonrpc":"2.0","id":1,"result":false}
```

#### Check optimism sync status

```
curl -X POST -H "Content-Type: application/json" --data \
    '{"jsonrpc":"2.0","method":"optimism_syncStatus","params":[],"id":1}'  \
    http://localhost:9545
```

```bash
{"jsonrpc":"2.0","id":1,"result":{"current_l1":{"hash":"0xda1a28e8d035386478138aa1941d324bf39ac9ff57f4fbcf72ff98450f2c2590","number":7876040,"parentHash":"0x3a3a56dd92718df3b55ad48d3b8adfcf2a1741f7ec1478b9ec9bcf152a4dbc26","timestamp":1741642332},"current_l1_finalized"....
```

#### Check Block Number

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}' \
http://localhost:8545 or 9993

# Response should resemble the below.
{"jsonrpc":"2.0","id":1,"result":"0x17c3e4e"}
```


# Baremetal

Author: \[ jLeopoldA ]

## System Requirements

| CPU      | OS                 | RAM  | DISK |
| -------- | ------------------ | ---- | ---- |
| 4+ Cores | Ubuntu 22.04.4 LTS | 16GB | 5TB  |

{% hint style="info" %}
The Optimism Sepolia Archive Node has a size of 2.3TB as of 3/10/2025.
{% endhint %}

{% hint style="info" %}
Subgraphs using callHandlers requires the RPC client to support the Parity Tracing API. With Optimism sepolia we observe that `erigon` supports the parity tracing API, while `geth` does not.\
\
This guide shows how to set up a `geth` client.&#x20;
{% endhint %}

## Pre-Requisites

#### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
sudo apt install -y git gcc make --fix-missing
```

#### Install GO

{% hint style="warning" %}
OP-NODE and OP-GETH specifically require GO  v1.22.0.\
OP-NODE requires an L1 and an L1 Beacon.
{% endhint %}

```bash
# Remove previous installation of GO
rm -rf /usr/local/go # For GO installations locacated within /usr/local/go
rm -rf /usr/local/bin/go # For GO installations located within /usr/local/bin/go

# Download GO
wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz

# Extract and place within /usr/local
tar -xzf go1.22.0.linux-amd64.tar.gz -C /usr/local && rm go1.22.0.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
```

## Firewall Configuration

#### Set Explicit Firewall Configuration

```bash
sudo ufw default deny incoming && sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow Connections for OP-NODE & OP-GETH

```bash
sudo ufw allow 9222
sudo ufw allow 9545
sudo ufw allow 8545
sudo ufw allow 30303
```

#### Enable Firewall Rules

```bash
sudo ufw enable
```

#### Check Status of Firewall Rules (UFW)

```bash
sudo ufw status verbose
```

## Download and Set up OP-Node & OP-Geth

### Create Directories

```bash
mkdir -p /var/lib/optimism/database
mkdir -p /var/lib/optimism/configuration
mkdir -p /root/chain
```

### Create JWT Secret

```bash
openssl rand -hex 32 > /var/lib/optimism/configuration/jwt.txt
```

## Set up OP-Node&#x20;

#### Download & Build OP-Node

```bash
cd /root/chain

# Clone Optimism Repo
git clone https://github.com/ethereum-optimism/optimism.git
cd optimism

# Check out Latest Git version
git checkout v1.10.0

# Build OP-Node
make op-node
```

### Set up OP-Geth

```bash
cd /root/chain

# Clone OP-Geth repo
git clone https://github.com/ethereum-optimism/op-geth.git
cd op-geth

# Check out latest Git version
git checkout v1.101500.1

# Build OP-Geth
make geth
```

## Create System Services

#### Create Service for OP-Node

```bash
echo "[Unit]
Description=op-node
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/chain/optimism/
ExecStart=/root/chain/optimism/op-node/bin/op-node \
	--l1={L1_URL_HERE} \
	--l1.rpckind=any \
	--l1.beacon={L1_BEACON_URL_HERE} \
	--l2=ws://localhost:8551 \
	--l2.jwt-secret=/var/lib/optimism/configuration/jwt.txt \
	--network=op-sepolia \
	--syncmode=execution-layer
KillSignnal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > 
```

#### Create Service for OP-Geth

```bash
echo "[Unit]
Description=op-geth
After=network.target

[Service]
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/chain/op-geth
ExecStart=/root/chain/op-geth/build/bin/geth \
    --http --http.port=8545 --http.addr=localhost \
    --authrpc.addr=localhost \
    --authrpc.jwtsecret=/var/lib/optimism/configuration/jwt.txt \
    --verbosity=3 \
    --rollup.sequencerhttp=https://sepolia-sequencer.optimism.io/ \
    --op-network=op-sepolia \
    --datadir=/var/lib/optimism/database \
    --syncmode=full --gcmode=archive
KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/op-geth.service
```

## Run System Services

#### Reload System Services

```bash
systemctl daemon-reload
```

#### Run OP-Node Service

```bash
systemctl enable op-node.service 
systemctl start op-node.service
```

#### Run OP-Geth Service

```bash
systemctl enable op-geth.service
systemctl start op-geth.service
```

## Query Node

#### Check Logs

```bash
# Check OP-Node
journalctl -xeu op-node.service -o cat

# Check OP-Geth
journalctl -xeu op-geth.service -o cat
```

#### Check Sync Status

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_syncing", "params":[], "id":1}' \
http://localhost:8545

# If node is done syncing - the response should resemble the below.
{"jsonrpc":"2.0","id":1,"result":false}
```

#### Check Block Number

```bash
curl -H "Content-Type: application/json" \
-X POST --data '{"jsonrpc":"2.0", "method":"eth_blockNumber", "params":[], "id":1}' \
http://localhost:8545

# Response should resemble the below.
{"jsonrpc":"2.0","id":1,"result":"0x17c07de"}
```

{% embed url="<https://docs.optimism.io/operators/node-operators/tutorials/node-from-source>" %}

{% embed url="<https://docs.optimism.io/operators/node-operators/tutorials/run-node-from-source>" %}

{% embed url="<https://github.com/ethereum-optimism/optimism>" %}

{% embed url="<https://github.com/ethereum-optimism/op-geth>" %}


# Polygon


# Docker

Authors: \[Vince | Nodeify]

## System Requirements

<table data-full-width="false"><thead><tr><th align="center">CPU</th><th width="140" align="center">OS</th><th width="180" align="center">RAM</th><th align="center">DISK</th></tr></thead><tbody><tr><td align="center">16c CPU</td><td align="center">Ubuntu 22.04</td><td align="center">>= 32GB</td><td align="center">>= 10TB SSD/NVME</td></tr></tbody></table>

## Polygon ♾️

Official Docs <https://wiki.polygon.technology/docs/pos/operate/node/archive-node/>

### Pre-requisites

Update, upgrade, and clean the system, and then firewall management (ufw), Docker, and the Git version control system.

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y
```

Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

Allow SSH, HTTP and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

Get the IP address of the host machine, you can use the following command in a terminal or command prompt

```bash
curl ifconfig.me
```

Set an A record for a domain, you need to access the domain's DNS settings and create an A record that points to the IP address of the host machine. This configuration allows users to reach your domain by resolving the domain name to the specific IP address associated with your host machine.

{% embed url="<https://www.youtube.com/watch?v=QcNBLSSn8Vg>" %}

### Create Polygon directory

The first command, `mkdir polygon`, will create a new directory named polygon in the current location. The second command, `cd polygon`, will change your current working directory to the newly created polygon directory. Now you are inside the polygon directory and can start storing docker-compose and related files in it.

```bash
mkdir polygon
cd polygon
```

### Create .env file

```bash
sudo nano .env
```

Paste the following into the file.

```bash
EMAIL={YOUR_EMAIL} #Your email to receive SSL renewal emails
DOMAIN={YOUR_DOMAIN} #Domain of your reth node you set earlier, polygon.indexerdao.com
WHITELIST={YOUR_REMOTE_MACHINE_IP} # Remote IP's allowed to connect to RPC
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Create heimdall  and erigon directories

```
mkdir /var/lib/heimdall
mkdir /var/lib/erigon
```

### Initialize Heimdall

Run a Docker container from the `0xpolygon/heimdall` image. By using the `-v` flag, you're mapping the host directory `/var/lib/heimdall` to the container's `/root/.heimdalld` directory. The `init --home /root/.heimdalld` command initializes configurations and data on the host machine.

```
docker run -it -v /var/lib/heimdall:/root/.heimdalld 0xpolygon/heimdall:latest init --home /root/.heimdalld
```

{% hint style="info" %}
You should now have `/var/lib/heimdall/config` and `/var/lib/heimdall/data` directories on the host.
{% endhint %}

### Download genesis.json to `/var/lib/heimdall/config`

```
wget https://raw.githubusercontent.com/maticnetwork/launch/master/mainnet-v1/without-sentry/heimdall/config/genesis.json -O /var/lib/heimdall/config/genesis.json
```

### Modify seeds and cors\_allowed\_origins

```
sed -i '/^seeds/c\seeds = "f4f605d60b8ffaaf15240564e58a81103510631c@159.203.9.164:26656,4fb1bc820088764a564d4f66bba1963d47d82329@44.232.55.71:26656,2eadba4be3ce47ac8db0a3538cb923b57b41c927@35.199.4.13:26656,3b23b20017a6f348d329c102ddc0088f0a10a444@35.221.13.28:26656,25f5f65a09c56e9f1d2d90618aa70cd358aa68da@35.230.116.151:26656"' /var/lib/heimdall/config/config.toml
sed -i 's/cors_allowed_origins = \[\]/cors_allowed_origins = ["*"]/g' /var/lib/heimdall/config/config.toml
```

### Create docker-compose.yml

```bash
sudo nano docker-compose.yml
```

Paste the following into the docker-compose.yml

```docker
version: '3.8'

networks:
  monitor-net:
    driver: bridge

volumes:
    traefik_letsencrypt: {}

services:

######################################################################################
#####################         TRAEFIK PROXY CONTAINER          #######################
######################################################################################     

  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "443:443"
    networks:
      - monitor-net
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=$EMAIL"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    volumes:
      - "traefik_letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.ipwhitelist.ipwhitelist.sourcerange=$WHITELIST"

######################################################################################
#####################              ERIGON CONTAINER            #######################
###################################################################################### 

  erigon:
    image: thorax/erigon:v2.52.0
    container_name: erigon
    restart: unless-stopped
    user: root
    expose:
      - "8545" #rpc
      - "8551" #auth
      - "6060" #metrics
      - "9090" #api
    ports:
      - 30303:30303 #p2p
      - 30303:30303/udp #p2p
      - 30304:30304 #p2p
      - 30304:30304/udp #p2p
      - 42069:42069 #torrent
      - 42069:42069/udp #torrent
      - 4000:4000/udp #lightclient discovery
      - 4001:4001 #lightclient tcp
    networks:
      - monitor-net
    command: >
      --chain bor-mainnet
      --datadir /root/.local/share/erigon
      --bor.heimdall=http://heimdallr:1317
      --torrent.download.rate 1024mb
      --metrics
      --metrics.addr 0.0.0.0
      --metrics.port 6060
      --http.addr 0.0.0.0
      --http.port 8545
      --http.vhosts *
      --http.api eth,debug,net,trace
      --db.pagesize 16kb
      --batchSize 2048MB
      --etl.bufferSize 512MB
      --rpc.returndata.limit 1000000
      --snapshots=false
      --maxpeers 200
      --sentry.drop-useless-peers=true
      --db.size.limit=12TB
    volumes:
      - /var/lib/erigon:/root/.local/share/erigon:rw
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.erigon.loadbalancer.server.port=8545"
      - "traefik.http.routers.erigon.entrypoints=websecure"
      - "traefik.http.routers.erigon.tls.certresolver=myresolver"
      - "traefik.http.routers.erigon.rule=Host(`$DOMAIN`)"
      - "traefik.http.routers.erigon.middlewares=ipwhitelist"

######################################################################################
#####################              HEIMDALLD CONTAINER          #######################
######################################################################################

  heimdalld:
    image: 0xpolygon/heimdall:1.0.2
    container_name: heimdalld
    restart: unless-stopped
    expose:
      - "26657" # RPC
      - "1317" # REST
    ports:
      - "26656:26656" # P2P
    networks:
      - monitor-net
    command: |
      - start
      - --home /root/.heimdalld
      - --p2p.laddr=tcp://0.0.0.0:26656
      - --rpc.laddr=tcp://0.0.0.0:26657
      - --chain=mainnet
      - --rest-server
    volumes:
      - /var/lib/heimdall:/root/.heimdalld:rw
```

{% hint style="info" %}
ctrl + x and y to save file
{% endhint %}

### Run Polygon Node

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

### Monitor Logs

Use `docker logs` to monitor your erigon and heimdall nodes. The `-f` flag ensures you are following the log output

```
docker logs erigon -f
docker logs heimdalld -f
docker logs heimdallr -f
```

## Test Polygon RPC 🧪

{% code overflow="wrap" %}

```bash
curl --data '{"method":"eth_syncing","params":[],"id":1,"jsonrpc":"2.0"}' -H "Content-Type: application/json" -X POST https://{DOMAIN}
```

{% endcode %}


# Polygon zkEVM


# Erigon


# Baremetal

Author: \[ jLeopoldA ]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU    | OS                  | RAM  | DISK  |
| ------ | ------------------- | ---- | ----- |
| 4 Core | Ubunutu 24.04.1 LTS | 16GB | 128GB |

{% hint style="info" %}
The Polygon zkEVM archive node has a size of 103GB as of 1/15/2025
{% endhint %}

### Pre-Requisites <a href="#pre-requisites" id="pre-requisites"></a>

{% hint style="info" %}
CDK-Erigon requires the installation of Go.
{% endhint %}

### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -ye
```

### Set up Firewall <a href="#set-up-firewall" id="set-up-firewall"></a>

**Set Explicit Default Firewall Rules**

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow Remote RPC Connections with Polygon Zkevm

```bash
sudo ufw allow 8545
```

#### Allow P2P Connections

```bash
sudo ufw allow 30303/tcp && sudo ufw allow 30303/udp
```

#### Enable Firewall

```bash
sudo ufw enable
```

#### Check Status / Current Rules of UFW

```bash
sudo ufw status verbose
```

### Install GO

#### Check for Latest Version of GO

```bash
# This will return the latest version of GO
curl -s https://go.dev/VERSION?m=text

# Example response
go1.23.3
time 2024-11-06T18:46:45Z
```

#### Download the Latest GO Tarball

```bash
# Downloading using the above example response
wget https://go.dev/d1/go1.23.3.linux-amd64.tar.gz

# Example command if the above version is different
wget https://go.dev/d1/VERSION.linux-amd64.tar.gz
```

#### Extract and Install GO

```bash
sudo tar -C /usr/local -xzf go.1.23.3.linux-amd64.tar.gz
```

#### Set Environment Variables

```bash
echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
```

#### Check Installation

```bash
go version

# Example response
go version go1.23.3 linux/amd64
```

## Set up Polygon zkEVM with Erigon

### Clone the Polygon Hermez Repo for Erigon and Build Erigon

```bash
cd /root
git clone https://github.com/0xPolygonHermez/cdk-erigon
cd cdk-erigon/cmd/cdk-erigon
go build -o erigon
```

### Create Directory for DB

```bash
mkdir -p /var/lib/zkevm/db/
```

### Create YAML Configuration

#### Create Configuration Directory

```bash
mkdir /root/config/
nano /root/config/config.yaml
```

#### Paste and modify parameters. Save by entering ctrl+X and Y+ENTER&#x20;

```yaml
datadir: /var/lib/zkevm/db/
chain: hermez-mainnet
http: true
private.api.addr: localhost:9091
zkevm.l2-chain-id: 1101
zkevm.l2-sequencer-rpc-url: https://zkevm-rpc.com
zkevm.l2-datastreamer-url: stream.zkevm-rpc.com:6900
zkevm.l1-chain-id: 1
zkevm.l1-rpc-url: {YOUR_L1_RPC_URL_HERE}

zkevm.address-sequencer: "0x148Ee7dAF16574cD020aFa34CC658f8F3fbd2800"
zkevm.address-zkevm: "0x519E42c24163192Dca44CD3fBDCEBF6be9130987"
zkevm.address-rollup: "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2"
zkevm.address-ger-manager: "0x580bda1e7A0CFAe92Fa7F6c20A3794F169CE3CFb"

zkevm.default-gas-price: 1000000000
zkevm.max-gas-price: 0
zkevm.gas-price-factor: 0.0375

zkevm.l1-rollup-id: 1
zkevm.l1-block-range: 20000
zkevm.l1-query-delay: 6000
zkevm.l1-first-block: 16896700
zkevm.datastream-version: 2

# debug.timers: true # Uncomment to enable timers

externalcl: true
http.port: 8545
http.api: [eth, debug, net, trace, web3, erigon, zkevm]
http.addr: 0.0.0.0
http.vhosts: any
http.corsdomain: any
ws: true
```

## Launch Erigon Node

### Create Systemd Service

```bash
sudo nano /etc/systemd/system/erigon.service
```

Paste the below configuration and save by entering ctrl+X and Y+ENTER

```bash
[Unit]
Description=Zkevm Node
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/cdk-erigon/
ExecStart=/root/cdk-erigon/cmd/cdk-erigon/erigon \
	--config="/root/config/config.yaml"
KillSignal=SIGTERM
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
```

### Start CDK-Erigon

```bash
sudo systemctl daemon-reload # Refresh after systemd configuration changes
sudo systemctl enable erigon.service # Enable erigon.service at start up
sudo systemctl start erigon.service # Starts erigon.service
sudo systemctl stop erigon.service # Stops erigon.service
sudo systemctl restart erigon.service # Restarts erigon.service
```

### View Logs for Debugging

```bash
journalctl -fu erigon.service -xe
```

#### Alternatively, you can view logs minus server name and time and receive the below

```bash
journalctl -fu erigon.service -o cat
```

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

### Query Polygon zkEVM Node

{% hint style="info" %}
CDK-Erigon does take time to process blocks before you can fully query it.
{% endhint %}

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8545

# Example response
{"jsonrpc":"2.0","id":1,"result":"0x40e2d5"}
```

### References <a href="#references" id="references"></a>

{% embed url="<https://github.com/0xPolygonHermez/cdk-erigon>" %}


# Docker

Authors: \[ Ankur | Dapplooker]

## System Requirements

<table data-full-width="false"><thead><tr><th>CPU</th><th>OS</th><th>RAM</th><th>DISK</th></tr></thead><tbody><tr><td>4 vCPU</td><td>Ubuntu 22.04</td><td>64 GB</td><td>1TB (SSD)</td></tr></tbody></table>

{% hint style="info" %}
*The CDK-Erigon archival node has a size of 104GB on January 29, 2025.*
{% endhint %}

## Pre-requisite

Before starting, clean the setup then update and upgrade. Install following:

* Docker
* Docker Compose
* Git
* Go v1.19 +
* L1 Ethereum node RPC&#x20;

### **Commands:**

{% code overflow="wrap" %}

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install docker.io docker-compose git ufw -y 
```

{% endcode %}

## Firewall Settings:

### Set explicit default UFW rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

### Allow SSH, HTTP, and HTTPS

```bash
sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
```

### Allow Remote connection

```bash
sudo ufw allow from ${REMOTE.HOST.IP} to any port 8545
```

## Setup Instructions:

**Clone the CDK Erigon Repository**

Clone the repository and navigate to its root directory:

```bash
git clone https://github.com/0xPolygonHermez/cdk-erigon.git
cd cdk-erigon/
```

**Build Libraries**

Install the relevant libraries for your architecture:

```bash
make build-libs
```

**Configure `.env` file**

Create a `.env` file to configure environment variables:

```bash
echo "NETWORK=mainnet" >> .env
echo "L1_RPC_URL=<ETH_RPC_URL>" >> .env
```

### Example docker compose file:

```yaml
version: '2.2'
services:
  erigon:
    image: hermeznetwork/cdk-erigon:${TAG:-latest}
    user: root
    build:
      args:
        UID: root
        GID: root
      context: .
    command: ${ERIGON_FLAGS-} --config mainnet.yaml --zkevm.l1-rpc-url=<ETH_RPC_URL>
    environment:
      - name=value
    ports:
      - "8545:8545"
    volumes:
      - /root/cdk-erigon/data:/home/erigon/.local/share/erigon
    restart: unless-stopped
    mem_swappiness: 0
```

**Start the Node**

```bash
 docker compose -f docker-compose-example.yml up -d
```

## Monitor Logs

Monitor Logs of Docker Container&#x20;

```bash
docker ps 
docker logs  cdk-erigon-erigon-1
```

## Sync Status

Run a query to check the latest synchronized L2 block:

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber",
"params":[],"id":83}' http://localhost:8545
```

Response should look like:

```json
{"jsonrpc":"2.0","id":83,"result":"0x124ff31"}
```

### References <a href="#references" id="references"></a>

{% embed url="<https://github.com/0xPolygonHermez/cdk-erigon>" %}

{% embed url="<https://zkevm.polygonscan.com/>" %}


# Ronin


# Docker

Author \[godwin]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

| CPU      | OS           | RAM   | DISK     |
| -------- | ------------ | ----- | -------- |
| 8 cores+ | Ubuntu 24.04 | 32GB+ | >= 1.2TB |

{% hint style="info" %}
*The Ronin Mainnet archive node has a size of 1.2TB on November 14th, 2024*
{% endhint %}

Last updated at: 14th November 2024

Official docs - <https://docs.roninchain.com/rpc/mainnet-rpc>​

## Pre-Requisites

First, update, upgrade, and clean the system:

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install ufw -y
```

## Configure Firewall Settings&#x20;

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 8545
sudo ufw allow 8546
sudo ufw allow 30303
sudo ufw allow 6060
```

## Install Docker

Run this command to remove any conflicting docker

```bash
`for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done`
```

Add Docker's official GPG key:

```bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
```

Add the repository to ppt sources:

```bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
```

Install docker

```bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Test docker is working
sudo docker run hello-world

# Install docker compose

sudo apt-get update
sudo apt-get install docker-compose-plugin

# Test the docker version
docker compose version
```

## Setup Ronin Node

Make and switch to the working directory for the ronin node

```bash
mkdir -p ~/ronin/docker
cd ~/ronin
```

Make a directory for the chain data

```bash
mkdir -p chaindata/data/ronin
```

Go into the `docker` directory, create a `docker-compose.yml` file with the following configuration:

```bash
version: "3"
services:
  node:
    image: ${NODE_IMAGE}
    stop_grace_period: 5m
    stop_signal: SIGINT
    hostname: node
    container_name: node
    ports:
      - 127.0.0.1:8545:8545
      - 127.0.0.1:8546:8546
      - 30303:30303
      - 30303:30303/udp
      - 6060:6060
    volumes:
      - ~/ronin/chaindata:/ronin
    environment:
      - SYNC_MODE=full
      - PASSWORD=${PASSWORD}
      - NETWORK_ID=${NETWORK_ID}
      - RONIN_PARAMS=${RONIN_PARAMS}
      - VERBOSITY=${VERBOSITY}
      - MINE=${MINE}
      - GASPRICE=${GASPRICE}
      - ETHSTATS_ENDPOINT=${INSTANCE_NAME}:${CHAIN_STATS_WS_SECRET}@${CHAIN_STATS_WS_SERVER}:443
```

This compose file defines the `node` service that pulls a Ronin node image from the GitHub Container Registry.

Create an `.env` file and add the following content, replacing the `<...>` placeholder values with your information:

```bash
# The name of your node that you want displayed on https://ronin-stats.roninchain.com/
INSTANCE_NAME=<INSTANCE_NAME>

# The latest version of the node's image as listed in https://docs.roninchain.com/validators/setup/upgrade-validator
NODE_IMAGE=<NODE_IMAGE>

# The password used to encrypt the node's private key file
PASSWORD=<PASSWORD>

MINE=false

NETWORK_ID=2020
GASPRICE=20000000000
VERBOSITY=3

CHAIN_STATS_WS_SECRET=WSyDMrhRBe111
CHAIN_STATS_WS_SERVER=ronin-stats-ws.roninchain.com

RONIN_PARAMS=--http.api eth,net,web3,consortium --txpool.pricelimit 20000000000 --txpool.nolocals --cache 4096 --discovery.dns enrtree://AIGOFYDZH6BGVVALVJLRPHSOYJ434MPFVVQFXJDXHW5ZYORPTGKUI@nodes.roninchain.com
```

(Optional) Download the snapshot from the [ronin-snapshot](https://github.com/axieinfinity/ronin-snapshot) repo - If you want to sync the ronin chain data in time and not wait for weeks before it is fully synced.

```bash
cd ~/ronin/chaindata/data/ronin/
wget -q -O - <snapshot URL from the README file in the repo> | tar -I zstd -xvf -
```

## Run the node

```bash
cd ~/ronin/docker && docker-compose up -d
```

## Monitor the node

Use docker logs to monitor the rootstock node. The -f flag ensures you are following the log output.

```bash
docker logs node -f --tail 100
```

You should see a response similar to this once your node starts syncing

```
INFO [11-14|21:24:17.122] Imported new chain segment               blocks=1          txs=11          mgas=1.280   elapsed=16.911ms   mgasps=75.657  number=39,923,835 hash=1afff2..417928 dirty=0.00B
INFO [11-14|21:24:20.156] Imported new chain segment               blocks=1          txs=16          mgas=3.102   elapsed=25.749ms   mgasps=120.449 number=39,923,836 hash=52613d..18b334 dirty=0.00B
INFO [11-14|21:24:23.139] Imported new chain segment               blocks=1          txs=15          mgas=3.349   elapsed=30.903ms   mgasps=108.379 number=39,923,837 hash=e34fa3..50d71d dirty=0.00B
INFO [11-14|21:24:26.089] Imported new chain segment               blocks=1          txs=12          mgas=1.821   elapsed=20.431ms   mgasps=89.147  number=39,923,838 hash=7b568b..250cb0 dirty=0.00B
INFO [11-14|21:24:29.155] Imported new chain segment               blocks=1          txs=18          mgas=4.263   elapsed=26.391ms   mgasps=161.523 number=39,923,839 hash=f16921..a764e8 dirty=0.00B
INFO [11-14|21:24:30.882] Deep froze chain segment                 blocks=20         elapsed=5.064ms    number=39,833,839 hash=925558..afa3ca
INFO [11-14|21:24:32.101] Imported new chain segment               blocks=1          txs=7           mgas=1.347   elapsed=18.884ms   mgasps=71.350  number=39,923,840 hash=d1019d..13e80a dirty=0.00B
INFO [11-14|21:24:35.177] Imported new chain segment               blocks=1          txs=14          mgas=2.823   elapsed=23.487ms   mgasps=120.211 number=39,923,841 hash=5e0d2a..f2691b dirty=0.00B
```

## Query the node

To get the web3 client version

```bash
curl http://localhost:8545 -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}'
```

Output

```bash
{"jsonrpc":"2.0","id":67,"result":"ronin/v2.8.3-d27eb42e/linux-amd64/go1.20.10"}
```

To check the block number

```bash
curl -X POST http://localhost:8545/ -H "Content-Type: application/json" --data '{"jsonrpc":"2.0", "method":"eth_blockNumber","params":[],"id":1}'
```

Output

```bash
{"jsonrpc":"2.0","id":1,"result":"0x26130a0"}
```

## References

{% embed url="<https://docs.roninchain.com/validators/setup/mainnet/run-archive>" %}

{% embed url="<https://docs.roninchain.com/rpc/mainnet-rpc>" %}


# Baremetal

Author: \[ jleopoldA ]

## System Requirements

| CPU    | OS                 | RAM   | DISK    |
| ------ | ------------------ | ----- | ------- |
| 8 Core | Ubuntu 24.04.1 LTS | 32 GB | 7TB SSD |

{% hint style="info" %}
Ronin has a size of 5.8TB as of 1/15/2025.
{% endhint %}

## Pre-Requisites

{% hint style="info" %}
Ronin requires the installation of Go.
{% endhint %}

### Update System

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
```

### Set up Firewall

#### Set Explicit Default Firewall Rules

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow Remote RPC Connections with Ronin Node

```bash
sudo ufw allow 8545
sudo ufw allow 8546
```

#### Allow P2P Connections

```bash
sudo ufw allow 30303/tcp && sudo ufw allow 30303/udp
```

#### Enable Firewall

```bash
sudo ufw enable
```

#### To Check Status / Current Rules of UFW&#x20;

```bash
sudo ufw status verbose
```

### Install GO

{% hint style="info" %}
This step is necessary if GO is not installed.
{% endhint %}

#### Check for latest version of GO

```bash
# This will return the latest version of GO
curl -s https://go.dev/VERSION?m=text

# Example response
go1.23.3
time 2024-11-06T18:46:45Z
```

#### Download the latest GO Tarball

```bash
# Downloading using the above example response
wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz

# Example command if the above version is different
wget https://go.dev/dl/VERSION.linux-amd64.tar.gz
```

#### Extract and Install GO

```bash
sudo tar -C /usr/local -xzf go1.23.3.linux-amd64.tar.gz 
```

#### Set Up Environment Variables

```bash
echo "export PATH=\$PATH:/usr/local/go/bin" >> ~/.bashrc
source ~/.bashrc
```

#### Check Installation

```bash
go version

# Example response
go version go1.23.3 linux/amd64
```

## Install Ronin

### Clone the Ronin Repo

```bash
cd /root

# The below command will create a directory called 'ronin'
# The path to it will be /root/ronin
git clone https://github.com/axieinfinity/ronin
```

### Build Ronin

```bash
cd /ronin/cmd/ronin
go build -o ronin
```

### Initialize Ronin Genesis Block

{% hint style="info" %}
Ronin requires the initialization of its Genesis Block before being run.
{% endhint %}

```bash
./ronin init --datadir /opt/ronin /root/ronin/genesis/mainnet.json
```

## Create System Service

```bash
# Copy and paste the code below and run it within your terminal.
sudo echo "[Unit]
Description=Ronin Node
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/ronin/
ExecStart=/root/ronin/cmd/ronin/ronin \
	--gcmode archive --syncmode full \
	--http --http.addr 0.0.0.0 --http.api eth,net,web3 --http.port 8545 \
	--ws --ws.addr 0.0.0.0 --ws.port 8546 --ws.api eth,net,web3 \
	--datadir /opt/ronin \
        --port 30303 --networkid 2020 \
	--discovery.dns enrtree://AIGOFYDZH6BGVVALVJLRPHSOYJ434MPFVVQFXJDXHW5ZYORPTGKUI@nodes.roninchain.com
Restart=on-failure
LimitNOFILE=1000000
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/ronin.service
```

## Run Ronin Node

```bash
sudo systemctl daemon-reload # Refresh after systemd configuration changes
sudo systemctl enable ronin.service # Enable ronin.service at start up
sudo systemctl start ronin.service # Starts ronin.service
sudo systemctl stop ronin.service # Stops ronin.service
sudo systemctl restart ronin.service # Restarts ronin.service
```

### View Logs for Debugging

```bash
journactl -fu ronin.service -xe
```

### Query Ronin Node

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:8545

# Example response
{"jsonrpc":"2.0","id":1,"result":"0x40e2d5"}
```

## References

{% embed url="<https://github.com/axieinfinity/ronin>" %}

{% embed url="<https://docs.roninchain.com/protocol/validators/setup/overview>" %}


# Rootstock


# Docker

Author \[abstractCube]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

Comment

| CPU      | OS           | RAM  | DISK     |
| -------- | ------------ | ---- | -------- |
| 2 cores+ | Ubuntu 24.04 | 8GB+ | >= 128GB |

{% hint style="info" %}
*The Rootstock Mainnet archive node has a size of 132GB on September 22nd, 2024*
{% endhint %}

Last updated: 22nd Sept 2024

Official docs - <https://dev.rootstock.io/node-operators/>

## Pre-Requisites

First, update, upgrade, and clean the system:

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt auto-remove -y
sudo apt install ufw -y
```

## Configure Firewall Settings&#x20;

```bash
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 4444
```

## Install Docker

Run this command to remove any conflicting docker

```bash
`for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done`
```

Add Docker's official GPG key:

```bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
```

Add the repository to ppt sources:

```bash
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
```

Install docker

```bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Test docker is working
sudo docker run hello-world

# Install docker compose

sudo apt-get update
sudo apt-get install docker-compose-plugin

# Test the docker version
docker compose version
```

## Setup Rootstock Node

Make and switch to the working directory for the Rootstock node

```bash
mkdir rootstock && cd rootstock
```

Create and edit the configuration file:

```bash
nano node.conf
```

Paste the following content into the file You can find all the configuration options [here](https://dev.rootstock.io/node-operators/setup/configuration/reference/)

If you are interested in running the config for other networks, you can find the configs [here](https://github.com/rsksmart/rskj/tree/master/rskj-core/src/main/resources/config)

```bash
blockchain.config.name = "main"

database.dir = /var/lib/rsk/database/mainnet

rpc {
providers : {
    web: {
        cors: "localhost",
        http: {
            enabled: true,
            bind_address = "0.0.0.0",
            hosts = ["localhost"]
            port: 4444,
            }
        ws: {
            enabled: false,
            bind_address: "0.0.0.0",
            port: 4445,
            }
        }
    }

    modules = [
        {
            name: "eth",
            version: "1.0",
            enabled: "true",
        },
        {
            name: "net",
            version: "1.0",
            enabled: "true",
        },
        {
            name: "rpc",
            version: "1.0",
            enabled: "true",
        },
        {
            name: "web3",
            version: "1.0",
            enabled: "true",
        },
        {
            name: "evm",
            version: "1.0",
            enabled: "true"
        },
        {
            name: "sco",
            version: "1.0",
            enabled: "false",
        },
        {
            name: "txpool",
            version: "1.0",
            enabled: "true",
        },
        {
            name: "debug",
            version: "1.0",
            enabled: "false",
        },        
        {
            name: "personal",
            version: "1.0",
            enabled: "true"
        }
    ]
}
```

Create and edit the docker compose file

```bash
nano docker-compose.yml
```

Paste the content into the compose file.

In this Docker Compose file, we are utilizing the prebuilt Rootstock node image available on [dockerhub](https://hub.docker.com/r/rsksmart/rskj), where you can also find other prebuilt images.

````bash
services:
  rsk-node:
    image: rsksmart/rskj:ARROWHEAD-6.3.1
    container_name: rsk-node
    ports:
      - 5050:5050
      - 4444:4444
    volumes:
      - rsk-data:/var/lib/rsk/.rsk
      - ./node.conf:/etc/rsk/node.conf
    restart: unless-stopped
volumes:
  rsk-data:
```
This section mounts the host's data directory for blockchain storage and the node.conf file for configuration into the container,
```bash
volumes:
      - ./data:/var/lib/rsk/.rsk
      - ./node.conf:/etc/rsk/node.conf
````

## Run the node

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

## Monitor the node

Use docker logs to monitor the rootstock node. The -f flag ensures you are following the log output.

```bash
docker logs -f rsk-node
```

You should see a response similar to this once your node starts syncing

```
2024-09-16-21:23:20.0646 INFO [blockchain] [message handler] [blockHash=c6225969d4795419027f98269b1c5c0f2a6afc2a0a5f399fcaa607c27a2c484a, peerMsgId=iCvIT12JZvyWvki, peerSID=8dfb1d6268b4b13, blockHeight=1309986]  block: num: [1309986] hash: [c6225969d4795419027f98269b1c5c0f2a6afc2a0a5f399fcaa607c27a2c484a], processed after: [0.005189]seconds, result IMPORTED_BEST
2024-09-16-21:23:20.0676 INFO [blockchain] [message handler] [blockHash=39a7299155cebca0b4f22ddbf49ce1c39f7d230e21aa7061874f2894d43b4847, peerMsgId=g7k643wFWTOWBfZ, peerSID=8dfb1d6268b4b13, blockHeight=1309987]  block: num: [1309987] hash: [39a7299155cebca0b4f22ddbf49ce1c39f7d230e21aa7061874f2894d43b4847], processed after: [0.005022]seconds, result IMPORTED_BEST
2024-09-16-21:23:20.0706 INFO [blockchain] [message handler] [blockHash=9c5b971fb0094e922c5e517f11324e17babed9c14a33e426a5f7984b1701fe37, peerMsgId=akXn9XtqflGiK4y, peerSID=8dfb1d6268b4b13, blockHeight=1309988]  block: num: [1309988] hash: [9c5b971fb0094e922c5e517f11324e17babed9c14a33e426a5f7984b1701fe37], processed after: [0.005072]seconds, result IMPORTED_BEST
2024-09-16-21:23:20.0735 INFO [blockchain] [message handler] [blockHash=53677df4e16affaf09da709a42a288e4df376ee16c97d76f25e862113f59680d, peerMsgId=n5RGPtCFbshskYG, peerSID=8dfb1d6268b4b13, blockHeight=1309989]  block: num: [1309989] hash: [53677df4e16affaf09da709a42a288e4df376ee16c97d76f25e862113f59680d], processed after: [0.004886]seconds, result IMPORTED_BEST
```

## Query the node

To get the web3 client version

```bash
curl http://localhost:4444 -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}'
```

Output

```bash
{"jsonrpc":"2.0","id":67,"result":"RskJ/6.3.1/Mac OS X/Java1.8/ARROWHEAD-202f1c5"}
```

To check the block number

```bash
curl -X POST http://localhost:4444/ -H "Content-Type: application/json" --data '{"jsonrpc":"2.0", "method":"eth_blockNumber","params":[],"id":1}'
```

Output

```bash
{"jsonrpc":"2.0","id":1,"result":"0x14144a"}
```

## References

{% embed url="<https://hub.docker.com/r/rsksmart/rskj>" %}

{% embed url="<https://dev.rootstock.io/node-operators/>" %}


# Baremetal

Author: \[ jleopoldA ]

### System Requirements <a href="#system-requirements" id="system-requirements"></a>

Comment

| CPU     | OS                    | RAM     | DISK  |
| ------- | --------------------- | ------- | ----- |
| 2 Cores | Debian / Ubuntu 22.04 | 8Gb RAM | 128GB |

{% hint style="info" %}
Rootstock has a size of 118GB on October 9, 2024.
{% endhint %}

{% hint style="danger" %}
Using a version of Rootstock that is below 6.3.1 will result in issues that prevent successful syncing.
{% endhint %}

## Pre-Requisites

```bash
sudo apt update -y && sudo apt upgrade -y && sudo apt autoremove -y
```

### Setting up Firewall

#### Set explicit default UFW rules

```bash
# Set explicit default UFW rules
sudo ufw default deny incoming
sudo ufw default allow outgoing
```

#### Allow SSH

```bash
sudo ufw allow 22/tcp
```

#### Allow remote RPC connections with Rootstock node

```bash
sudo ufw allow 4444
sudo ufw allow 4445
```

#### Allow P2P Connections

```bash
sudo ufw allow 30303/tcp
sudo ufw allow 30303/udp
```

#### Enable Firewall

```bash
sudo ufw enable
```

#### To check status of UFW and see the current rules

```bash
sudo ufw status verbose
```

## Building a Node on Rootstock

### Dependencies

{% hint style="info" %}
Rootstock uses Java 8
{% endhint %}

#### Install Java

```bash
# If you have a previous version of Java - remove it.
sudo apt purge openjdk-*

# Remove unused packages
sudo apt autoremove

# Install Java 8
sudo apt install openjdk-8-jdk

# Verify Installation
java -version
```

#### Create Directories for Rootstock

```bash
# Create directory for Rootstock
mkdir /root/rootstock 

# Create a folder for configuration
mkdir /root/rootstock/config
```

#### Create Configuration File

```bash
# Create Configuration File
nano /root/rootstock/config/node.conf
```

#### Paste the below Configuration into the file:

```bash
blockchain.config.name = "main"

database.dir = /root/rootstock/database/mainnet
rpc {
    providers: {
        web: {
            cors = "*"
                http: {
                    enabled = true
                    bind_address = 0.0.0.0
                    port = 4444
                    hosts = ["*"]
                }
                ws: {
                    enabled = true
                    bind_address = 0.0.0.0
                    port = 4445
                }
        }
    }
    modules = {
        eth { version: "1.0", enabled: "true"},
        net { version: "1.0", enabled: "true"},
        rpc { version: "1.0", enabled: "true"},
        web3 { version: "1.0", enabled: "true"},
        evm { version: "1.0", enabled: "true"},
        sco { version: "1.0", enabled: "false"},
        txpool { version: "1.0", enabled: "true"},
        debug { version:"1.0", enabled: "true"},
        personal { version: "1.0", enabled: "false"}
    }
}
```

> `Ctrl + X and Y` to exit and confirm saving changes to a file.

#### Create Data Directory to store chain data for Rootstock blockchain.

```bash
mkdir /root/rootstock/database/mainnet/
```

#### Download Rootstock

```bash
# Download Rootstock within your "rootstock" directory.
cd ./root/rootstock/
git clone --recursive https://github.com/rsksmart/rskj.git
cd rskj
git checkout tags/ARROWHEAD-6.3.1 -b ARROWHEAD-6.3.1
```

#### Ensure the Security Chain

{% hint style="info" %}
Rootstock advises to ensure the security chain. Follow the verification steps provided here: [**Verify security chain of RSKj source code**](https://dev.rootstock.io/node-operators/setup/security-chain/)
{% endhint %}

#### Get External Dependencies

```bash
# From within the root of your "rskj" directory, run the following.
./configure.sh
# This will download and set important components (ex. Gradle Wrapper)
```

#### Compile the node

```bash
# From within the root of your "rskj" directory, run the following.
./gradlew build -x test
```

### Create systemd service for Rootstock node

```bash
# Copy and paste the code below and run it within your terminal.
sudo echo "[Unit]
Description=Rootstock Node
After=network.target
StartLimitIntervalSec=200
StartLimitBurst=5

[Service]
Type=simple
Restart=on-failure
RestartSec=5
TimeoutSec=900
User=root
Nice=0
LimitNOFILE=200000
WorkingDirectory=/root/rootstock/rskj/rskj-core/build/libs/
ExecStart=/usr/bin/java -Drsk.conf.file=/root/rootstock/config/node.conf -jar /root/rootstock/rskj/rskj-core/build/libs/rskj-core-6.3.1-ARROWHEAD-all.jar co.rsk.Start

KillSignal=SIGTERM

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/rootstock.service
```

### Start Rootstock Node

```bash
sudo systemctl daemon-reload # refresh for systemd configuration changes

sudo systemctl enable rootstock.service # enable rootstock.service at start up

sudo systemctl start rootstock.service # start rootstock.service
```

#### View Logs for Debugging

{% hint style="info" %}
This method of installing does not allow you to view sync progress.
{% endhint %}

```bash
journalctl -fu rootstock.service
```

### Query Rootstock Node

```bash
curl -H "Content-Type: application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' http://localhost:4444

# The response should resemble the follow
{"jsonrpc":"2.0","id":1,"result":"0xcab5ab"}
```

### References

{% embed url="<https://dev.rootstock.io/node-operators/setup/node-runner/linux/>" %}

{% embed url="<https://dev.rootstock.io/node-operators/setup/configuration/preferences/>" %}




---

[Next Page](/llms-full.txt/1)

