Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial specification for block stream data. #342

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
747 changes: 747 additions & 0 deletions block/block_service.proto

Large diffs are not rendered by default.

71 changes: 71 additions & 0 deletions block/stream/block.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* # Block Stream
* The base element of the block stream _at rest_.
* A `Block` contains a record of all transactions, results, and outputs for
* a block in the chain. Each `Block` also contains a state proof for
* validation and a header with version and algorithm information.
*
* Block entries are not designed for streaming, but for storing blocks in
* persistent storage, verifying block stream data, and as query responses
* when a block is requested from a block node.
*
* ### Keywords
* The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
* "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
* document are to be interpreted as described in
* [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
* [RFC8174](https://www.ietf.org/rfc/rfc8174).
*/
syntax = "proto3";

package com.hedera.hapi.block.stream;

/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

option java_package = "com.hedera.hapi.block.stream.protoc";
// <<<pbj.java_package = "com.hedera.hapi.block.stream">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

import "stream/block_item.proto";

/**
* A single complete Hedera block chain block.
*
* This is a single block structure and SHALL NOT represent the primary
* mechanism to transmit a block stream.<br/>
* The primary mechanism for transmitting block stream data SHALL be to
* stream individual block items to the block node(s).<br/>
* The only delimiter between blocks when streamed SHALL be the `BlockHeader`
* item and `BlockProof` item.
*
* This block SHALL be verifiable as correct using only data in the block,
* including the `BlockProof`, and public keys for the consensus nodes.
*/
message Block {
/**
* A list of items that, together, make up this block.
* <p>
* This list SHALL begin with a `BlockHeader`.<br/>
* This list SHALL end with a `BlockProof`.<br/>
* Items in this list SHALL be in exactly the same order produced by
* consensus.<br/>
* Items in this list MAY be filtered, if so requested.<br/>
* If this list is filtered, removed items SHALL be replaced with
* `FilteredBlockItem` entries.<br/>
*/
repeated BlockItem items = 1;
}
156 changes: 156 additions & 0 deletions block/stream/block_header.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* # Block Header
* The block header reports information required to correctly process a block.
* This includes versions, block number, and algorithms used.
*
* ### Keywords
* The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
* "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
* document are to be interpreted as described in
* [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
* [RFC8174](https://www.ietf.org/rfc/rfc8174).
*/
syntax = "proto3";

package com.hedera.hapi.block.stream;

/*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

option java_package = "com.hedera.hapi.block.stream.protoc";
// <<<pbj.java_package = "com.hedera.hapi.block.stream">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

import "basic_types.proto";

/**
* A Block Header.
*
* Each block in the block stream SHALL begin with a block header.<br/>
* The block header SHALL provide the base minimum information needed to
* correctly interpret and process that block, or stop processing
* if appropriate.<br/>
* The block header MUST describe, at minimum, the following items.
* - The version of the block stream data
* - The block number
* - The hash of the previous block
* - The hash algorithm used to generate the block hash
*
* All fields of this message are REQUIRED, with the exception that
* `hash_algorithm` MAY be _transmitted_ as a default value to improve
* data efficiency.
*/
message BlockHeader {
/**
* A version of the HAPI specification.<br/>
* This is the API version that was used to serialize the block.
*/
proto.SemanticVersion hapi_proto_version = 1;

/**
* A version of the consensus node software.<br/>
* This is the software version that executed the transactions
* within this block.
*/
proto.SemanticVersion software_version = 2;

/**
* A block number for this block.
* <p>
* This value MUST be exactly `1` more than the previous block.<br/>
* Client systems SHOULD optimistically reject any block with a gap or
* reverse in `number` sequence, and MAY assume the block stream has
* encountered data loss, data corruption, or unauthorized modification.
*/
uint64 number = 3;

/**
* A block root hash for the previous block.
* <p>
* This value MUST match the block merkle tree root hash of the previous
* block in the block stream.<br/>
* This value SHALL be empty for the genesis block, and SHALL NOT be empty
* for any other block.<br/>
* Client systems SHOULD optimistically reject any block with a
* `previous_block_proof_hash` that does not match the block hash of the
* previous block and MAY assume the block stream has encountered data
* loss, data corruption, or unauthorized modification.
* <p>
* The process for computing a block hash is somewhat complex, and involves
* creating a "virtual" merkle tree to obtain the root merkle hash of
* that virtual tree.<br/>
* The merkle tree SHALL have a 4 part structure with 2 internal nodes,
* structured in a strictly binary tree.
* <ul>
* <li>The merkle tree root SHALL be the parent of both
* internal nodes.
* <ol>
* <li>The first "internal" node SHALL be the parent of the
* two "left-most" nodes.
* <ol>
* <li>The first leaf MUST be the previous block hash, and is a
* single 48-byte value.</li>
* <li>The second leaf MUST be the root of a, strictly binary,
* merkle tree composed of all "input" block items in
* the block.<br/>
* Input items SHALL be transactions, system transactions,
* and events.<br/>
* Leaf nodes in this subtree SHALL be ordered in the
* same order that the block items are encountered
* in the stream.</li>
* </ol>
* </li>
* <li>The second "internal" node SHALL be the parent of the
* two "right-most" nodes.
* <ol>
* <li>The third leaf MUST be the root of a, strictly binary,
* merkle tree composed of all "output" block items in
* the block.<br/>
* Output items SHALL be transaction result, transaction
* output, and state changes.<br/>
* Leaf nodes in this subtree SHALL be ordered in the
* same order that the block items are encountered
* in the stream.</li>
* <li>The fourth leaf MUST be the merkle tree root hash for
* network state at the end of the block, and is a single
* 48-byte value.</li>
* </ol>
* </li>
* </ol>
* </li>
* <li>The block hash SHALL be the SHA-384 hash calculated for the root
* of this merkle tree.</li>
* </ul>
*/
bytes previous_block_hash = 4;

/**
* A hash algorithm used for this block, including the block proof.
* <p>
* This SHOULD always be `SHA2_384`, currently.
*/
proto.BlockHashAlgorithm hash_algorithm = 5;

/**
* A version for the network address book.<br/>
* The address book version is needed to determine the correct public
* key(s) to use to validate block signatures and state proofs.
* <p>
* This MUST be the version of the address book that signed this
* block.
*/
proto.SemanticVersion address_book_version = 6;
}
Loading