Skip to main content

Overview

Firedancer is a from-scratch validator client for Solana, designed to be fast, secure, and independent. This guide covers the code style conventions and development practices used throughout the project.
The code style is defined by the code in src/tango. Most contributors do not use automated code formatting tools.

Getting Started

Firedancer currently only supports Linux and requires at least kernel v4.18 to build.
1

Clone the repository

2

Install dependencies

3

Build and run

The make run target runs the fddev dev command, which will:
  • Ensure your system is configured correctly
  • Create a genesis block and keys
  • Start a faucet
  • Start a validator on the local machine
fddev will use sudo to make privileged changes to system configuration where needed. If sudo is not available, you may need to run the command as root.

Code Style Guide

General Conventions

Text Word Wrap

Aspire to word wrap text (comments, not code) at 72 columns for readability. This is the level the publishing industry has used for hundreds of years for making print easily readable with minimal eye strain.

File Extensions

Include Guards

Header files must use #ifndef include guards, not #pragma once. Given file: src/path/to/file/fd_file_name.h:

Vertical Alignment

Unlike popular code formatting tools, Firedancer uses vertical alignment for better readability.
Good:
Wrong:

Spacing Rules

Function Calls

No spaces for function calls with zero arguments:
For function calls with arguments, spaces inside brackets, no space before brackets:
Exception: No spaces with sizeof:
Exception: No spaces between double bracket macros:

Control Flow

Annotate uncommon error paths with FD_UNLIKELY. For single-line if statements, no braces required:
If a branch goes on a separate line, braces are mandatory:

Function Prototypes

  • Modifiers and return types on separate lines
  • One function argument per line
  • Vertically align function argument types and names

Type System

Integers

Use fd_util_base.h types instead of stdint.h integer types:

Booleans

Do not use bool (stdbool). Instead use int. The value 1 is “true” and the value 0 is “false”.

Function Documentation

  • Documentation for a function is typically before the function prototype in a comment block
  • Comments should mention the name of the function toward the beginning
  • Function declarations belonging to a public API must be documented
  • Implementations of these functions must not repeat the comment

Macros

These are recommendations. Depending on macro scope, these rules might not make sense.
Enclose arguments in braces:
Enclose macro bodies in do/while(0) scopes:
Only evaluate macro arguments once:

Portability

Build Capabilities

Firedancer aspires to compile under any LP64 environment. If any component has more assumptions (e.g. needs a POSIX-like target), it should check for these capabilities via the FD_HAS_{...} switches. Example Makefile:
Example C code:

Language Features

Try to stick to ISO C17. GNU C extensions are permitted as long as they are well supported by Clang and CBMC many years back.

Compiler Compatibility

As of 2024-Jul, Firedancer builds on GNU/Linux sysroots with:
  • GCC 8.5 or newer
  • Clang
  • CBMC
The “Frankendancer” build target (fdctl) only targets x86_64 with a Haswell-like minimum feature set (AVX2, FMA). Experimental support exists for:
  • musl Linux, macOS, FreeBSD, Solana (SVM) C programs
  • arm64, ppc64le, sBPFv1, sBPFv2

seccomp Sandbox

Firedancer uses a strict sandbox architecture on Linux platforms using seccomp. Be mindful of what syscalls glibc could use under the hood when using standard library APIs.
During initialization, a seccomp profile is installed to each tile containing rules for allowed syscalls. If a syscall is triggered unexpectedly, seccomp will crash Firedancer.

File I/O

Prefer fd_io over stdio.h for streaming file I/O. Make sure to handle EINTR correctly.

Security Best Practices

Fuzzing

Most code should be covered by fuzz tests. Try to:
  • Use graceful error handling instead of aborting/crashing/exiting
  • Provide test APIs for mocking state (e.g. encryption keys when fuzzing a network protocol)

Test Vectors

Firedancer runs a large set of test vectors in CI that tests conformance between Firedancer and Agave’s block, transaction, instruction, and VM execution down to the same error code.
1

Create test fixtures

Make a pull request into the test-vectors repository with your new fixtures. See solana-conformance for more information on generating fixtures.
2

Update Firedancer

Once the pull request is merged, make a pull request into Firedancer, updating contrib/test/test-vectors-fixtures/test-vectors-commit-sha.txt with the latest test vectors GitHub commit SHA.

Complex Function Exit

Sometimes complex control flow is unavoidable. A typical error is failure to release resources on variables that go out of scope. Instead of multiple return points, use a do/while scope:
In egregious cases, you may use the cleanup attribute to execute an inline function when a variable goes out of scope. See FD_SCRATCH_SCOPE_BEGIN in src/util/scratch/fd_scratch.h for examples.

Resources