# Node Client (Daemon)
# Pre-requisite Readings
The full-node client of any SDK application is built by running a
main function. The client is generally named by appending the
-d suffix to the application name (e.g.
appd for an application named
app), and the
main function is defined in a
./cmd/appd/main.go file. Running this function creates an executable
.appd that comes with a set of commands. For an app named
app, the main command is
appd start, which starts the full-node.
In general, developers will implement the
main.go function with the following structure:
- First, a
codecis instanciated for the application.
- Then, the
configis retrieved and config parameters are set. This mainly involves setting the bech32 prefixes for addresses and pubkeys.
- Using cobra (opens new window), the root command of the full-node client is created. After that, all the custom commands of the application are added using the
- Add default server commands to
server.AddCommands(ctx, cdc, rootCmd, newApp, exportAppStateAndTMValidators)method. These commands are separated from the ones added above since they are standard and defined at SDK level. They should be shared by all SDK-based applications. They include the most important command: the
- Prepare and execute the
See an example of
main function from the
gaia (opens new window) application:
start command is defined in the
/server folder of the Cosmos SDK. It is added to the root command of the full-node client in the
main function and called by the end-user to start their node:
As a reminder, the full-node is composed of three conceptual layers: the networking layer, the consensus layer and the application layer. The first two are generally bundled together in an entity called the consensus engine (Tendermint Core by default), while the third is the state-machine defined with the help of the Cosmos SDK. Currently, the Cosmos SDK uses Tendermint as the default consensus engine, meaning the start command is implemented to boot up a Tendermint node.
The flow of the
start command is pretty straightforward. First, it retrieves the
config from the
context in order to open the
leveldb (opens new window) instance by default). This
db contains the latest known state of the application (empty if the application is started from the first time.
start command creates a new instance of the application using an
Note that an
appCreator is a function that fulfills the
AppCreator signature. In practice, the constructor the application is passed as the
Then, the instance of
app is used to instanciate a new Tendermint node:
The Tendermint node can be created with
app because the latter satisfies the
abci.Application interface (opens new window) (given that
baseapp). As part of the
NewNode method, Tendermint makes sure that the height of the application (i.e. number of blocks since genesis) is equal to the height of the Tendermint node. The difference between these two heights should always be negative or null. If it is strictly negative,
NewNode will replay blocks until the height of the application reaches the height of the Tendermint node. Finally, if the height of the application is
0, the Tendermint node will call
InitChain on the application to initialize the state from the genesis file.
Once the Tendermint node is instanciated and in sync with the application, the node can be started:
Upon starting, the node will bootstrap its RPC and P2P server and start dialing peers. During handshake with its peers, if the node realizes they are ahead, it will query all the blocks sequentially in order to catch up. Then, it will wait for new block proposals and block signatures from validators in order to make progress.
Learn about the store