This repository contains a Besu plugin that performs node connection and transaction permissioning by consulting on-chain smart contracts via transaction simulation.
- Main plugin entry point:
rbb.PermissioningPlugin - Supporting helpers:
rbb.PermissioningPluginFunctions
Following the aim of having permissioning rely upon smart contracts (on-chain permissioning), this plugin just "consults" the respective permisioning smart contracts already deployed on the blockchain through transaction simulation. For that, the plugin provides two environment variables for the user to inform the contracts' address:
--plugin-permissioning-node-ingress-address--plugin-permissioning-account-ingress-address
- Node connection permissioning: intercepts inbound/outbound peer connection attempts and checks if they are allowed by a smart contract (Node Ingress).
- Transaction permissioning: intercepts transactions and checks if they are allowed by a smart contract (Account/Transaction Ingress) using Besu’s transaction simulation.
The plugin integrates with Besu via:
PermissioningServiceBlockchainServiceTransactionSimulationServicePicoCLIOptions
And registers:
NodeConnectionPermissioningProviderTransactionPermissioningProvider
At startup, PermissioningPlugin.register acquires Besu services and registers two providers:
- Node provider that delegates to
checkConnectionAllowed(source, destination) - Transaction provider that delegates to
checkTxAllowed(transaction)
It also registers CLI options so you can configure the contract addresses.
- Besu asks the plugin whether a connection to a peer is permitted.
- The plugin builds a call to the Node Ingress contract function:
- Function signature (conceptual):
connectionAllowed(bytes32,bytes32,bytes16,uint16,bytes32,bytes32,bytes16,uint16) - ABI selector precomputed in
PermissioningPluginFunctions.NODE_FUNCTION_SIGNATURE_HASH
- Function signature (conceptual):
- The plugin uses node identity and endpoint data to build the call data and executes a read-only contract call (via transaction simulation) to get an allow/deny decision.
- The boolean result is returned to Besu to allow or block the connection.
- Besu asks the plugin whether a transaction is permitted.
- The plugin builds a call to the Account/Transaction Ingress contract function:
- Function signature (conceptual):
transactionAllowed(address,address,uint256,uint256,uint256,bytes) - ABI selector precomputed in
PermissioningPluginFunctions.TX_FUNCTION_SIGNATURE_HASH
- Function signature (conceptual):
- The plugin encodes sender/recipient, value, gas fields, and calldata. For simulation sizing, a static fake signature is provided in
PermissioningPluginFunctions. - Using
TransactionSimulationServiceandBlockchainService, the plugin simulates the call against the current head without broadcasting a transaction. - The simulation result determines if the transaction is permitted; the boolean is returned to Besu.
This approach mirrors Besu’s native on-chain permissioning strategy while keeping the logic inside a plugin.
To include transaction permissioning as a functionality of this plugin, it was necessary to understand how Besu performs this task. To do so, the source code was searched so as to track the classes and their hierarchy in this proccess. The Besu RunnerBuilder, Besu AccountPermissioningControler and the Besu TransactionSmartContractPermissioningController were the main source of inspiration/information for this plugin development.
You can configure the smart contract addresses via CLI flags or environment variables (names may vary depending on your implementation). CLI options are defined in PermissioningPlugin:
- Node permissioning contract:
- CLI:
--plugin-permissioning-node-ingress-address - Environment:
BESU_PLUGIN_PERMISSIONING_NODE_INGRESS_ADDRESS
- CLI:
- Transaction permissioning contract:
- CLI:
--plugin-permissioning-account-ingress-address - Environment:
BESU_PLUGIN_PERMISSIONING_ACCOUNT_INGRESS_ADDRESS
- CLI:
Examples:
--plugin-permissioning-node-ingress-address=0xabc...--plugin-permissioning-account-ingress-address=0xdef...
The plugin produces a self-contained “fat JAR” using Gradle Shadow.
- Build with wrapper:
./gradlew shadowJar
- Ensure your Besu node is configured.
- Create a plugins directory one level above the Besu executable if it doesn’t exist.
- Copy the fat JAR to the plugins/ directory.
- Start Besu adding the plugin CLI flags, for example:
besu \ --plugin-permissioning-node-ingress-address=0x0000000000000000000000000000000000000001 \ --plugin-permissioning-account-ingress-address=0x0000000000000000000000000000000000000002