Building a group messaging CorDapp using Corda multi RPC

Corda Aug 31 2021 By: Ollie Gilbey
Comments

0 Comments

Views

154 Views

Building a group messaging CorDapp using Corda multi RPC
Ollie Gilbey
Ollie Gilbey Blockchain Development (Corda Open Source)
Share This Post:
Copied

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:

  1. Clone the samples-java repo from GitHub. You will find the multirpc-chainmail sample in the features directory. 
  2. Open this project using IntelliJ. 
  3. Run the following commands to deploy and run the nodes:
    ./gradlew deployNodes
    ./build/nodes/runnodes
  4. 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 HAADDRESSPOOL

    ATTEMPTING 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.
  5. Change to the  multirpc-chainmail/clients/src/main/webapp directory, then run:
    npm install
    npm start
    This will start the front end and automatically open localhost:3000 in your browser.
  6. 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 by Node: 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!

Ollie Gilbey
Ollie Gilbey Oliver Gilvey is a Developer Evangelist at R3, an enterprise blockchain software firm working with a global ecosystem of more than 350 participants across multiple industries from both the private and public sectors to develop on Corda, its open-source blockchain platform, and Corda Enterprise, a commercial version of Corda for enterprise usage.

Leave a Reply

Subscribe to our newsletter to stay up to date on the latest developer news, tools, and articles.