# Consensus Traits ### Decidable #### choices/decision.rs ```rust // Decidable represents element that can be decided. // // Decidable objects are typically thought of as either transactions, blocks, or // vertices. pub trait Decidable { // ID returns a unique ID for this element. // // Typically, this is implemented by using a cryptographic hash of a // binary representation of this element. An element should return the same // IDs upon repeated calls. fn id(&self) -> ID; // Accept this element. // // This element will be accepted by every correct node in the network. fn accept(&mut self); // Reject this element. // // This element will not be accepted by any correct node in the network. fn reject(&mut self); // Status returns this element's current status. // // If Accept has been called on an element with this ID, Accepted should be // returned. Similarly, if Reject has been called on an element with this // ID, Rejected should be returned. If the contents of this element are // unknown, then Unknown should be returned. Otherwise, Processing should be // returned. fn status(&self) -> Status; } ``` ### AvalancheConsensus #### consensus/avalanche/consensus.rs ``` rust // Consensus represents a general avalanche instance that can be used directly // to process a series of partially ordered elements. pub trait Consensus { // Takes in alpha, beta1, beta2, the accepted frontier, the join statuses, // the mutation statuses, and the consumer statuses. If accept or reject is // called, the status maps should be immediately updated accordingly. // Assumes each element in the accepted frontier will return accepted from // the join status map. fn initialize( &mut self, snow_context: String, params: Parameters, vertexes: Vec<Box<dyn Vertex>>, ); // Returns the parameters that describe this avalanche instance fn parameters(self) -> Parameters; // Returns true if the transaction is virtuous. // That is, no transaction has been added that conflicts with it // IsVirtuous(snowstorm.Tx) bool fn is_virtuous(&self, tx: Box<dyn Tx>) -> bool; // Adds a new decision. Assumes the dependencies have already been added. // Assumes that mutations don't conflict with themselves. fn add(&mut self, vertex: Box<dyn Vertex>); // VertexIssued returns true iff Vertex has been added fn vertex_issued(&self, vertex: Box<dyn Vertex>) -> bool; // TxIssued returns true if a vertex containing this transanction has been added // TxIssued(snowstorm.Tx) bool fn tx_issued(&self, tx: Box<dyn Tx>) -> bool; // Returns the set of transaction IDs that are virtuous but not contained in // any preferred vertices. fn orphans(self) -> Set; // Returns a set of vertex IDs that were virtuous at the last update. fn virtuous(self) -> Set; // Returns a set of vertex IDs that are preferred fn preferences(self) -> Set; // RecordPoll collects the results of a network poll. If a result has not // been added, the result is dropped. fn record_poll(&mut self, bag: UniqueBag); // Quiesce returns true iff all vertices that have been added but not been accepted or rejected are rogue. // Note, it is possible that after returning quiesce, a new decision may be added such // that this instance should no longer quiesce. fn quiesce(&self) -> bool; // Finalized returns true if all transactions that have been added have been // finalized. Note, it is possible that after returning finalized, a new // decision may be added such that this instance is no longer finalized. fn finalized(&self) -> bool; } ``` ### AvalancheVertex #### consensus/avalanche/consensus.rs ```rust pub trait Vertex: DynClone + Decidable { // Returns the vertices this vertex depends on fn parents(&self) -> Vec<Box<dyn Vertex>>; // Returns a series of state transitions to be performed on acceptance fn txs(&self) -> Vec<Box<dyn Tx>>; fn bytes(&self) -> Vec<u8>; } ``` ### AvalancheConsensusFactory #### consensus/avalanche/factory.rs ``` rust // Factory returns new instances of Consensus pub trait Factory { fn new() -> Box<dyn Consensus>; } ``` ### SnowballConsensus #### consensus/snowball/consensus.rs ``` rust // Consensus represents a general snow instance that can be used directly to // process the results of network queries. pub trait Consensus { // Takes in alpha, beta1, beta2, and the initial choice fn initialize(&mut self, params: Parameters, initial_preference: ID); // Returns the parameters that describe this snowball instance fn parameters(&self) -> Parameters; // Adds a new choice to vote on fn add(&mut self, new_choice: ID); // Returns the currently preferred choice to be finalized fn preference(&self) -> ID; // RecordPoll records the results of a network poll. Assumes all choices // have been previously added. fn record_poll(&mut self, votes: Bag); // RecordUnsuccessfulPoll resets the snowflake counters of this consensus // instance fn record_unsuccessful_poll(&mut self); // Return whether a choice has been finalized fn finalized(&self) -> bool; } ``` ### NnarySnowball #### consensus/snowball/consensus.rs ``` rust // NnarySnowball augments NnarySnowflake with a counter that tracks the total // number of positive responses from a network sample. pub trait NnarySnowball: NnarySnowflake {} ``` ### NnarySnowflake #### consensus/snowball/consensus.rs ``` rust // NnarySnowflake is a snowflake instance deciding between an unbounded number // of values. After performing a network sample of k nodes, if you have alpha // votes for one of the choices, you should vote for that choice. Otherwise, you // should reset. pub trait NnarySnowflake { // Takes in alpha, beta1, beta2, and the initial choice fn initialize(&mut self, beta_virtous: usize, beta_rogue: usize, initial_preference: ID); // Adds a new choice to vote on fn add(&mut self, new_choice: ID); // Returns the currently preferred choice to be finalized fn preference(&self) -> ID; // RecordSuccessfulPoll records a successful poll towards finalizing the // specified choice. Assumes the choice was previously added. fn record_successful_poll(&mut self, choices: ID); // RecordUnsuccessfulPoll resets the snowflake counters of this consensus // instance fn record_unsuccessful_poll(&mut self); // Return whether a choice has been finalized fn finalized(&self) -> bool; } ``` ### NnarySlush #### consensus/snowball/consensus.rs ``` rust // NnarySlush is a slush instance deciding between an unbounded number of // values. After performing a network sample of k nodes, if you have alpha // votes for one of the choices, you should vote for that choice. pub trait NnarySlush { // Takes in the initial choice fn initialize(&mut self, initial_preference: ID); // Returns the currently preferred choice to be finalized fn preference(&self) -> ID; // RecordSuccessfulPoll records a successful poll towards finalizing the // specified choice. Assumes the choice was previously added. fn record_successful_poll(&mut self, choice: ID); } ``` ### BinarySnowball #### consensus/snowball/consensus.rs ``` rust // BinarySnowball augments BinarySnowflake with a counter that tracks the total // number of positive responses from a network sample. pub trait BinarySnowball: BinarySnowflake {} ``` ### BinarySnowflake #### consensus/snowball/consensus.rs ```rust // BinarySnowflake is a snowball instance deciding between two values // After performing a network sample of k nodes, if you have alpha votes for // one of the choices, you should vote for that choice. Otherwise, you should // reset. pub trait BinarySnowflake { // Takes in alpha, beta1, beta2, and the initial choice fn initialize(&self, params: Parameters, initial_preference: ID); // Returns the currently preferred choice to be finalized fn preference(&self) -> ID; // RecordSuccessfulPoll records a successful poll towards finalizing the // specified choice. Assumes the choice was previously added. fn record_successful_poll(&self, choices: ID); // RecordUnsuccessfulPoll resets the snowflake counters of this consensus // instance fn record_unsuccessful_poll(&self); // Return whether a choice has been finalized fn finalized(&self) -> bool; } ``` ### BinarySlush #### consensus/snowball/consensus.rs ```rust // BinarySlush is a slush instance deciding between two values. After performing // a network sample of k nodes, if you have alpha votes for one of the choices, // you should vote for that choice. pub trait BinarySlush { // Takes in the initial choice fn initialize(&mut self, initial_preference: usize); // Returns the currently preferred choice to be finalized fn preference(&self) -> usize; // RecordSuccessfulPoll records a successful poll towards finalizing the // specified choice fn record_successful_poll(&mut self, choice: usize); } ``` ### UnarySnowball #### consensus/snowball/consensus.rs ```rust // UnarySnowball is a snowball instance deciding on one value. After performing // a network sample of k nodes, if you have alpha votes for the choice, you // should vote. Otherwise, you should reset. pub trait UnarySnowball { // Takes in alpha, beta1, beta2, and the initial choice fn initialize(&self, params: Parameters, initial_preference: ID); // RecordSuccessfulPoll records a successful poll towards finalizing the // specified choice. Assumes the choice was previously added. fn record_successful_poll(&self, choices: ID); // RecordUnsuccessfulPoll resets the snowflake counters of this consensus // instance fn record_unsuccessful_poll(&self); // Return whether a choice has been finalized fn finalized(&self) -> bool; // Returns a new binary snowball instance with the agreement parameters // transferred. Takes in the new beta value and the original choice fn extend(&self, original_preference: usize) -> Self; // Returns a new unary snowball instance with the same state fn clone(&self) -> Self; } ``` ### UnarySnowflake #### consensus/snowball/consensus.rs ```rust // UnarySnowflake is a snowflake instance deciding on one value. After // performing a network sample of k nodes, if you have alpha votes for the // choice, you should vote. Otherwise, you should reset. pub trait UnarySnowflake { // Takes in the beta value fn initialize(&mut self, beta: usize); // RecordSuccessfulPoll records a successful poll towards finalizing fn record_successful_poll(&mut self); // RecordUnsuccessfulPoll resets the snowflake counter of this instance fn record_unsuccessful_poll(&mut self); // Return whether a choice has been finalized fn finalized(&self) -> bool; // Returns a new binary snowball instance with the agreement parameters // transferred. Takes in the new beta value and the original choice fn extend(&mut self, beta: usize, original_preference: usize) -> dyn BinarySnowflake; // Returns a new unary snowflake instance with the same state fn clone(&self) -> dyn UnarySnowflake; } ``` ### SnowballConsensusFactory #### consensus/snowball/factory.rs ```rust pub trait Factory { fn new() -> Box<dyn Consensus>; } ``` ### Node #### consensus/snowball/tree.rs ```rust pub trait Node: DynClone { // Preference returns the preferred choice of this sub-tree fn preference(&mut self) -> ID; // Return the number of assumed decided bits of this node fn decided_prefix(&self) -> usize; // Adds a new choice to vote on fn add(&mut self, new_choice: ID) -> Box<dyn Node>; // Apply the votes, reset the model if needed fn record_poll(&mut self, votes: Bag, should_reset: bool) -> Box<dyn Node>; // Returns true if consensus has been reached on this node fn finalized(&self) -> bool; fn printable(&self) -> (String, Vec<Box<dyn Node>>); } ```