Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

To automatically reformat the code before creating a pull request, run:

./gradlew spotlessApply

You can set up a pre-commit (or pre-push) hook following this guide (optional) https://medium.com/@mmessell/apply-spotless-formatting-with-git-pre-commit-hook-1c484ea68c34


pre-push hook example - save as .git/hooks/pre-push in the root of your besu working dir

#!/bin/sh
echo "Running spotlessApply. Formatting code..."
./gradlew spotlessApply --parallel
echo "checking if any files required spotless alterations"
stagedFiles=$(git diff --name-only)

for file in $stagedFiles; do
  if test -f "$file"; then
    echo "!! spotlessApply results need commit - aborting push"
    exit 1 # exit if spotless check failed
  fi
done

Install Google Style Settings

The Google style settings can be installed in Intellij and Eclipse (the xml file is in the gradle dir of the besu repo so should be picked up automatically).

Additional Java Style Guidelines

...

To help future-proof the code (avoiding libraries that may be deprecated in the near future), avoid assertions from the org.assertj.core.api.Java6Assertions class. Java6 in the name is a concerning signal

...

Miscellaneous

...

  • When creating loggers it should be the first declaration in the class with:

...

  • Ternary operators are acceptable when they make the code clearer but should never be nested
  • Avoid TODO comments. Log a ticket instead
  • Specify Gradle dependency versions in versions.gradle
  • Don't use two or more blank lines in a row (although this should be handled by spotless)

Logging

Logging is important for understanding what Besu is doing at any given time (for example, progress while synchronizing) and investigating defects. During development, add logging to aid in these cases.

  • When creating loggers it should be the first declaration in the class, for example:
private static final Logger LOG = LoggerFactory.getLogger(MergeCoordinator.class);

Log Messages

Make log messages:

...

  • Trace - Extremely detailed view showing the execution flow. Likely only useful to developers
  • Debug - Information that is diagnostically helpful to a wider group than just developers (for example, sysadmins)
  • Info - Generally useful information to log (for example, service start/stop, configuration assumptions). Default logging level
  • Warn - Anything that can potentially cause application oddities but from which Besu automatically recovers
  • Error - Any error which is fatal to the operation, but not Besu itself (for example, missing data)
  • Fatal - An error that forces a shutdown of Besu

INFO Principles

  • Aimed at users
  • Should indicate any relevant progress for example sync, peering, worldstate download
  • Should not present errors or warnings that require no intervention

DEBUG Principles

  •  Aimed at both end users and developers
  •  Should lead to resolution of common problems, whilst not spamming
  •  Should not contain logs that take up more than one terminal screen, e.g. raw data, including RLP

DEBUG Guidelines

  • Should not include peer discovery
  • Should not include txpool management
  • Could include some peering to debug peering issues
  • Could include some high level syncing logs
  • Could include API requests, including potentially truncated data, but not full RLP

TRACE Principles

  • Aimed at developers
  • Expectation is everything is there and it's spammy
  • Only useful when targeting certain packages/classes

For any log level past INFO, you will see in the code this pattern which is used to avoid unnecessary runtime processing.

LOG.atDebug()
.setMessage(
"disconnecting peer {}. Waiting for better peers. Current {} of max {}")
.addArgument(peer::getLoggableId)
.addArgument(this::peerCount)
.addArgument(this::getMaxPeers)
.log();