--- title: Protocol Tangle tags: RFC, draft --- # Summary This RFC proposes a pre-coordicide milestone-based Tangle as part of the `bee-protocol` crate. It is built on-top of the generic Tangle from the `bee-tangle` crate. # Motivation The pre-coordicide IOTA technology requires a special node (run by the IOTA Foundation), that in certain intervals issues so-called milestones. Milestones are signed 0-value bundles/transactions, that represent a vote over a certain sub-graph (or past cone of that milestone) being considered valid and confirmed by the Foundation. The nodes in the network usually follow that opinion (but don't have to), and hence reach consensus on the ledger state. # Detailed design Since the Tangle from the `bee-tangle` crate is generic over the data associated with a transaction, one can define the type of metadata elsewhere: ## `Flags` struct There is a variety of relevant metadata, that is associated with a transaction: * `Solid`: a transaction is solid, if its full past cone is locally available (that means that each Tangle walk starting from that transaction into the past always yields a transaction, that is either in memory or persisted in the database); * `Tail`: At the time of this writing the IOTA technology still uses bundles (several transaction equally sized transactions are bundled together to describe a ledger change in case of value transactions). The transactions within a bundle are chained together, and therefore can be ordered. The last transaction (that has index `0` for historical reasons) is called the `Tail`; * `Requested`: If a node enters the network it needs to synchronize wit the rest of the network. As this usually happens in between two milestones, the node has to request missing transactions in order to be able to validate the recent activity. * `Milestone`: Flags a bundle/transaction as milestone. Once such a transaction arrives, the node software flags the past cone of that bundle/transaction as confirmed and associates each of such transaction with the so-called milestone index, that confirmed it. ```rust bitflags! { #[derive(Default)] struct Flags: u8 { const SOLID = 0b0000_0001; const TAIL = 0b0000_0010; const REQUESTED = 0b0000_0100; const MILESTONE = 0b0000_1000; } } ``` **NOTE:** For each of those flags it is convenient to define getters and setters, like in the following example: ```rust impl Flags { fn is_solid(&self) -> bool { self.contains(Flags::SOLID) } fn set_solid(&mut self) { self.insert(Flags::SOLID); } } ``` Apart from just mere toggle on/off flags, additional metadata is required: ## `TransactionMetadata` struct * `arrival timestamp`: the system time at which the node has received the associated transaction; * `solidification timestamp`: the system time at which the node was able to solidify the associated transaction (acquired its past cone up to the confirmed root transactions); * `milestone index`: the milestone index, that confirmed the associated transaction; Together with the `Flags` those information form the metadata that will be attached to each transaction: ```rust #[derive(Copy, Clone, Default)] struct TransactionMetadata { flags: Flags, arrival_timestamp: u64, solidification_timestamp: u64, milestone_index: MilestoneIndex, } ``` ## `MsTangle` struct The milestone-based Tangle can then be defined as the following struct: ```rust use bee_tangle::Tangle; // imports the generic Tangle struct MsTangle { // creates a special Tangle that associates `TransactionMetadata` with each transaction inner: Tangle<TransactionMetadata>, // a map between the milestone index and the assiated tail transaction hash milestones: DashMap<MilestoneIndex, TransactionHash>, // a solid entry point is just a transaction hash the node doesn't traverse any further in // into the past during solidity checks. The associated value is the milestone index, that // confirmed the corresponding transaction in the past. solid_entry_points: DashMap<TransactionHash, MilestoneIndex>, // the current "time" of the network, that the coordinator node sets (short "lmi"). last_milestone_index: AtomicU32, // represents the last milestone the node has the full past cone locally availble // (short "lsmi"). If `lmi == lsmi`, then the node is synchronized. last_solid_milestone_index: AtomicU32, snapshot_milestone_index: AtomicU32, } ``` # Drawbacks * as long as the milestones are issued by a central authority, the consensus mechanism is not fully decentralized; nodes don't need to follow the coordinator node, but currently there has to be some trusted entity for the consensus mechanism to work. Post-coordicide the IOTA protocol will be fully decentralized, and the milestone-based Tangle in the current form will be obsolete; # Rationale and Alternatives * there are no alternatives at the time of writing; # Unresolved questions * none