The MultiRPC: ChainMail sample CorDapp has been released in our samples-java repo. This post explores the sample CorDapp and talks about using the Corda multi RPC client.
If you’re interested in learning more about the standard Corda RPC client and about RPC in general, read Corda RPC reconnecting client—a great blog written by Sneha.
What is RPC?
In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it were a normal (local) procedure call, without the programmer explicitly coding the details for the remote interaction (Wikipedia).
In Sneha’s blog, she mentioned that for all of Corda’s use cases, you’ll want to use an external application to interact with a node. This could be a legacy application or a new application that provides an enhanced user experience.
Introducing the MultiRPC: ChainMail sample CorDapp
The MultiRPC: ChainMail sample demonstrates how you can implement RPC in a more Highly-Available (HA) fashion, which enables failover if a node goes offline. This is achieved by using the built-in Corda Multi RPC Client library.
To demonstrate how Corda’s Multi RPC Client works, we have built a group messaging CorDapp that allows group communication between nodes—much like a group chat on your favorite messaging platform. The difference here is that as it uses Blockchain, or Distributed Ledger Technology (DLT), a message will only be shown to all participants of the chat if every participant signs that they have received the message. The best way of seeing this in action is by running the CorDapp yourself.
Running the MultiRPC: ChainMail sample CorDapp
Firstly, you need to clone the CorDapp and get your nodes up and running:
- Clone the samples-java repo from GitHub. You will find the
multirpc-chainmail
sample in thefeatures
directory. - Open this project using IntelliJ.
- Run the following commands to deploy and run the nodes:
./gradlew deployNodes
./build/nodes/runnodes
- Attach the Spring webserver:
./gradlew runChainMailServer
You should see some logs that confirm the connection to the nodes has been established:INITIALISING NODE RPC CONNECTION
ATTEMPTING MULTIRPC WITH HAADDRESSPOOLATTEMPTING CLIENT START FROM NODERPCCONNECTION
LISTENER: CONNECTED
I 16:56:09 52 RPCClient.logElapsedTime - Startup took 1183 msec
The next stage is to get the React front end running with Node. - Change to the
multirpc-chainmail/clients/src/main/webapp
directory, then run:npm install
npm start
This will start the front end and automatically openlocalhost:3000
in your browser. - Try typing a message into the chat input box and hit enter. The message will only appear in the chat once all nodes have confirmed and signed the message. The message is invisible until it’s present in every participant’s node’s vault.
Once the message appears, you will notice that it was sent byNode: Alice
.
How the Multi RPC client works
The Multi RPC Client has received a list of ports to try to connect to in the form of an HA address pool. You can see this in the runChainMailServer
task in clients/build.gradle
:
task runChainmailServer(type: JavaExec, dependsOn: assemble) {
classpath = sourceSets.main.runtimeClasspath
main = 'net.corda.samples.chainmail.webserver.Starter'
args '--server.port=10052', '--config.rpc.host=localhost', '--config.rpc.port=10012,10013,10014,10015', '--config.rpc.username=user1', '--config.rpc.password=test'
}
This list of ports are passed to the NodeRPCConnection.java
class when the server is started, where they are parsed into an address pool and are then given to the MultiRPCClient
:
List rpcPorts = Arrays.asList(rpcPortsString.split(","));
for (String rpcPort: rpcPorts) {
NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, Integer.parseInt(rpcPort));
haAddressPool.add(rpcAddress);
}
MultiRPCClient client = new MultiRPCClient(haAddressPool, CordaRPCOps.class, username, password);
This defines the addresses that the Multi RPC Client can failover to if an address (node) goes offline.
You will also see that an RPCConnectionListener
has been added below that code block. By using the RPCConnectionListener interface, we can log or perform actions when certain events occur on the Multi RPC Client. Some of these logs were shown above in Step 4.
You can now take a look at what happens if the node that the webserver is connected to goes offline. Navigate to Alice’s node terminal and simply type bye
. This shuts down that Corda node as well as its RPC endpoint.
Looking at the terminal that runs the webserver, you will see that the listener has logged that a disconnection has occurred. RPCClientProxyHandler
then attempts to reconnect and finds an RPC server available
. This is due to the Multi RPC Client discovering the next available RPC server within its HAAddressPool
. Since the Multi RPC Client attempts servers in a round-robin fashion—and Alice’s node is down—Bob will be the next address to attempt a connection.
If you go back to your web browser, you will notice that the UI is still visible and active. Try sending a new message. It doesn’t appear in the chat! The message has been sent to all the participants on the network, however, because Alice is offline the message cannot be verified by all participants.
If you restart Alice’s node by entering java -jar corda.jar
inside Alice’s terminal, the flow will be retried and Alice will now be able to verify and sign the second message. This may take a couple of seconds, but the message will then show in the chat UI. However, what you will notice is that Bob’s node sent the message, rather than Alice’s. The Multi RPC Client has now switched over to using Bob’s node to send messages.
This architecture provides a useful failover and HA—if a message is sent when the initial node is down, it doesn’t simply fail and never gets received by the other parties. This is useful in a number of scenarios, such as cargo ship guidance systems communicating with each other and the port they intend to arrive at during foul weather. These ships can prove receipt of messages and make sure that the messages are delivered in an HA fashion. Therefore, each guidance system would know when all parties are aware of a new piece of information.
Have some fun sending messages and taking down and spooling up different nodes and see how the CorDapp behaves, and then have a deeper look into the code. It’s a fun sample to run and shows off a few different aspects of CorDapp development working in synergy.
Happy coding!