Dan Albert ffeac298a2
Move from gitbook to docusaurus, build docs in Travis CI (#10970)
* fix: ignore unknown fields in more RPC responses

* Remove mdbook infrastructure

* Delete gitattributes and other theme related items

Move all docs to /docs folder to support Docusaurus

* all docs need to be moved to /docs

* can be changed in the future

Add Docusaurus infrastructure

* initialize docusaurus repo

Remove trailing whitespace, add support for eslint

Change Docusaurus configuration to support `src`

* No need to rename the folder! Change a setting and we're all good to
go.

* Fixing rebase items

* Remove unneccessary markdown file, fix type

* Some fonts are hard to read. Others, not so much. Rubik, you've been
sidelined. Roboto, into the limelight!

* As much as we all love tutorials, I think we all can navigate around a
markdown file. Say goodbye, `mdx.md`.

* Setup deployment infrastructure

* Move docs job from buildkite to travic

* Fix travis config

* Add vercel token to travis config

* Only deploy docs after merge

* Docker rust env

* Revert "Docker rust env"

This reverts commit f84bc208e807aab1c0d97c7588bbfada1fedfa7c.

* Build CLI usage from docker

* Pacify shellcheck

* Run job on PR and new commits for publication

* Update README

* Fix svg image building

* shellcheck

Co-authored-by: Michael Vines <mvines@gmail.com>
Co-authored-by: Ryan Shea <rmshea@users.noreply.github.com>
Co-authored-by: publish-docs.sh <maintainers@solana.com>
2020-07-11 05:11:07 +00:00

3.6 KiB

title
title
Commitment

The commitment metric aims to give clients a measure of the network confirmation and stake levels on a particular block. Clients can then use this information to derive their own measures of commitment.

Calculation RPC

Clients can request commitment metrics from a validator for a signature s through get_block_commitment(s: Signature) -> BlockCommitment over RPC. The BlockCommitment struct contains an array of u64 [u64, MAX_CONFIRMATIONS]. This array represents the commitment metric for the particular block N that contains the signature s as of the last block M that the validator voted on.

An entry s at index i in the BlockCommitment array implies that the validator observed s total stake in the cluster reaching i confirmations on block N as observed in some block M. There will be MAX_CONFIRMATIONS elements in this array, representing all the possible number of confirmations from 1 to MAX_CONFIRMATIONS.

Computation of commitment metric

Building this BlockCommitment struct leverages the computations already being performed for building consensus. The collect_vote_lockouts function in consensus.rs builds a HashMap, where each entry is of the form (b, s) where s is the amount of stake on a bank b.

This computation is performed on a votable candidate bank b as follows.

   let output: HashMap<b, Stake> = HashMap::new();
   for vote_account in b.vote_accounts {
       for v in vote_account.vote_stack {
           for a in ancestors(v) {
               f(*output.get_mut(a), vote_account, v);
           }
       }
   }

where f is some accumulation function that modifies the Stake entry for slot a with some data derivable from vote v and vote_account (stake, lockout, etc.). Note here that the ancestors here only includes slots that are present in the current status cache. Signatures for banks earlier than those present in the status cache would not be queryable anyway, so those banks are not included in the commitment calculations here.

Now we can naturally augment the above computation to also build a BlockCommitment array for every bank b by:

  1. Adding a ForkCommitmentCache to collect the BlockCommitment structs
  2. Replacing f with f' such that the above computation also builds this BlockCommitment for every bank b.

We will proceed with the details of 2) as 1) is trivial.

Before continuing, it is noteworthy that for some validator's vote account a, the number of local confirmations for that validator on slot s is v.num_confirmations, where v is the smallest vote in the stack of votes a.votes such that v.slot >= s (i.e. there is no need to look at any votes > v as the number of confirmations will be lower).

Now more specifically, we augment the above computation to:

   let output: HashMap<b, Stake> = HashMap::new();
   let fork_commitment_cache = ForkCommitmentCache::default();
   for vote_account in b.vote_accounts {
       // vote stack is sorted from oldest vote to newest vote
       for (v1, v2) in vote_account.vote_stack.windows(2) {
           for a in ancestors(v1).difference(ancestors(v2)) {
               f'(*output.get_mut(a), *fork_commitment_cache.get_mut(a), vote_account, v);
           }
       }
   }

where f' is defined as:

    fn f`(
        stake: &mut Stake,
        some_ancestor: &mut BlockCommitment,
        vote_account: VoteAccount,
        v: Vote, total_stake: u64
    ){
        f(stake, vote_account, v);
        *some_ancestor.commitment[v.num_confirmations] += vote_account.stake;
    }