Key concepts - HelixNetwork/pendulum GitHub Wiki

Round is a global time window defined as [GENESIS_TIME + i*ROUND_DURATION, GENESIS_TIME + (i+1)*ROUND_DURATION), where i is the round index. The only property required from a round r is that there is global knowledge of the validator set for a specified round:

List<PublicKey> getValidators(Round r)

The source of truth for the global knowledge can either be an authorized resource (Proof-Of-Authority mode) or a public ledger (either the HelixNetwork itself or HelixDAO on Ethereum).

Trunk and Branch This terminology is inherited from IOTA and simply refers to the two parents of a transaction. Here child-parent relationship is defined by the hash references. In particular, a transaction has the following structure:

Transaction tx = new Transaction()
tx.trunk = <hash of the first parent here>
tx.branch = <hash of the second parent here>

The child-parent directed relationship is usually visualized graphically when a child transaction has two outgoing arrows to the two parents. Furthermore, a parent cannot directly or indirectly point to its childs. Such a directed graph is a DAG (directed acyclic graph), with the genesis transaction as its sink (being the only transaction without parents).

Tangle The Tangle is a term originally used by IOTA to describe the IOTA Tangle. It's simply the DAG consisting of all transactions submitted to the Helix Network. 'The' article emphasises the global and immutable nature of the hash reference data to be stored in such a DAG.

Local DAG(Tangle) Each node keeps its local representation of the Tangle which typically misses some transactions. Some portion is kept in memory (the most recent transactions received from the peers), while most of it is persisted to the disk (in the current implementation RocksDB is used).

Solid A transaction is considered solid in a local DAG, when all of its direct and indirect (i.e. grand-, grandgrand, etc) parents are available. To check whether a transaction is solid, you simply check whether its (in)direct parents are solid until you reach genesis(null_hash) or a new solid entry point. Solidification of a transaction is the process of requesting the missing parents from the network peers until a transaction becomes solid.

Milestone is a special transaction issued by a validator and attached to the Tangle. A single milestone is a short representation of the local DAG of view of the validator at the time it had been submitted in the following sense: The branch of a milestone is a transaction containing a Merkle root for a maximal consistent solid tipset, and the trunk is a transaction with a Merkle root of all the solid milestones in the previous round as seen by the local DAG of the validator at the moment it is created. The list of milestones in the trunk are referred to as milestone parents.

Milestone index A milestone has its own index which, as opposed to the round index, is determined solely by the DAG structure and thus is immutable and globally defined. Formally, milestone index is defined recursively as

  Milestone m = new Milestone();
  //... assuming parents indices are resolved
  m.index = m.getParents().stream().max(Milestone::index) + 1;

Validator Validators are nodes with special privileges to attest the consistency of the network. It is taken for granted that in each time round at least 2/3 of the validators respect the protocol rules and have local clocks synchronized with UTC (up to 1 second).

An (honest) validator never publishes a non-consistent milestone.

  • A milestone never confirms directly or indirectly two conflicting transactions (e.g. double spends).
  • Everything a milestone confirms is solid in the local DAG of the validator issuing it
  • A validator issues a milestone with index I (according to his local DAG) during the round with index I
  • A validator never publishes more than one milestone with the same index
  • If for some reason there is no solid milestone with index I-1 when a milestone with index I is required (i.e. the validator is in the time round with index I according to the local validator's clock), the single parent will be a NULL_HASH. However, it may happen only when a validator joins the network, as otherwise it has at least its own previous milestone as a parent.

Confirmation of a transaction T by a milestone M is simply the assertion "Milestone M has T as direct or indirect parent. Number of confirmations of a transaction T in round I is the number of milestones having index I, confirming T.

Finalized transaction T is a transaction with the following property. There is round r index such that:

T.getConfirmations(r).length >= 2/3 * getValidators(r).length

Put in words, there is some round such that at least 2/3 valid milestones in that round (as seen by their corresponding DAG indices) confirm this transaction.

Snapshot is a short representation of the DAG state, which however, does not contain any transaction data. Instead, it only contains the account addresses and balances and thus completely indifferent to the data transactions. Thus, it is impossible to tell if a given transaction is accounted in a given snapshot or not. Snapshots are useful as they significantly reduce the processing overhead for verification.

Latest Snapshot is an in-memory representation of the account balances, that gets updated with each round.

Local Snapshot is an optional feature that enables frequently saving, the latest snapshot containing account addresses, balances and meta data, to disk. It's an optional feature.

⚠️ **GitHub.com Fallback** ⚠️