Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Hare Protocol Implementation
Hare Protocol Implementation
This page will describe the design and implementation details of the hare protocol. It is mainly intended for programmers who want to use it as a reference implementation. It is suggested to have a good understanding of the Hare protocol.
The Hare protocol is used to achieve consensus on a given set of values. Most of the protocol's logic is done in the ConsensusProcess. This implementation supports having more than one consensus concurrently as you shall see later on when we describe the broker and the orchestrator. The role of the Hare protocol in the Spacemesh stack is to achieve a faster and more secure mesh validation by using the results of the Hare protocol as votes in the mined block. I.e. each block created by a miner will include explicit votes on a set of valid blocks as received from the Hare protocol.
High-Level Block Diagram
Since there could be multiple consensus processes at a time, we are using a broker to dispatch the incoming messages of the protocol to the matching consensus process instance. The broker supports registration and un-registration of instances. On an incoming Hare message, the broker will check message validity and report back to the p2p (see Reporting Validation to P2P). If validation succeeds, the broker will pick in the message to check the instance id to which the message is intended to. If there is no registered process for this instance id, it will be buffered and passed later (see Early Messages). Otherwise, the broker will pass the messages to the registered instance (through the corresponding channel).
The consensus process (CP) is the implementation of the Hare protocol's logic.
Since the moment the CP starts the protocol follows the rounds logic.
Since each round has different messages and logic, we delegate some of that logic to
Each message type has its corresponding tracker which keeps track of the relevant state for the specific message type.
We have five trackers corresponding to the five message types:
PreRoundTracker- for each value, tracks the number of unique pre-round messages that included that value. It can be queried to check if a set is provable by pre-round messages and to filter non-provable values from a given set.
StatusTracker- tracks status messages. It can be asked to validate the current status messages, check if the SVP is ready, build an SVP for a proposal and retrieve the proposal set.
ProposalTracker- Tracks proposal messages in order to keep track of the leading proposed set and detect conflicting proposals.
CommitTracker- tracks commit messages so we can build the corresponding certificate if we have collected sufficient commits.
NotifyTracker- track notification messages per set. It can be asked for the number of notifications we witnessed (for a specific set) and if we witnessed a specific certificate.
Note: all trackers assume that the messages they receive are completely valid.
Message validation is separated into two parts, the MessageValidator and EligibilityValidator. The former is used in the CP while the latter is used in the broker. The Hare should report back to the p2p about the result of a message validation. Contextual validation in CP is more delicate as the result may change between nodes and hence, is not taken into account in the report back to the p2p (see Reporting Validation to P2P). That is the reason for the separation of these two validators.
The message validator is used to validate messages in the CP. It exposes two main validation methods, one to validate syntax and the other to validate the context. This separation is beneficial since inner messages (for example, in a certificate or an SVP) wouldn't require contextual validation.
The validator used to validate messages on the broker level. This validation is part of the report sent back to the p2p (see Reporting Validation to P2P). It exposes a Validate method that validates the role of the sender and the signature of the message.
The orchestrator keeps track of the collection of running consensus processes. It is also in charge of collecting the last X outputs of the consensus processes and can be queried later for the output matching a specific instance.
Reporting Validation to P2P
The P2P has a mechanism that requires gossip-based protocols to report back to it with the result of the message validation. This mechanism prevents honest nodes from propagating invalid messages over the gossip network. We decided to include in the report only the contextual (broke-wise, meaning we accept only messages close to the current layers we are handling) eligibility and signature validations as both are independent of time drifts and context.
Currently, syntax validation is not included in the report since it is not as important in terms of malicious behavior. Following that need, we divide the validation logic into two: 1. Syntax and contextual validation used in the ConsensusProcess. 2. Contextual, eligibility and signature validation used in the broker. This way, the broker can unburden the ConsensusProcess from the responsibility to report back to the P2P.
Please note that while referring to contextual validation in both the broker and the CP, the former refers to layer context while the latter refers to round/iteration context.
Due to time drifts, messages may appear as too early for some nodes. We want to allow buffering of messages that are intended for round
r+1 even if they have arrived on round
r. This required adjustments in two parts:
Broker- if an early message is received before the corresponding
Consensus Processhas registered, we will not have an instance to dispatch the messages to. We currently buffer all early messages and send them on registration of the corresponding instance. A more complete solution is a work in progress (See #544).
Consensus Process- after validating the syntax we use
contextual validationto decide whether we should process the message in this round (contextually valid), buffer the message for the next round (early message) or ignore the message otherwise (contextually invalid)
Fixed Roles Oracle
The FixedRolacle is an intermediate implementation of the
eligibility oracle which is used only for testing purposes. A fixed size committee is free of probability and hence:
- We cannot get a significantly bigger/smaller committee, just the exact provided size. This is especially required for testing since the typical numbers used are much lower and hence introduces higher variance.
- We have better control over the number of active honest/dishonest nodes.
Unit tests use many mocks in order to achieve high coverage. For example, you can find mocks of the p2p, message validation, roles oracle, different trackers and consensus process. When approaching to write unit tests we recommend to have a look at your need and the available mocks. Of course, you are encouraged to add new ones as needed.
E2E & Integration Tests
- E2E tests use the p2p simulator. Examples can be found on consensus_test.go.
- Integration tests use the real p2p implementation in our system. Examples can be found on integration_test.go.