Factom Daemon

Table of contents

  1. Start Up
    1. NetStart
  2. A Factom Server is Born
    1. NetworkProcessorNet
    2. LoadDatabase
    3. Timer
    4. GoSyncEntries
    5. Elections Run/hackingfactom/
    6. ValidatorLoop/hackingfactom/
  3. State Reference
  4. Additional reading

Start Up

factomd.go is the entry point for the program. It starts by defining state := Factom(params, sim_Stdin). And as long as state.Running() is true, the program remains running. Factomd is found in engine/factomd.go.

The first order of business is to initialize a new interfaces.IState object and set its IsRunning property to true. From there, additional items are set such as the timestamp at boot, a message filter timestamp, and a new elections factory–and then it starts the networking system.

NetStart

Networking is started at engine/NetStart.go. NetStart handles a lot of things, though, including but not limited to:

  • enables or disables control panel
  • registers Prometheus handlers
  • sets ports to open
  • checks if RPC credentials are required
  • runs CheckChainHeads
  • runs FixChainHeads
  • starts pprof with StartProfiler (see “Operations” chapter)
  • sets log levels

Many of the things that control the flow of start up and set important pieces of state are found in engine/factomParams.go. Stop and take a brief look at the init() function and the defaults.

It is equally important to check out the State.Init() function which is run during this initialization prior to starting the server.

Then, a few hundred lines later,

//************************************************
// Actually setup the Network
//************************************************

If we are running a single full mainnet node, we will call makeServer once and supply it with a copy of the state object that we have been building up. It creates a new FactomNode struct and returns it. If we are running a simulated network, additional Factom servers are started at this point and given skeleton Identities. Then, the P2P network is started.

The type of network we are on is determined (main, test, local, custom). The SeedURL is determined here based on the type of network we are on–the role of SeedURL will be discussed in the “Peer to Peer Network” chapter. The most important module for peer-to-peer networking in Factom is started here, the p2p.Controller, also discussed in the “Peer to Peer Network” chapter.

For a simulated network, the pattern of network is set here. This includes network options like “circle” and “tree”–the deafult is “alot+”. These different configurations of how nodes are shaped and connected helps evaluate performance of the gossip protocol. The arborjs.org/halfviz visualization text of the network is generated here, you can copy it into the arborjs page to visualize the network pattern. Here is an example of what halfviz does:

halfviz

(It is possible to have factomd keep a journal of all messages it receives, and replay those messages, if the paramters are set–by default this is disabled. But if it is enabled, factomd will make note of that fact at this point.)

Prometheus (see “Operations” chapter) is started and made available on port 9876. The control panel server is started. The web server API is started (see “Operations” chapter). And finally the simulator listener is started for listening on stdin.

The servers that have been made are started in the startServers function call.

A Factom Server is Born

Inside NetStart.go the function startServers fires 6 goroutines for our new Factom node.

  • NetworkProcessorNet
  • Timer(fnode.State)
  • state.LoadDatabase(fnode.State)
  • fnode.State.GoSyncEntries()
  • elections.Run(fnode.State)
  • fnode.State.ValidatorLoop()

State is aptly named for its role in keeping information about the node during its start up, operation, and shut down.

NetworkProcessorNet

This call goes to engine/NetworkProcessorNet.go and takes the FactomNode as an argument, which contains the State. The node is passed to goroutines that call Peers and NetworkOutputs and InvalidOutputs. The purpose of these functions will be discussed in the “Messaging” chapter.

LoadDatabase

This call goes to state/loadDatabase.go and takes the node’s State directly. This function call begins the process of loading the database. This will be discussed in the “Database” chapter.

Timer

This call goes to Timer and takes the node’s State directly. It looks up the block time of of factomd (600 seconds on main net; same as BlkTime unless otherwise defined, such as in a test or simulator), does some math, and determines a wait and next value. These values are used in calls to time.Sleep inside the inner loop of this function. As the loop concludes, in adds a value between [0,...,9] to the state.TickerQueue() channel–which correspond approximately to “minutes” in the block. The size of the AckQueue() and InMsgQueue() affect the timing of this ticker.

GoSyncEntries

This call runs on the fnode.State and can be found at state/entrySyncing.go. GoSyncEntries() starts a messaging goroutine and runs a nonterminating loop to handle the work of discovering what entries or entry blocks are missing. When missing entries or entry blocks are found, this goroutine will submit messages to request missing entries and entry blocks. This part of the start up will be discussed in the “Database” Chapter.

Elections Run/hackingfactom/

This call goes to/hackingfactom/lections/elections.go`](https://github.com/FactomProject/factomd/blob/master/elections/elections.go) and takes the node’s State directly. This starts the main election loop for running elections. This will be discussed in the “Elections” chapter.

ValidatorLoop/hackingfactom/

This call goes to ValidatorLoop and takes the node’s State directly. If you take a peek at the Operations chapter, you’ll see under the section about pprof that ValidatorLoop spends more time running than any other function and it triggers many other important, long running functions. ValidatorLoop is where we will go from this chapter into Messages.

Next Chapter

State Reference

The State Struct contains several properties that factomd initializes during start up and then continues to update during operation. A description of some of the noteworthy properties is found below.

Name Type Description
Salt IHash A number generated by the node to tell if a message was originated by the node.
IdentityChainID IHash If this node has an identity, this is it. Most nodes do not.
AuthorityServerCount Int Number of authority nodes allowed.
BootTime Int64 Time in seconds since node last booted
IgnoreDone bool If ignore mode has ended, this is a stop gap for performance reasons
IgnoreMissing bool Ignore missing messages during network reboot, where your own messages might show back up from the old network state
LLeaderHeight unint32 The current height – the extra L makes it easier to look up in the IDE
EOM bool True when the first EOM is encountered (see glossary)
DBSig bool True when the first DBSig is encountered (see glossary)
Syncing bool True when looking for messages from leaders to sync
Holding map[[32]byte]interfaces.IMsg Follower holding messages
Acks map[[32]byte]interfaces.IMsg Following holding acknowledgements
HighestKnown uint32 Highest block for which we have received a message
EntryDBHeightComplete uint32 DBlock height this node has complete set of EBlocks and entries
EntryDBHeightProcessing uint32 DBlock Height at which we have started asking for or have all entries
DBFinished bool Database is loaded
DirectoryBlockInSeconds int Seconds per block, pulled from params for BlkTime
ProcessLists *ProcessLists Where temporary Factoid and Entry Credit balances are stored (discussed in “Messaging”)
RunLeader bool If this node is allowed to run as a leader
Leader bool If this node is a leader

Additional reading

“factomd major process flow” by Who, February 7, 2019.