CINXE.COM

IPLD ♦

<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="/css/layout.css?1738557326388"> <link rel="stylesheet" href="/css/nav.css?1738557326388"> <link rel="stylesheet" href="/css/style.css?1738557326388"> <link rel="stylesheet" href="/css/prismjs@1.24-themes-prism.css"> <title>IPLD ♦ </title> </head> <body> <header> <div class="sidebar-button" onclick="document.getElementById('sidebar').classList.toggle('sidebar-open')"> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"> <path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path> </svg> </div> <a href="/" class="logo">IPLD</a> <aside id=breadcrumbs> <ul> <li><a href="/specs">specs</a></li> <li><a href="/specs/codecs">codecs</a></li> <li><a href="/specs/codecs/dag-cosmos">dag-cosmos</a></li> <li><a href="/specs/codecs/dag-cosmos/tendermint_chain/">tendermint_chain</a></li> </ul> </aside> </header> <aside id=sidebar> <nav> <ul> <li> <a href="/docs/">Docs</a><ul> <li> <a href="/docs/intro/">Intro</a><ul> <li> <a href="/docs/intro/hello-world/">Hello, World</a></li> <li> <a href="/docs/intro/primer/">The Brief Primer</a></li> <li> <a href="/docs/intro/ecosystem/">InterPlanetary Ecosystem Overview</a></li> <li> <a href="/docs/intro/community/">Finding Community</a></li></ul></li> <li> <a href="/docs/motivation/">Motivation</a><ul> <li> <a href="/docs/motivation/benefits-of-content-addressing/">Benefits of Content Addressing</a></li> <li> <a href="/docs/motivation/data-to-data-structures/">From Data to Data Structures</a></li></ul></li> <li> <a href="/docs/codecs/">Codecs</a><ul> <li> <a href="/docs/codecs/known/">Known Codecs</a><ul> <li> <a href="/docs/codecs/known/dag-cbor/">DAG-CBOR</a></li> <li> <a href="/docs/codecs/known/dag-json/">DAG-JSON</a></li> <li> <a href="/docs/codecs/known/dag-pb/">DAG-PB</a></li></ul></li></ul></li> <li> <a href="/docs/data-model/">Data Model</a><ul> <li> <a href="/docs/data-model/node/">Nodes</a></li> <li> <a href="/docs/data-model/kinds/">Kinds</a></li> <li> <a href="/docs/data-model/pathing/">Pathing</a></li> <li> <a href="/docs/data-model/traversal/">Traversal</a></li></ul></li> <li> <a href="/docs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/docs/advanced-data-layouts/intro/">Intro to ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/naming/">ADL Naming</a></li> <li> <a href="/docs/advanced-data-layouts/signalling/">Signalling ADLs</a></li> <li> <a href="/docs/advanced-data-layouts/dynamic-loading/">Dynamic Loading</a></li> <li> <a href="/docs/advanced-data-layouts/known/">Known ADLs</a></li></ul></li> <li> <a href="/docs/schemas/">Schemas</a><ul> <li> <a href="/docs/schemas/intro/">Introduction</a><ul> <li> <a href="/docs/schemas/intro/compare/">compare</a></li> <li> <a href="/docs/schemas/intro/goals/">Goals</a></li> <li> <a href="/docs/schemas/intro/feature-summary/">Feature Summary</a></li></ul></li> <li> <a href="/docs/schemas/features/">Features</a><ul> <li> <a href="/docs/schemas/features/typekinds/">Type Kinds</a></li> <li> <a href="/docs/schemas/features/representation-strategies/">Representation Strategies</a></li> <li> <a href="/docs/schemas/features/links/">Links</a></li> <li> <a href="/docs/schemas/features/indicating-adls/">Using ADLs in Schemas</a></li></ul></li> <li> <a href="/docs/schemas/using/">Using Wisely</a><ul> <li> <a href="/docs/schemas/using/authoring-guide/">Authoring Guide</a></li> <li> <a href="/docs/schemas/using/migrations/">Migrations</a></li></ul></li></ul></li> <li> <a href="/docs/synthesis/">Synthesis</a><ul> <li> <a href="/docs/synthesis/gtd/">Getting Things Done</a></li> <li> <a href="/docs/synthesis/building-in-alignment/">Building in Alignment</a></li> <li> <a href="/docs/synthesis/how-ipfs-web-gateways-work/">How IPFS Web Gateways Work</a></li> <li> <a href="/docs/synthesis/encryption/">Working With Encryption</a></li></ul></li></ul></li> <li> <a href="/specs/">Specs</a><ul> <li> <a href="/specs/about/">About the Specifications</a></li> <li> <a href="/specs/codecs/">Codecs</a><ul> <li> <a href="/specs/codecs/dag-cbor/">DAG-CBOR</a><ul> <li> <a href="/specs/codecs/dag-cbor/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-cbor/fixtures/">DAG-CBOR Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-cbor/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li> <li> <a href="/specs/codecs/dag-cosmos/">DAG-COSMOS</a><ul> <li> <a href="/specs/codecs/dag-cosmos/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-cosmos/cosmos_state/">cosmos_state</a></li> <li> <a href="/specs/codecs/dag-cosmos/crypto_types/">crypto_types</a></li> <li class="active-page"> <a href="/specs/codecs/dag-cosmos/tendermint_chain/">tendermint_chain</a></li> <li> <a href="/specs/codecs/dag-cosmos/typed_protobuf/">typed_protobuf</a></li></ul></li> <li> <a href="/specs/codecs/dag-eth/">DAG-ETH</a><ul> <li> <a href="/specs/codecs/dag-eth/basic_types/">basic_types</a></li> <li> <a href="/specs/codecs/dag-eth/chain/">chain</a></li> <li> <a href="/specs/codecs/dag-eth/convenience_types/">convenience_types</a></li> <li> <a href="/specs/codecs/dag-eth/state/">state</a></li></ul></li> <li> <a href="/specs/codecs/dag-jose/">DAG-JOSE</a><ul> <li> <a href="/specs/codecs/dag-jose/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-jose/fixtures/">fixtures</a></li></ul></li> <li> <a href="/specs/codecs/dag-json/">DAG-JSON</a><ul> <li> <a href="/specs/codecs/dag-json/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-json/fixtures/">DAG-JSON Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-json/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li> <li> <a href="/specs/codecs/dag-pb/">DAG-PB</a><ul> <li> <a href="/specs/codecs/dag-pb/spec/">Spec</a></li> <li> <a href="/specs/codecs/dag-pb/fixtures/">DAG-PB Test Fixtures</a><ul> <li> <a href="/specs/codecs/dag-pb/fixtures/cross-codec/">cross-codec</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/advanced-data-layouts/">Advanced Data Layouts</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/">FBL ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/fbl/spec/">spec</a></li></ul></li> <li> <a href="/specs/advanced-data-layouts/hamt/">HAMT ADL</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/spec/">spec</a></li> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/">HashMap (HAMT) Test Fixtures</a><ul> <li> <a href="/specs/advanced-data-layouts/hamt/fixture/alice-words/">alice-words</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/schemas/">Schemas</a><ul> <li> <a href="/specs/schemas/prelude/">prelude</a></li></ul></li> <li> <a href="/specs/transport/">Transports</a><ul> <li> <a href="/specs/transport/car/">CAR</a><ul> <li> <a href="/specs/transport/car/carv1/">CARv1 Specification</a></li> <li> <a href="/specs/transport/car/carv2/">CARv2 Specification</a></li> <li> <a href="/specs/transport/car/fixture/">CAR Test Fixtures</a><ul> <li> <a href="/specs/transport/car/fixture/carv1-basic/">carv1-basic</a></li> <li> <a href="/specs/transport/car/fixture/carv2-basic/">carv2-basic</a></li></ul></li></ul></li> <li> <a href="/specs/transport/graphsync/">Graphsync</a><ul> <li> <a href="/specs/transport/graphsync/known_extensions/">known_extensions</a></li></ul></li> <li> <a href="/specs/transport/trustless-pathing/">Trustless Pathing</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/">Trustless Pathing Fixtures</a><ul> <li> <a href="/specs/transport/trustless-pathing/fixtures/unixfs_20m_variety/">unixfs_20m_variety</a></li></ul></li></ul></li></ul></li> <li> <a href="/specs/selectors/">Selectors</a><ul> <li> <a href="/specs/selectors/fixtures/">fixtures</a><ul> <li> <a href="/specs/selectors/fixtures/selector-fixtures-1/">selector-fixtures-1</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-adl/">selector-fixtures-adl</a></li> <li> <a href="/specs/selectors/fixtures/selector-fixtures-recursion/">selector-fixtures-recursion</a></li></ul></li></ul></li> <li> <a href="/specs/patch/">Patch</a><ul> <li> <a href="/specs/patch/fixtures/">IPLD Patch Test Fixtures</a><ul> <li> <a href="/specs/patch/fixtures/fixtures-1/">fixtures-1</a></li></ul></li></ul></li></ul></li> <li> <a href="/libraries/">Libraries</a><ul> <li> <a href="/libraries/golang/">Golang</a></li> <li> <a href="/libraries/java/">Java</a></li> <li> <a href="/libraries/javascript/">JavaScript</a></li> <li> <a href="/libraries/python/">Python</a></li> <li> <a href="/libraries/rust/">Rust</a></li></ul></li> <li> <a href="/design/">Design</a><ul> <li> <a href="/design/objectives/">Objectives</a></li> <li> <a href="/design/concepts/">Concepts</a><ul> <li> <a href="/design/concepts/type-theory-glossary/">type-theory-glossary</a></li></ul></li> <li> <a href="/design/libraries/">Libraries</a><ul> <li> <a href="/design/libraries/nodes-and-kinds/">nodes-and-kinds</a></li></ul></li> <li> <a href="/design/tricky-choices/">Tricky Choices</a><ul> <li> <a href="/design/tricky-choices/dag-pb-forms-impl-and-use/">dag-pb-forms-impl-and-use</a></li> <li> <a href="/design/tricky-choices/map-key-domain/">map-key-domain</a></li> <li> <a href="/design/tricky-choices/numeric-domain/">numeric-domain</a></li> <li> <a href="/design/tricky-choices/ordering/">ordering</a></li> <li> <a href="/design/tricky-choices/string-domain/">string-domain</a></li></ul></li> <li> <a href="/design/open-research/">Open Research</a><ul> <li> <a href="/design/open-research/ADL-autoexecution/">ADL autoexecution</a></li></ul></li></ul></li> <li> <a href="/tools/">Tools</a></li> <li> <a href="/glossary/">Glossary</a></li> <li> <a href="/media/">Media</a></li> <li> <a href="/FAQ/">FAQ</a></li></ul> </nav> </aside> <main> <div class=content> <h1>Tendermint Chain Data Structures</h1> <p>Tendermint is a generic proof-of-stake consensus layer that provides Byzantine fault tolerant state machine replication for any state machine that conforms to the Application BlockChain Interface (ABCI) or ABCI++. For more details on Tendermint and ABCI/ABCI++, see the specification <a href="https://github.com/tendermint/tendermint/tree/master/spec">here</a>.</p> <h2 id="tendermint-merkle-tree-nodes" tabindex="-1"><a class="header-anchor" href="#tendermint-merkle-tree-nodes">Tendermint Merkle Tree Nodes</a></h2> <p>A Merkle tree node is a single node in a Merkle tree. A Merkle node is referenced by its hash. The top-level node in the tree is the root node, its hash is the Merkle root. Tendermint uses the RFC 6962 specification of a merkle tree, with SHA256 as the hash function.</p> <ul> <li>The hash of an inner node is <code>SHA256(0x01 || left_hash || right_hash)</code>.</li> <li>The hash of a leaf node is <code>SHA256(0x00 || value)</code>.</li> <li>The multicodec type used for a Merkle tree will depend on the content it stores</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">MerkleTreeNode</span></span> <span class="token builtin">union</span> <span class="token punctuation">{</span> <span class="token punctuation">|</span> MerkleTreeRootNode <span class="token string">"root"</span> <span class="token punctuation">|</span> MerkleTreeInnerNode <span class="token string">"inner"</span> <span class="token punctuation">|</span> MerkleTreeLeafNode <span class="token string">"leaf"</span> <span class="token representation">} <span class="token builtin">representation</span></span> keyed <span class="token comment"># MerkleTreeRootNode is the top-most node in a merkle tree; the root node of the tree.</span> <span class="token comment"># It can be a leaf node if there is only one value in the tree</span> <span class="token comment"># We explicitly type the root node for the purposes of handling Block and Header marshalling</span> <span class="token comment"># since entire sub-dags need to be collapsed down and encoded into the protobuf object we need to be</span> <span class="token comment"># able to check that the ipld.Node provided to the marshaller is a root node</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">MerkleTreeRootNode</span></span> MerkleTreeNode <span class="token comment"># MerkleTreeInnerNode nodes contain two byte arrays which contain the hashes which link its two child nodes.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">MerkleTreeInnerNode</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Left <span class="token keyword">nullable</span> <span class="token punctuation">&amp;</span>MerkleTreeNode Right <span class="token keyword">nullable</span> <span class="token punctuation">&amp;</span>MerkleTreeNode <span class="token punctuation">}</span> <span class="token comment"># Value union type used to handle the different values stored in leaf nodes in the different merkle trees</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Value</span></span> <span class="token builtin">union</span> <span class="token punctuation">{</span> <span class="token punctuation">|</span> SimpleValidator <span class="token string">"validator"</span> <span class="token punctuation">|</span> Evidence <span class="token string">"evidence"</span> <span class="token punctuation">|</span> TypedTxCID <span class="token string">"tx"</span> <span class="token punctuation">|</span> Part <span class="token string">"part"</span> <span class="token punctuation">|</span> ResponseDeliverTx <span class="token string">"result"</span> <span class="token punctuation">|</span> Bytes <span class="token string">"header"</span> <span class="token punctuation">|</span> CommitSig <span class="token string">"commit"</span> <span class="token representation">} <span class="token builtin">representation</span></span> keyed <span class="token comment"># MerkleTreeLeafNode is a single byte array containing the value stored at that leaf</span> <span class="token comment"># Often times this "value" will be a hash of content rather than the content itself</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">MerkleTreeLeafNode</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Value Value <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-block" tabindex="-1"><a class="header-anchor" href="#tendermint-block">Tendermint Block</a></h2> <p>A block consists of a header, transactions, votes (the commit), and a list of evidence of malfeasance (i.e. signing conflicting votes). Blocks are indirectly content-hash referenced by the root of a Merkle tree composed of its parts.</p> <p>In order to support this indirect content referencing, we introduce a new multihash type: SHA256_MERKLE. This multihash type stipulates that the hash is an SHA256 RFC 6962 specification Merkle tree root hash.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># BlockCID is a CID link to a Tendermint block, this link is indirect by means of reference to the root node of a Part</span> <span class="token comment"># Merkle tree (formed from all of the parts of a complete block) rather than a direct reference by hash of the block itself</span> <span class="token comment"># This CID is composed of the SHA256 multihash of the root node in the Block Part Merkle Tree and the TendermintBlock codec (tbd)</span> <span class="token comment"># Part merkle tree is a Merkle tree built from the PartSet, each leafs contains Part.Bytes</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">BlockCID</span></span> <span class="token punctuation">&amp;</span>Block <span class="token comment"># Block defines the atomic unit of a Tendermint blockchain</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Block</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Header Header Data Txs Evidence EvidenceList LastCommit Commit <span class="token punctuation">}</span> <span class="token comment"># BlockID contains two distinct Merkle roots of the block.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">BlockID</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> HeaderCID HeaderFieldTreeCID PartSetHeader PartSetHeader <span class="token punctuation">}</span> <span class="token comment"># PartSetHeader is used for secure gossiping of the block during consensus</span> <span class="token comment"># It contains the Merkle root of the complete serialized block cut into parts (ie. MerkleRoot(MakeParts(block))).</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">PartSetHeader</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Total Uint BlockCID BlockPartTreeCID <span class="token punctuation">}</span> <span class="token comment"># PartSet is the complete set of parts for a header</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">PartSet</span></span> <span class="token punctuation">[</span>Part<span class="token punctuation">]</span> <span class="token comment"># Part is a section of bytes of a complete protobuf serialized block</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Part</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Index Uint Bytes HexBytes Proof Proof <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-block-part-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-block-part-tree">Tendermint Block Part Tree</a></h2> <p>This is the IPLD schema for Block Part Merkle Tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is of type <code>Part</code>.</p> <ul> <li>The Block Part Merkle Tree is a Merkle tree built from the set of block <code>Part</code>s, these are byte segments of the serialized block.</li> <li>The block binary is segmented across parts based on a chunk size. In this manner, the fields of the block do not map to specific leaves but instead the binary for a specific field can be spread across multiple leaves and a single leaf may contain chunks of different fields.</li> <li>CID links to a <code>BlockPartTreeNode</code> use an SHA256 multihash of the node binary and the TendermintBlockPartTree codec (tbd).</li> <li>The root node of this tree for block <code>n-1</code> is referenced in a Tendermint <code>PartSetHeader</code> by the <code>BlockCID</code> at block <code>n</code>.</li> <li>The <code>PartSetHeader</code> is part of the <code>BlockID</code>.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># BlockPartTreeNode is an IPLD block for a node in a Block Part merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">BlockPartTreeNode</span></span> MerkleTreeNode <span class="token comment"># BlockPartTreeCID is a CID link to a node of a Block Part merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">BlockPartTreeCID</span></span> <span class="token punctuation">&amp;</span>BlockPartTreeNode</code></pre> <h2 id="tendermint-header" tabindex="-1"><a class="header-anchor" href="#tendermint-header">Tendermint Header</a></h2> <p>A block header contains metadata about the block and about the consensus, as well as commitments to the data in the current block, the previous block, and the results returned by the application. Similar to blocks, headers are indirectly content-hash referenced by the root of a Merkle tree composed of the header's separate fields.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># HeaderCID is a CID link to a Tendermint header, this link is indirect by means of a reference to the root node of a</span> <span class="token comment"># Header merkle tree (formed from all the fields of a header) rather than a direct reference by hash of the header itself</span> <span class="token comment"># This CID is composed of the SHA256 multihash of the root node in the Header Merkle Tree and the TendermintHeader codec (tbd)</span> <span class="token comment"># Header merkle tree is a Merklization of all of the fields in the header, each leaf stores a single protobuf encoded field</span> <span class="token comment"># and the order of these fields in the Merkle Tree corresponds with their order in the header object</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">HeaderCID</span></span> <span class="token punctuation">&amp;</span>Header <span class="token comment"># Header defines the structure of a Tendermint block header</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Header</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> <span class="token comment"># basic block info</span> Version Version ChainID String Height Int Time Time <span class="token comment"># prev block info</span> <span class="token comment"># the first block has an empty BlockID struct as LastBlockID</span> LastBlockID BlockID <span class="token comment"># hashes of block data</span> LastCommitCID CommitTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from the last block's set of commit signatures</span> DataCID TxTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from this block's set of transactions</span> <span class="token comment"># hashes from the app output from the prev block</span> ValidatorsCID ValidatorTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from this block's validator set</span> NextValidatorsCID ValidatorTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from the next validator set</span> ConsensusCID HashedParamsCID <span class="token comment"># CID link to HashedParams</span> AppCID AppStateTreeCID <span class="token comment"># State Root from the state machine</span> <span class="token comment"># root hash of all results from the txs from the previous block</span> LastResultsCID ResultTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from the last block's set of results</span> <span class="token comment"># consensus info</span> EvidenceCID EvidenceTreeCID <span class="token comment"># CID link to the root node of a Merkle Tree formed from this block's set of evidence</span> ProposerAddress Address <span class="token comment"># Address of the original proposer of this block, which must a validator in the current validator set</span> <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-header-field-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-header-field-tree">Tendermint Header Field Tree</a></h2> <p>This is the IPLD schema for header field tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is of type <code>Bytes</code>.</p> <ul> <li>The Header Field merkle tree is a Merkle tree built from the individual fields of a <code>Header</code>.</li> <li>Each protobuf serialized field is stored in a leaf node, in the order they appear in the <code>Header</code> object. As such, each leaf stores a different type of value.</li> </ul> <pre><code>LeafIndex0 = protobuf(Version) LeafIndex1 = protobuf(ChainID) LeafIndex2 = protobuf(Height) LeafIndex3 = protobuf(Time) LeafIndex4 = protobuf(LastBlockID) LeafIndex5 = protobuf(LastCommitID) LeafIndex6 = protobuf(DataCID) LeafIndex7 = protobuf(ValidatorsCID) LeafIndex8 = protobuf(NextValidatorsCID) LeafIndex9 = protobuf(ConsensusCID) LeafIndex10 = protobuf(AppCID) LeafIndex11 = protobuf(LastResultsCID) LeafIndex12 = protobuf(EvidenceCID) LeafIndex13 = protobuf(ProsperAddress) </code></pre> <p>For a visual representation of the above, see the included <a href="../tendermint_dag.png">diagram</a>.</p> <ul> <li>CID links to a <code>HeaderFieldTreeNode</code> use an SHA256 multihash of the node binary and the TendermintHeaderFieldTree codec (tbd).</li> <li>The root node of this tree at block <code>n-1</code> is referenced in a Tendermint <code>BlockID</code> by the <code>BlockCID</code> at block <code>n</code>.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># HeaderFieldTreeNode is an IPLD block for a node in a Header Field merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">HeaderFieldTreeNode</span></span> MerkleTreeNode <span class="token comment"># HeaderFieldTreeCID is a CID link to a node of a Header Field merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">HeaderFieldTreeCID</span></span> <span class="token punctuation">&amp;</span>HeaderFieldTreeNode</code></pre> <h2 id="tendermint-light-block" tabindex="-1"><a class="header-anchor" href="#tendermint-light-block">Tendermint Light Block</a></h2> <p>LightBlock is the core data structure of the light client. It combines two data structures needed for verification (SignedHeader &amp; ValidatorSet). CID links to LightBlock use the SHA256 multihash and the LightBlock codec (tbd).</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># LightBlock is a SignedHeader and a ValidatorSet.</span> <span class="token comment"># It is the basis of the light client</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">LightBlock</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> SignedHeader SignedHeader ValidatorSet ValidatorSet <span class="token punctuation">}</span> <span class="token comment"># SignedHeader is a header along with the commits that prove it.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">SignedHeader</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Header Header Commit Commit <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-validator-and-validator-set" tabindex="-1"><a class="header-anchor" href="#tendermint-validator-and-validator-set">Tendermint Validator and Validator Set</a></h2> <p>A Validator object is used to uniquely identify a Tendermint validator. A Validator Set is used to help verify that the validators that committed a infraction were truly in the validator set.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># ValidatorSet represent a set of Validators at a given height.</span> <span class="token comment">#</span> <span class="token comment"># The validators can be fetched by address or index.</span> <span class="token comment"># The index is in order of .VotingPower, so the indices are fixed for all</span> <span class="token comment"># rounds of a given blockchain height - ie. the validators are sorted by their</span> <span class="token comment"># voting power (descending). Secondary index - .Address (ascending).</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ValidatorSet</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Validators Validators Proposer Validator <span class="token punctuation">}</span> <span class="token comment"># Validators is a list of validators</span> types Validators <span class="token punctuation">[</span>Validator<span class="token punctuation">]</span> <span class="token comment"># Volatile state for each Validator</span> <span class="token comment"># NOTE: The Address and ProposerPriority is not included in Validator.Hash();</span> <span class="token comment"># make sure to update that method if changes are made here</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Validator</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Address Address <span class="token comment"># Not included in the hash</span> PubKey PubKey VotingPower Int ProposerPriority Int <span class="token comment"># Not included in the hash</span> <span class="token punctuation">}</span> <span class="token comment"># SimpleValidator contains only the consensus fields of a Validator</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">SimpleValidator</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> PubKey PubKey VotingPower Int <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-validator-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-validator-tree">Tendermint Validator Tree</a></h2> <p>This is the IPLD schema for validator tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is <code>SimpleValidator</code>.</p> <ul> <li>The Validator Merkle Tree is a Merkle Tree built from the set of <code>SimpleValidator</code>s for the given block</li> <li>The validators are first sorted by voting power (descending), then by address (ascending) to determine their index in the tree.</li> <li>Leaves contain a protobuf serialized <code>SimpleValidator</code> object, which contains consensus fields for a validator.</li> <li>CID links to a <code>ValidatorTreeNode</code> use an SHA256 multihash of the node binary and the TendermintValidatorTree codec (tbd).</li> <li>The root node of this tree is referenced in a Tendermint <code>Header</code> by the <code>ValidatorsCID</code> for the current set at the current block height and the <code>NextValidatorsCID</code> for the set at the next block height.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># ValidatorTreeNode is an IPLD block for a node in a Validator merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ValidatorTreeNode</span></span> MerkleTreeNode <span class="token comment"># ValidatorTreeCID is a CID link to a node of a Validator merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ValidatorTreeCID</span></span> <span class="token punctuation">&amp;</span>ValidatorTreeNode</code></pre> <h2 id="tendermint-evidence-list-and-evidence" tabindex="-1"><a class="header-anchor" href="#tendermint-evidence-list-and-evidence">Tendermint Evidence List and Evidence</a></h2> <p>Evidence in Tendermint is used to indicate breaches in the consensus by a validator.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># EvidenceList is a simple wrapper for a list of evidence</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">EvidenceList</span></span> <span class="token punctuation">[</span>Evidence<span class="token punctuation">]</span> <span class="token comment"># Evidence in Tendermint is used to indicate breaches in the consensus by a validator</span> <span class="token comment"># Currently there are two types of Evidence</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Evidence</span></span> <span class="token builtin">union</span> <span class="token punctuation">{</span> <span class="token punctuation">|</span> DuplicateVoteEvidence <span class="token string">"duplicate"</span> <span class="token punctuation">|</span> LightClientAttackEvidence <span class="token string">"light"</span> <span class="token representation">} <span class="token builtin">representation</span></span> keyed <span class="token comment"># DuplicateVoteEvidence represents a validator that has voted for two different blocks in the same round of the same height.</span> <span class="token comment"># Votes are lexicographically sorted on BlockID.</span> type `DuplicateVoteEvidence` <span class="token builtin">struct</span> <span class="token punctuation">{</span> VoteA Vote VoteB Vote <span class="token comment"># abci specific information</span> TotalVotingPower Int ValidatorPower Int Timestamp Time <span class="token punctuation">}</span> <span class="token comment"># Vote represents a prevote, precommit, or commit vote from validators for</span> <span class="token comment"># consensus.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Vote</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> SMType SignedMsgType Height Int Round Int BlockID BlockID Timestamp Time ValidatorAddress Address ValidatorIndex Int Signature Signature <span class="token punctuation">}</span> <span class="token comment"># SignedMsgType is the type of signed message in the consensus.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">SignedMsgType</span></span> <span class="token builtin">enum</span> <span class="token punctuation">{</span> <span class="token punctuation">|</span> UnknownType <span class="token punctuation">(</span><span class="token string">"0"</span><span class="token punctuation">)</span> <span class="token punctuation">|</span> PrevoteType <span class="token punctuation">(</span><span class="token string">"1"</span><span class="token punctuation">)</span> <span class="token punctuation">|</span> PrecommitType <span class="token punctuation">(</span><span class="token string">"2"</span><span class="token punctuation">)</span> <span class="token punctuation">|</span> ProposalType <span class="token punctuation">(</span><span class="token string">"32"</span><span class="token punctuation">)</span> <span class="token representation">} <span class="token builtin">representation</span></span> <span class="token keyword">int</span> <span class="token comment"># LightClientAttackEvidence is a generalized evidence that captures all forms of known attacks on</span> <span class="token comment"># a light client such that a full node can verify, propose and commit the evidence on-chain for</span> <span class="token comment"># punishment of the malicious validators. There are three forms of attacks: Lunatic, Equivocation and Amnesia.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">LightClientAttackEvidence</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> ConflictingBlock LightBlock CommonHeight Int <span class="token comment"># abci specific information</span> ByzantineValidators <span class="token punctuation">[</span>Validator<span class="token punctuation">]</span> <span class="token comment"># Validators in the validator set that misbehaved in creating the conflicting block</span> TotalVotingPower Int <span class="token comment"># Total voting power of the validator set at the common height</span> Timestamp Time <span class="token comment"># Timestamp of the block at the common height</span> <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-evidence-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-evidence-tree">Tendermint Evidence Tree</a></h2> <p>This is the IPLD schema for evidence tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is <code>Evidence</code>.</p> <ul> <li>The Evidence Merkle Tree is Merkle Tree built from the list of Evidence of Byzantine behaviour included in this block.</li> <li>Leaves contain a protobuf serialized <code>Evidence</code> object, either <code>DuplicateVoteEvidence</code> or <code>LightClientAttackEvidence</code>.</li> <li>CID links to a <code>EvidenceTreeNode</code> use an SHA256 multihash of the node binary and the TendermintEvidenceTree codec (tbd).</li> <li>The root node of this tree is referenced in a Tendermint <code>Header</code> by the <code>EvidenceCID</code>.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># EvidenceTreeNode is an IPLD block for a node in an Evidence merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">EvidenceTreeNode</span></span> MerkleTreeNode <span class="token comment"># EvidenceTreeCID is a CID link to a node of an Evidence merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">EvidenceTreeCID</span></span> <span class="token punctuation">&amp;</span>EvidenceTreeNode</code></pre> <h2 id="tendermint-transaction" tabindex="-1"><a class="header-anchor" href="#tendermint-transaction">Tendermint Transaction</a></h2> <p>Transactions in Tendermint are unstructured byte arrays from the perspective of the Tendermint client. This is necessary to support any arbitrary ABCI/ABCI++ compliant state machine. The state machine is responsible for decoding and applying these transactions in a deterministic capacity.</p> <p>For CosmosSDK based state machines these transactions are always protobuf encoded objects, if we accept this as the general case we can provide rich content typing using the protobuf typing scheme described in <a href="../typed_protobuf">typed_protobuf.md</a>.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># TypedTx is an alias for a TypedProtobuf object</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">TypedTx</span></span> TypedProtobuf <span class="token comment"># TypedTxCID is an alias for a TypedProtobufCID</span> <span class="token comment"># This CID is composed of the SHA2-256-Ignore32BytePrefix multihash of the TypedProtobuf IPLD block binary and the TypedProtobuf codec (tbd)</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">TypedTxCID</span></span> TypedProtobufCID</code></pre> <h2 id="tendermint-tx-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-tx-tree">Tendermint Tx Tree</a></h2> <p>This is the IPLD schema for tx tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is a <code>TxTreeCID</code>.</p> <ul> <li>The Tx Merkle Tree is Merkle Tree built from the list of transactions included in this block, ordered by their index in the block.</li> <li>A transaction is an unstructured byte array, it's decoding is dependent on the state machine it is intended for.</li> <li>Leaves contain a hash link (<code>TypedTxCID</code>) to a transaction rather than the transaction itself.</li> <li>CID links to a <code>TxTreeNode</code> use an SHA256 multihash of the node binary and the TxTree codec (tbd).</li> <li>The root node of this tree is referenced in a Tendermint <code>Header</code> by the <code>DataCID</code>.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># TxTreeNode is an IPLD block for a node in a Tx merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">TxTreeNode</span></span> MerkleTreeNode <span class="token comment"># TxTreeCID is a CID link to a node in a Tx merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">TxTreeCID</span></span> <span class="token punctuation">&amp;</span>TxTreeNode</code></pre> <h2 id="tendermint-result" tabindex="-1"><a class="header-anchor" href="#tendermint-result">Tendermint Result</a></h2> <p>The result object contains the consensus fields of an ABCI ResponseDeliverTx.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># ResponseDeliverTx are the consensus fields of an ABCI ResponseDeliverTx, that are included in the ResultTree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ResponseDeliverTx</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> Code Uint Data Bytes GasWanted Int GasUsed Int <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-result-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-result-tree">Tendermint Result Tree</a></h2> <p>This is the IPLD schema for result tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is a <code>ResponseDeliverTx</code>.</p> <ul> <li>The Result Merkle Tree is Merkle tree built from the list of the consensus results included in the previous block, ordered by their index in the block.</li> <li>Leaves contain a protobuf serialized <code>ResponseDeliverTx</code>, this object contains only the consensus fields of the ABCI <code>ResponseDeliverTx</code>.</li> <li>CID links to a <code>ResultTreeNode</code> use an SHA256 multihash of the node binary and the TendermintResultTree codec (tbd).</li> <li>The root node of this tree is referenced in a Tendermint <code>Header</code> by the <code>LastResultsCID</code>.</li> <li>The first block has an empty Result tree. The <code>LastResultsCID</code> will be derived from the hash of an empty input, for RFC-6962 conformance.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># ResultTreeNode is an IPLD block for a node in a Result merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ResultTreeNode</span></span> MerkleTreeNode <span class="token comment"># ResultTreeCID is a CID link to a node in a Result merkle tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">ResultTreeCID</span></span> <span class="token punctuation">&amp;</span>ResultTreeNode</code></pre> <h2 id="tendermint-commit-and-commitsig" tabindex="-1"><a class="header-anchor" href="#tendermint-commit-and-commitsig">Tendermint Commit and CommitSig</a></h2> <p>Commit is a simple wrapper for a list of commit signatures for every validator at a block, as well as the associated BlockID and corresponding block height and round.</p> <p>CommitSig represents a signature of a validator, who has voted either for nil, a particular BlockID, or was absent. It's a part of the Commit and can be used to reconstruct the vote set given the validator set.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># Commit contains the evidence that a block was committed by a set of validators</span> <span class="token comment"># NOTE: Commit is empty for height 1, but never nil.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Commit</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> <span class="token comment"># NOTE: The signatures are in order of address to preserve the bonded</span> <span class="token comment"># ValidatorSet order.</span> <span class="token comment"># Any peer with a block can gossip signatures by index with a peer without</span> <span class="token comment"># recalculating the active ValidatorSet.</span> Height Int <span class="token comment"># Height at which this commit was created</span> Round Int <span class="token comment"># Round that the commit corresponds to</span> BlockID BlockID <span class="token comment"># The BlockID of the corresponding block</span> Signatures Signatures <span class="token comment"># Array of CommitSigs for the validators at this block</span> <span class="token punctuation">}</span> <span class="token comment"># Signatures is a list of CommitSigs</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">Signatures</span></span> <span class="token punctuation">[</span>CommitSig<span class="token punctuation">]</span> <span class="token comment"># CommitSig is a part of the Vote included in a Commit.</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">CommitSig</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> BlockIDFlag BlockIDFlag <span class="token comment"># Represents the validators participation in consensus: Either voted for the block that received the majority, voted for another block, voted nil or did not vote</span> ValidatorAddress Address <span class="token comment"># Address of the validator</span> Timestamp Time Signature Signature <span class="token comment"># Signature corresponding to the validators participation in consensus.</span> <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-commit-tree" tabindex="-1"><a class="header-anchor" href="#tendermint-commit-tree">Tendermint Commit Tree</a></h2> <p>This is the IPLD schema for commit tree nodes. This is an alias for a <code>MerkleTreeNode</code> where the <code>Value</code> union type stored in a leaf node is a <code>CommitSig</code>.</p> <ul> <li>The Commit Merkle Tree is Merkle tree built from the list of the previous block's commit signatures.</li> <li>The signatures represent the validators that committed to the last block.</li> <li>Leaves contain a protobuf serialized <code>CommitSig</code> object.</li> <li>CID links to a <code>CommitTreeNode</code> use an SHA256 multihash of the node binary and the TendermintCommitTree codec (tbd).</li> <li>The root node of this tree is referenced in a Tendermint <code>Header</code> by the <code>LastCommitCID</code>.</li> <li>The first block's Commit Merkle Tree is empty, and its root is represented as an empty byte slice.</li> </ul> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># CommitTreeNode is an IPLD block for a node in a Commit Merkle Tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">CommitTreeNode</span></span> MerkleTreeNode <span class="token comment"># CommitTreeCID is a CID link to a node in a Commit Merkle Tree</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">CommitTreeCID</span></span> <span class="token punctuation">&amp;</span>CommitTreeNode</code></pre> <h2 id="tendermint-params" tabindex="-1"><a class="header-anchor" href="#tendermint-params">Tendermint Params</a></h2> <p>HashedParams contains the max bytes and max gas for a block.</p> <pre class="language-ipldsch"><code class="language-ipldsch"><span class="token comment"># HashedParamsCID is a CID link to the HashedParams for this Header</span> <span class="token comment"># This CID is composed of the SHA256 multihash of the linked protobuf serialized HashedParams object and the TendermintParams codec (tbd)</span> <span class="token comment"># HashedParams are referenced in a Tenderint Header by the ConsensusCID</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">HashParamsCID</span></span> <span class="token punctuation">&amp;</span>HashedParams <span class="token comment"># HashedParams is a subset of ConsensusParams that is included in the consensus encoding</span> <span class="token comment"># It is hashed into the Header.ConsensusHash</span> <span class="token typedef"><span class="token keyword">type</span> <span class="token class-name">HashedParams</span></span> <span class="token builtin">struct</span> <span class="token punctuation">{</span> BlockMaxBytes Int BlockMaxGas Int <span class="token punctuation">}</span></code></pre> <h2 id="tendermint-proposal" tabindex="-1"><a class="header-anchor" href="#tendermint-proposal">Tendermint Proposal</a></h2> <p>A CanonicalProposal contains the consensus fields used to propose a new block for validation.</p> <pre><code># PropsalCID is a CID link to a CanonicalProposal for a block # This CID is composed of the SHA256 multihash of the linked protobuf serialized CanonicalProposal object and the TendermintProposal codec (tbd) type ProposalCID &amp;Proposal # CanonicalProposal defines a block proposal for consensus. # It refers to the block by BlockID field. # It must be signed by the correct proposer for the given Height/Round # to be considered valid. It may depend on votes from a previous round, # a so-called Proof-of-Lock (POL) round, as noted in the POLRound. # If POLRound &gt;= 0, then BlockID corresponds to the block that is locked in POLRound. type CanonicalProposal struct { SMType SignedMsgType Height Int Round Int # There can not be greater than 2_147_483_647 rounds POLRound Int # -1 if null. BlockID BlockID # The block being proposed Timestamp Time ChainID String } </code></pre> </div> </main> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10