Overview
The Quorum client is a modified geth client. One of the unique enhancements
is the pluggable architecture which allows adding additional features as plugins to the core geth,
providing extensibility, flexibility, and isolation of Quorum features.
Benefits¶
This enhancement provides a number of benefits, including:
- Allowing the implementation of certain components of the Quorum client to be changed at configuration time.
- Supporting our community to improve the Quorum client with their own innovative implementations of the supported pluggable components.
- Decoupling new Quorum-specific features from core
geththereby simplifying the process of pulling in changes from upstreamgeth.
How it works?¶
Each plugin exposes an implementation for a specific plugin interface (or see Pluggable Architecture -> Plugins for more details)
Plugins are executed as a separate process and communicate with the main Quorum client geth process
over a gRPC interface.
The plugin implementation must adhere to certain gRPC services defined in a .proto file corresponding to the plugin interface.
Plugins can be written in different languages as gRPC provides a mechanism to generate stub code from .proto files.
The network communication and RPC are handled automatically by the high-level plugin library.
Installing Plugins¶
Currently plugins must be manually installed into a directory (defaults to plugins directory inside geth data directory - default can be overriden by setting baseDir in plugins settings).
Using Plugins¶
Plugins settings file contains a JSON that describes what plugins to be used.
Then start geth with --plugins as below:
geth ... \
--plugins file:///<path>/<to>/plugins.json
Plugin Integrity Verification¶
Plugin Central Server can be used to download and verify plugin integrity using PGP.
The architecture enables the same verification process locally via --plugins.localverify and --plugins.publickey flags or
remotely with custom plugin central - reference the Settings section for more information on how to support custom plugin central.
If the flag --plugins.skipverify is provided at runtime the plugin verification process will be disabled.
Warning
Using --plugins.skipverify is not advised for production settings and it should be avoided as it introduces security risks.
Example: HelloWorld plugin¶
The plugin interface is implemented in Go and Java. In this example, HelloWorld plugin exposes a JSON RPC endpoint
to return a greeting message in the configured language.
This plugin is reloadable. It means that the plugin can take changes from its JSON configuration.
Build plugin distribution file¶
- Clone plugin repository
› git clone --recursive https://github.com/jpmorganchase/quorum-plugin-hello-world.git › cd quorum-plugin-hello-world - Here we will use Go implementation of the plugin
quorum-plugin-hello-world› cd go quorum-plugin-hello-world/go› makequorum-plugin-hello-world-1.0.0.zipis now created inbuilddirectory. Noticed that there’s a filehello-world-plugin-config.jsonwhich is the JSON configuration file for the plugin.
Start Quorum with plugin support¶
- Build Quorum
› git clone https://github.com/jpmorganchase/quorum.git › cd quorum quorum› make geth - Copy
HelloWorldplugin distribution file and its JSON configurationhello-world-plugin-config.jsontobuild/bin - Create
geth-plugin-settings.jsonquorum› cat > build/bin/geth-plugin-settings.json <<EOF { "baseDir": "./build/bin", "providers": { "helloworld": { "name":"quorum-plugin-hello-world", "version":"1.0.0", "config": "file://./build/bin/hello-world-plugin-config.json" } } } EOF - Run
gethwith pluginquorum› PRIVATE_CONFIG=ignore \ geth \ --nodiscover \ --verbosity 5 \ --networkid 10 \ --raft \ --raftjoinexisting 1 \ --datadir ./build/_workspace/test \ --rpc \ --rpcapi eth,debug,admin,net,web3,plugin@helloworld \ --plugins file://./build/bin/geth-plugin-settings.json \ --plugins.skipverify
ps -ef | grep helloworldwould reveal theHelloWorldplugin process
Test the plugin¶
- Call the JSON RPC
quorum› curl -X POST http://localhost:8545 \ -H "Content-type: application/json" \ --data '{"jsonrpc":"2.0","method":"plugin@helloworld_greeting","params":["Quorum Plugin"],"id":1}' {"jsonrpc":"2.0","id":1,"result":"Hello Quorum Plugin!"}
- Update plugin config to support
eslanguage# update language to "es" quorum› vi build/bin/hello-world-plugin-config.json - Reload the plugin
quorum› curl -X POST http://localhost:8545 \ -H "Content-type: application/json" \ --data '{"jsonrpc":"2.0","method":"admin_reloadPlugin","params":["helloworld"],"id":1}' {"jsonrpc":"2.0","id":1,"result":true}
- Call the JSON RPC
quorum› curl -X POST http://localhost:8545 \ -H "Content-type: application/json" \ --data '{"jsonrpc":"2.0","method":"plugin@helloworld_greeting","params":["Quorum Plugin"],"id":1}' {"jsonrpc":"2.0","id":1,"result":"Hola Quorum Plugin!"}