In previous sections you learned about different ABCI 2.0 methods and how they are used.
In this section you will learn how to run the Forum Application
.
The application is almost ready to run, but first we’ll need to populate the CometBFT configuration file.
The following command will create a cometbft home directory in your project and add a basic set of configuration files in ~/config/.
For more information on what these files contain see the configuration documentation.
Clone the cometbft
repository:
git clone https://github.com/cometbft/cometbft
checkout the latest v1
release and install it
cd cometbft
git checkout v1.0.0
make install
initialize cometbft:
cometbft init --home /tmp/forum-app
You should see an output similar to the following:
I[2024-04-23|20:16:43.493] Found private validator module=main keyFile=/tmp/forum-app/config/priv_validator_key.json stateFile=/tmp/forum-app/data/priv_validator_state.json
I[2024-04-23|20:16:43.493] Found node key module=main path=/tmp/forum-app/config/node_key.json
I[2024-04-23|20:16:43.493] Found genesis file module=main path=/tmp/forum-app/config/genesis.json
Now build the app:
cd abci/tutorials/abci-v2-forum-app
go build
If there are no errors when running the build command above, then everything is now in place to run your application.
Note: If this is not the first time you’re running this application, you need to remove the previously created database, please run the command
rm -Rf forum-db
to remove the previous database folder and run from a fresh start
Lets run our Forum Application specifying a home directory (using --home
) hosted in the tmp/forum-app
folder
(if you don’t specify the home folder, it is created under $HOME/.cometbft
by default)
./abci-v2-forum-app --home /tmp/forum-app
This should start the full node and connect to our ABCI application, which will be reflected in the application output.
(abci-v2-forum-app) > ./abci-v2-forum-app --home /tmp/forum-app
badger 2024/07/11 11:00:19 INFO: All 0 tables opened in 0s
badger 2024/07/11 11:00:19 INFO: Discard stats nextEmptySlot: 0
badger 2024/07/11 11:00:19 INFO: Set nextTxnTs to 0
I[2024-07-11|15:00:19.091] State store key layout version version=vv1
I[2024-07-11|15:00:19.100] Blockstore version version=v1
I[2024-07-11|15:00:19.100] WARNING: deleting genesis file from database if present, the database stores a hash of the original genesis file now
I[2024-07-11|15:00:19.100] service start module=proxy msg="Starting multiAppConn service" impl=multiAppConn
I[2024-07-11|15:00:19.100] service start module=abci-client connection=query msg="Starting localClient service" impl=localClient
I[2024-07-11|15:00:19.100] service start module=abci-client connection=snapshot msg="Starting localClient service" impl=localClient
I[2024-07-11|15:00:19.100] service start module=abci-client connection=mempool msg="Starting localClient service" impl=localClient
I[2024-07-11|15:00:19.100] service start module=abci-client connection=consensus msg="Starting localClient service" impl=localClient
I[2024-07-11|15:00:19.100] service start module=events msg="Starting EventBus service" impl=EventBus
I[2024-07-11|15:00:19.100] service start module=pubsub msg="Starting PubSub service" impl=PubSub
I[2024-07-11|15:00:19.120] service start module=txindex msg="Starting IndexerService service" impl=IndexerService
I[2024-07-11|15:00:19.120] ABCI Handshake App Info module=consensus height=0 hash=0000000000000000 software-version=2.1.0 protocol-version=1
I[2024-07-11|15:00:19.120] ABCI Replay Blocks module=consensus appHeight=0 storeHeight=0 stateHeight=0
I[2024-07-11|15:00:19.120] Executing Application InitChain
I[2024-07-11|15:00:19.124] Completed ABCI Handshake - CometBFT and App are synced module=consensus appHeight=0 appHash=0000000000000000
I[2024-07-11|15:00:19.124] Version info tendermint_version=1.0.0-dev abci=2.1.0 block=11 p2p=9 commit_hash=
I[2024-07-11|15:00:19.124] This node is a validator module=consensus addr=488A741EC0B687FE06C045EFAB12DDBFF82A5993 pubKey=PubKeyEd25519{41AA07512ED9B4607C17AF49B7D30737FC19D77EAA2FE69F66F5F46AB619D221}
I[2024-07-11|15:00:19.157] P2P Node ID module=p2p ID=f32302c56b40b7bc249613185913b422be494ee0 file=/tmp/forum-app/config/node_key.json
I[2024-07-11|15:00:19.157] Adding persistent peers module=p2p addrs=[]
I[2024-07-11|15:00:19.157] Adding unconditional peer ids module=p2p ids=[]
I[2024-07-11|15:00:19.157] Add our address to book module=p2p book=/tmp/forum-app/config/addrbook.json addr=f32302c56b40b7bc249613185913b422be494ee0@0.0.0.0:26656
I[2024-07-11|15:00:19.157] service start msg="Starting Node service" impl=Node
I[2024-07-11|15:00:19.158] service start module=p2p msg="Starting P2P Switch service" impl="P2P Switch"
I[2024-07-11|15:00:19.158] service start module=mempool msg="Starting Mempool service" impl=Mempool
I[2024-07-11|15:00:19.158] service start module=blocksync msg="Starting Reactor service" impl=Reactor
I[2024-07-11|15:00:19.158] serve module=rpc-server msg="Starting RPC HTTP server on 127.0.0.1:26657"
I[2024-07-11|15:00:19.158] service start module=consensus msg="Starting Consensus service" impl=ConsensusReactor
I[2024-07-11|15:00:19.158] service start module=consensus msg="Starting State service" impl=ConsensusState
I[2024-07-11|15:00:19.158] service start module=consensus wal=/tmp/forum-app/data/cs.wal/wal msg="Starting baseWAL service" impl=baseWAL
I[2024-07-11|15:00:19.162] service start module=consensus wal=/tmp/forum-app/data/cs.wal/wal msg="Starting Group service" impl=Group
I[2024-07-11|15:00:19.162] service start module=consensus msg="Starting TimeoutTicker service" impl=TimeoutTicker
I[2024-07-11|15:00:19.162] Searching for height module=consensus wal=/tmp/forum-app/data/cs.wal/wal height=1 min=0 max=0
I[2024-07-11|15:00:19.162] Searching for height module=consensus wal=/tmp/forum-app/data/cs.wal/wal height=0 min=0 max=0
I[2024-07-11|15:00:19.162] Found module=consensus wal=/tmp/forum-app/data/cs.wal/wal height=0 index=0
I[2024-07-11|15:00:19.162] Catchup by replaying consensus messages module=consensus height=1
I[2024-07-11|15:00:19.162] Replay: Done module=consensus
I[2024-07-11|15:00:19.162] service start module=evidence msg="Starting Evidence service" impl=Evidence
I[2024-07-11|15:00:19.162] service start module=statesync msg="Starting StateSync service" impl=StateSync
I[2024-07-11|15:00:19.162] service start module=pex msg="Starting PEX service" impl=PEX
I[2024-07-11|15:00:19.162] service start module=p2p book=/tmp/forum-app/config/addrbook.json msg="Starting AddrBook service" impl=AddrBook
I[2024-07-11|15:00:19.163] Saving AddrBook to file module=p2p book=/tmp/forum-app/config/addrbook.json size=0
I[2024-07-11|15:00:19.163] Ensure peers module=pex numOutPeers=0 numInPeers=0 numDialing=0 numToDial=10
I[2024-07-11|15:00:19.163] service start module=state msg="Starting Pruner service" impl=Pruner
I[2024-07-11|15:00:19.163] No addresses to dial. Falling back to seeds module=pex
I[2024-07-11|15:00:19.163] Started pruning blocks module=state interval=10s
I[2024-07-11|15:00:20.154] Timed out module=consensus dur=991.108ms height=1 round=0 step=RoundStepNewHeight
I[2024-07-11|15:00:20.154] Executing Application PrepareProposal
I[2024-07-11|15:00:20.154] Processed vote extensions curse_words=map[]
I[2024-07-11|15:00:20.166] Received proposal module=consensus proposal="Proposal{1/0 (3F859221DD1F92490BCB4D93E27BCF61716285DB1412091EDAEC41E31752A161:1:3E782D5C89A4, -1) C9C6EEDA8B33 @ 2024-07-11T15:00:11.194908Z}" proposer=488A741EC0B687FE06C045EFAB12DDBFF82A5993
I[2024-07-11|15:00:20.171] Received complete proposal block module=consensus height=1 hash=3F859221DD1F92490BCB4D93E27BCF61716285DB1412091EDAEC41E31752A161
I[2024-07-11|15:00:20.171] Executing Application ProcessProposal
I[2024-07-11|15:00:20.176] Executing Application ExtendVote
I[2024-07-11|15:00:20.181] Finalizing commit of block module=consensus height=1 hash=3F859221DD1F92490BCB4D93E27BCF61716285DB1412091EDAEC41E31752A161 root=0000000000000000 num_txs=0
I[2024-07-11|15:00:20.190] Executing Application FinalizeBlock
I[2024-07-11|15:00:20.190] Finalized block module=state height=1 num_txs_res=0 num_val_updates=0 block_app_hash=0000000000000000 syncing_to_height=1
I[2024-07-11|15:00:20.194] Executing Application Commit
I[2024-07-11|15:00:20.194] Committed state module=state height=1 block_app_hash=0000000000000000
I[2024-07-11|15:00:20.203] indexed block events module=txindex height=1
Also, the application using CometBFT Core is producing blocks 🎉🎉 and you can see this reflected in the log output of the service in lines like this:
I[2024-07-11|15:00:21.181] Executing Application PrepareProposal
I[2024-07-11|15:00:21.181] Processed vote extensions curse_words="map[bad:1 bloodmagic:1 cry:1 muggle:1 rain:1]"
I[2024-07-11|15:00:21.193] Received proposal module=consensus proposal="Proposal{2/0 (2F2187B9E889B4C9DD33B5D510039F12CE70DC2854D8EDF706B6C46178909BA6:1:F60DF39D940E, -1) 9E244663B13B @ 2024-07-11T15:00:20.176517Z}" proposer=488A741EC0B687FE06C045EFAB12DDBFF82A5993
I[2024-07-11|15:00:21.198] Received complete proposal block module=consensus height=2 hash=2F2187B9E889B4C9DD33B5D510039F12CE70DC2854D8EDF706B6C46178909BA6
I[2024-07-11|15:00:21.198] Executing Application ProcessProposal
I[2024-07-11|15:00:21.202] Executing Application ExtendVote
I[2024-07-11|15:00:21.207] Finalizing commit of block module=consensus height=2 hash=2F2187B9E889B4C9DD33B5D510039F12CE70DC2854D8EDF706B6C46178909BA6 root=0000000000000000 num_txs=0
I[2024-07-11|15:00:21.216] Executing Application FinalizeBlock
I[2024-07-11|15:00:21.216] Finalized block module=state height=2 num_txs_res=0 num_val_updates=0 block_app_hash=0000000000000000 syncing_to_height=2
I[2024-07-11|15:00:21.220] Executing Application Commit
I[2024-07-11|15:00:21.220] Committed state module=state height=2 block_app_hash=0000000000000000
I[2024-07-11|15:00:21.228] indexed block events module=txindex height=2
Let’s try submitting a transaction to our new application. Open another terminal window and run the following curl
command:
curl -s 'localhost:26657/broadcast_tx_commit?tx="sender:Ron,message:Music"'
If everything went well, you should see a response indicating which height the transaction was included in the blockchain.
{"jsonrpc":"2.0","id":-1,"result":{"check_tx":{"code":0,"data":null,"log":"","info":"","gas_wanted":"0","gas_used":"0","events":[],"codespace":""},"tx_result":{"code":0,"data":null,"log":"","info":"","gas_wanted":"0","gas_used":"0","events":[],"codespace":""},"hash":"DD0DD9613C83E5CCDE31342DC49CEF1DD6423271B090BC6A73E800FD163E7ADD","height":"25"}}%
Let’s make sure that transaction really was persisted by the application. Run the following command:
curl -s 'localhost:26657/abci_query?data="Ron"'
Let’s examine the response object that this request returns. The request returns a json
object with a key
and value
field set.
{
"jsonrpc": "2.0",
"id": -1,
"result": {
"response": {
"code": 0,
"log": "\"Music\"",
"info": "",
"index": "0",
"key": "Um9u",
"value": "Ik11c2ljIg==",
"proofOps": null,
"height": "0",
"codespace": ""
}
}
}
Those values don’t look like the key and value we sent to CometBFT. What’s going on here?
The response contains a base64
encoded representation of the data we submitted. To get the original value out of
this data, we can use the base64 command line utility to view the key (sender) and value (message):
To view the value of key
(which is the sender) run:
echo Um9u | base64 -d
It will output Ron
Then run the command below to view the value
(which is the message):
echo Ik11c2ljIg== | base64 -d
It will output Music
As you can observe, the Music
message was added by Ron
.
curl -s 'localhost:26657/broadcast_tx_commit?tx="sender:Malfoy,message:muggle"'
After a certain amount of time you will see a message that tx could not be included in the block. This happens as tx is being rejected in PrepareProposal
{"jsonrpc":"2.0","id":-1,"error":{"code":-32603,"message":"Internal error","data":"timed out waiting for tx to be included in a block"}}
Let’s make sure that transaction really was not persisted by the application. Run the following command:
curl -s 'localhost:26657/abci_query?data="Malfoy"'
This should return an error with Key not found
since the sender and message were not included in the application
{"jsonrpc":"2.0","id":-1,"error":{"code":-32603,"message":"Internal error","data":"Key not found"}}
curl -s 'localhost:26657/broadcast_tx_commit?tx="sender:Malfoy,message:heroic"'
After a certain amount of time you will observe that tx was rejected in checkTx
since the user has been already banned.
{"jsonrpc":"2.0","id":-1,"result":{"check_tx":{"code":3,"data":null,"log":"User is banned","info":"","gas_wanted":"0","gas_used":"0","events":[],"codespace":""},"tx_result":{"code":0,"data":null,"log":"","info":"","gas_wanted":"0","gas_used":"0","events":[],"codespace":""},"hash":"9B110D7648000037B8385562B15810C70E1957AF2F65790B3617CB84C9398536","height":"0"}}%
The application can also return the history of messages that were submitted and added to the application. To view the chat history run the following query:
curl -s 'localhost:26657/abci_query?data="history"'
You can see the chat history in the log field of the response:
{"jsonrpc":"2.0","id":-1,"result":{"response":{"code":0,"log":"{sender:Ron,message:Music}","info":"","index":"0","key":"aGlzdG9yeQ==","value":"e3NlbmRlcjpSb24sbWVzc2FnZTpNdXNpY30=","proofOps":null,"height":"0","codespace":""}}}%
Our tutorial on building an ABCI 2 application using CometBFT has come to a close. We hope that the comprehensive tutorial we’ve provided has equipped you with the knowledge and skills necessary to develop your own ABCI 2.0 applications with ease and confidence.