C Language Implemented Tendermint ABCI


This article is about a C-ABCI program I implemented.

Original Author: XU LI
Chinese Version: C-ABCI

Brief Introduction

This article will focus on the implementation of C-ABCI which means use C language to implement Tendermint ABCI ! First of all,let’s brief introduce Tendermint and ABCI:

Temdermint’s core is consensus engine, it would be responsible for:

  • Sharing blocks and transactions between nodes
  • Establishing a canonical/immutable order of transactions (the blockchain)

ABCI(Application BlockChain Interfac) is interface between Tendermint and Application, which means Application will use ABCI to communicate with Tendermint. It can be implemented with any language, so far it’s been implemented with C++ and JavaScript, Java, Erlang. But not include C language, so I took the chance, use C language implemented C-ABCI.

Learn more about Tendermint: Tendermint Intro
Learn more about ABCI : ABCI Overview
Source code of C-ABCI : chainx-org/c-abci

How to run C-ABCI demo?

This is pretty easy part, there’s only five step to run a C-ABCI demo, do as the following:

Step 1: Install Tendermint

Install Tendermint into your computer, here is the guide of Installation of Tendermint

Step 2: Clone code

Clone the C-ABCI source code to your computer:

1
git clone https://github.com/chainx-org/c-abci.git   ~/work/c/c-abci

This is where I keep C-ABCI source code, you can chose your own path to keep it.

Step 3: Compile code

Enter into c-abci directory and compile the C-ABCI:

1
2
cd ~/work/c/c-abci
make

when you successfully compile the C-ABCI, you will see the terminal output like this:

And in the c-abci/bin directory you will see the c-dummy binary file, it can be executed !

Step 4: Run test program

Enter into c-abci/bin directory and run c-dummy program:

1
2
cd  bin/
./c-dummy

Step 5: Run Tendermint

Run Tendermint program:

If it is your first time run Tendermint in your computer, execute command:

1
2
tendermint init
tendermint node

If you have already run Tendermint in your computer , then execute command:

1
2
tendermint unsafe_reset_all
tendermint node

This is whole procedure of How to run C-ABCI demo. Here is the video of runing C-ABCI:

C-ABCI code framework

Tendermint provides two methods to communicate with, that’s GRPC and TSP ! C-ABCI chose the latter, it use TCP protocol to implement communication module. Tendermint keep three connections: Mempool Connection, Consensus Connection, Query Connection. Connections Introduction. In C-ABCI’s implementation each connection has it’s own process to dispose the connection’s request, maybe latter on I will implement another version which use separated threads to dispose each connection.

As we said before, ABCI is a interface, in C language term it means that C-ABCI is a library which provides three interfaces. Application can use C-ABCI library to communicate with Tendermint. C-ABCI doesn’t interested in the data which Application and Tendermint communicate with, it’s just a transmitter. Data transmission between Tendermint and C-ABCI is relay on TCP Socket, but C-ABCI and Application data transmission use callback function to achieve!

Processing flow among Tendermint, Application, C-ABCI:

  1. Tendermint send a request to C-ABCI
  2. C-ABCI receive the request and parse request data, then pass the data to the callback function which is Application implemented
  3. The callback function according to request type to act different with the data, and pass the result to C-ABCI via callback function return value
  4. C-ABCI pack the returned value and send it to Tendermint

In C-ABCI source code, there have been seven directories , each directory represent a individual modular except include directory. The sheet below describes each directory:

directory description
include Include all modular head files
socket Communication modular which implemented communication of network based on TCP Socket
encoding Character conversion modular which implemented conversion between unsigned char and unsigned integer of big endian and little endian
dlist Data storage modular which use Circular Doubly Linked List to store data
type Data type modular which dispose Tendermint data type, produce from Tendermint type.proto file with protobuf-c software
core C-ABCI core modular which provides three interface to Application
demo C-ABCI demo which is very simple Application for show you how to use C-ABCI library

How to build a Application on top of C-ABCI?

Even though C-ABCI have seven directories, there only have two directories you have to study:

  • core : use this modular to code Application’s framework
  • type : use this modular to malloc data struct and free data struct

I have already implemented a very simple application called c-dummy in c-abci/demo directory, you can draw lessons from it.

C-ABCI is very easy to start on, it provides only three interfaces which is all you need to code a Application framework!

The three interfaces is:

Initialize C-ABCI serve

Bind and listen the provided IP address and port.

1
int server_init(const char *ipaddr, const char *port);

Start C-ABCI serve

It will not return until some error occurred. app is callback function which need Application to implemented.

1
int server_start(Application app)

Stop C-ABCI server

Close listened socket.

1
void server_stop();

You just need write this three functions in your Application’s main function then the code framework of your Application is completed (see main function in main.c file of c-abci/demo/ directory) !

Rest of the work is to implement callback function which you provide to server_start function. It should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void *ABCIApplication(Types__Request *request)
{
switch( request->value_case )
{
case TYPES__REQUEST__VALUE_INFO:
return Info();
case TYPES__REQUEST__VALUE_SET_OPTION:
return SetOption(request->set_option);
case TYPES__REQUEST__VALUE_DELIVER_TX:
return DeliverTx(request->deliver_tx);
case TYPES__REQUEST__VALUE_CHECK_TX:
return CheckTx(request->check_tx);
case TYPES__REQUEST__VALUE_COMMIT:
return Commit();
case TYPES__REQUEST__VALUE_QUERY:
return Query(request->query);
case TYPES__REQUEST__VALUE_INIT_CHAIN:
return InitChain(request->init_chain);
case TYPES__REQUEST__VALUE_BEGIN_BLOCK:
return BeginBlock(request->begin_block);
case TYPES__REQUEST__VALUE_END_BLOCK:
return EndBlock(request->end_block);
}
}

You can find this code in c-abci/demo/dummy.c file. The parameter of request passed by C-ABCI, which is received from Tendermint.

You can see in this callback function each request type has it’s own function to dispose request. This is most important part of your Application code, you need implement functions of each request type, these functions are your Application’s business logic . And when you finished these functions, your Application’s code is completed!
In c-abci/demo/ directory just implemented a few functions of some request type, and it’s very simple business logic which just store data or query them. It use dlist modular to store data. You can choose your own method to store data, such as tree, database.

Problem’s Solution:C-ABCI’s problems during compiling

文章目录
  1. 1. Brief Introduction
  2. 2. How to run C-ABCI demo?
    1. 2.1. Step 1: Install Tendermint
    2. 2.2. Step 2: Clone code
    3. 2.3. Step 3: Compile code
    4. 2.4. Step 4: Run test program
    5. 2.5. Step 5: Run Tendermint
  3. 3. C-ABCI code framework
  4. 4. How to build a Application on top of C-ABCI?
    1. 4.1. Initialize C-ABCI serve
    2. 4.2. Start C-ABCI serve
    3. 4.3. Stop C-ABCI server