Skip to content

Commit 3e79785

Browse files
rbair23actions-userNana-ECedward-swirldslabsjsync-swirlds
authored
HIP-1056: Block Streams (#1056)
Signed-off-by: Joseph S <121976561+jsync-swirlds@users.noreply.github.com> Signed-off-by: Nana Essilfie-Conduah <nana@swirldslabs.com> Signed-off-by: Edward Wertz <edward@swirldslabs.com> Signed-off-by: Edward Wertz <123979964+edward-swirldslabs@users.noreply.github.com> Signed-off-by: Michael Garber <michael.garber@hashgraph.com> Co-authored-by: Richard Bair <rbair23@users.noreply.github.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Nana Essilfie-Conduah <nana@swirldslabs.com> Co-authored-by: Edward Wertz <123979964+edward-swirldslabs@users.noreply.github.com> Co-authored-by: Joseph S. <121976561+jsync-swirlds@users.noreply.github.com> Co-authored-by: Nana Essilfie-Conduah <56320167+Nana-EC@users.noreply.github.com> Co-authored-by: Michael Garber <michael.garber@hashgraph.com>
1 parent 34228eb commit 3e79785

24 files changed

+5181
-0
lines changed

HIP/hip-1056.md

Lines changed: 2004 additions & 0 deletions
Large diffs are not rendered by default.

assets/hip-1056/block-stream-items.svg

Lines changed: 4 additions & 0 deletions
Loading

assets/hip-1056/block-stream-merkle.svg

Lines changed: 4 additions & 0 deletions
Loading

assets/hip-1056/block-stream.svg

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* # Block Stream
3+
* The base element of the block stream _at rest_.
4+
* A `Block` contains a record of all transactions, results, and outputs for
5+
* a block in the chain. Each `Block` also contains a state proof for
6+
* validation and a header with version and algorithm information.
7+
*
8+
* Block entries are not designed for streaming, but for storing blocks in
9+
* persistent storage, verifying block stream data, and as query responses
10+
* when a block is requested from a block node.
11+
*
12+
* ### Keywords
13+
* The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
14+
* "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
15+
* document are to be interpreted as described in
16+
* [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
17+
* [RFC8174](https://www.ietf.org/rfc/rfc8174).
18+
*/
19+
syntax = "proto3";
20+
21+
package com.hedera.hapi.block.stream;
22+
23+
// SPDX-License-Identifier: Apache-2.0
24+
25+
option java_package = "com.hedera.hapi.block.stream.protoc";
26+
// <<<pbj.java_package = "com.hedera.hapi.block.stream">>> This comment is special code for setting PBJ Compiler java package
27+
option java_multiple_files = true;
28+
29+
import "stream/block_item.proto";
30+
31+
/**
32+
* A single complete Hedera block chain block.
33+
*
34+
* This is a single block structure and SHALL NOT represent the primary
35+
* mechanism to transmit a block stream.<br/>
36+
* The primary mechanism for transmitting block stream data SHALL be to
37+
* stream individual block items to the block node(s).<br/>
38+
* The only delimiter between blocks when streamed SHALL be the `BlockHeader`
39+
* item and `BlockProof` item.
40+
*
41+
* This block SHALL be verifiable as correct using only data in the block,
42+
* including the `BlockProof`, and public keys for the consensus nodes.
43+
*/
44+
message Block {
45+
/**
46+
* A list of items that, together, make up this block.
47+
* <p>
48+
* This list SHALL begin with a `BlockHeader`.<br/>
49+
* This list SHALL end with a `BlockProof`.<br/>
50+
* Items in this list SHALL be in exactly the same order produced by
51+
* consensus.<br/>
52+
* Items in this list MAY be filtered, if so requested.<br/>
53+
* If this list is filtered, removed items SHALL be replaced with
54+
* `FilteredBlockItem` entries.<br/>
55+
*/
56+
repeated BlockItem items = 1;
57+
}
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
/**
2+
* # Block Item
3+
* A single item in the block stream, such as transaction data, event metadata,
4+
* or a a system transaction.<br/>
5+
* Each block consists of a block header, one or more block items,
6+
* and a block state proof. Within the block are a series of events delimited
7+
* by start_event block items.
8+
*
9+
* This structure here MUST support a stream of block items with no enclosing
10+
* message.<br/>
11+
* Implementations SHOULD behave in a reasonable manner if used in a gRPC
12+
* bidirectional streaming RPC similar to
13+
* `rpc processBlocks(stream BlockItem) returns (stream Acknowledgement);`.
14+
*
15+
* ### Keywords
16+
* The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
17+
* "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
18+
* document are to be interpreted as described in
19+
* [RFC2119](https://www.ietf.org/rfc/rfc2119) and clarified in
20+
* [RFC8174](https://www.ietf.org/rfc/rfc8174).
21+
*/
22+
syntax = "proto3";
23+
24+
package com.hedera.hapi.block.stream;
25+
26+
// SPDX-License-Identifier: Apache-2.0
27+
28+
option java_package = "com.hedera.hapi.block.stream.protoc";
29+
// <<<pbj.java_package = "com.hedera.hapi.block.stream">>> This comment is special code for setting PBJ Compiler java package
30+
option java_multiple_files = true;
31+
32+
import "event/event_transaction.proto";
33+
import "stream/block_proof.proto";
34+
import "stream/record_file_item.proto";
35+
import "stream/input/event_metadata.proto";
36+
import "stream/input/round_header.proto";
37+
import "stream/output/block_header.proto";
38+
import "stream/output/state_changes.proto";
39+
import "stream/output/smart_contract_service.proto";
40+
import "stream/output/transaction_output.proto";
41+
import "stream/output/transaction_result.proto";
42+
43+
/**
44+
* A single item within a block stream.
45+
*
46+
* Each item in the block stream SHALL be self-contained and independent,
47+
* with the following constraints applicable to the _unfiltered_ stream.
48+
* - A block SHALL start with a `header`.
49+
* - A block SHALL end with a `state_proof`.
50+
* - A `block_header` SHALL be followed by an `event_header`.
51+
* - An `event_header` SHALL be followed by one or more
52+
* `event_transaction` items.
53+
* - An `event_transaction` SHALL be followed by a `transaction_result`.
54+
* - A `transaction_result` MAY be followed by a `transaction_output`.
55+
* - A `transaction_result` (or a `transaction_output`, if present) MAY be
56+
* followed by one or more `state_changes`.
57+
*
58+
* This forms the following required sequence for each block, which is then
59+
* repeated within the block stream, indefinitely. Note that there is no
60+
* container structure in the stream, the indentation below is only to
61+
* highlight repeated subsequences.<br/>
62+
* The order of items within each block below is REQUIRED and SHALL NOT change.
63+
*
64+
* ```text
65+
* header
66+
* repeated {
67+
* start_event
68+
* repeated {
69+
* event_transaction
70+
* transaction_result
71+
* (optional) transaction_output
72+
* (optional) repeated state_changes
73+
* }
74+
* }
75+
* state_proof
76+
* ```
77+
* A filtered stream may exclude some items above, depending on filter
78+
* criteria. A filtered item is replaced with a merkle path and hash value
79+
* to maintain block stream verifiability.
80+
*
81+
* A BlockItem SHALL be individually and directly processed to create the
82+
* item hash.<br/>
83+
* Items to be hashed MUST NOT be contained within another item.<br/>
84+
* Items which might be filtered out of the stream MUST NOT be
85+
* contained in other items.
86+
*
87+
* ### Forward Compatibility
88+
* In order to maximize forward compatibility, and minimize the need to
89+
* coordinate deployments of different systems creating and processing
90+
* block streams in the future, the following rules SHALL be followed
91+
* for field numbering in this message.
92+
* - The first 15 field numbers SHALL be assigned to the fields present
93+
* in the first release. Unused fields in this range SHALL remain reserved
94+
* until needed for additional options that do not fit into "input" or
95+
* "output" categories.
96+
* - Fields numbered 16 and above MUST be numbered as follows.
97+
* - "input" items MUST use `odd` field numbers.
98+
* - "output" items MUST use `even` field numbers.
99+
*
100+
* #### Forward Compatibility Example
101+
* A future update adding three new items. A "BlockTrailer" item which is
102+
* neither input nor output, a new "ConsensusTransform" which is an input,
103+
* and a new "BridgeTransform" which is an output.
104+
* - The "BlockTrailer" is field 12, which is removed from the `reserved` list.
105+
* - The "ConsensusTransform" is an input, so it is field `17` (the first unused
106+
* `odd` field greater than or equal to 16).
107+
* - The "BridgeTransform" is an output, so it is field `16` (the first unused
108+
* even field greater than or equal to 16).
109+
*
110+
* #### Initial Field assignment to "input", "output", and "other" categories.
111+
* - Inputs
112+
* - `event_header`
113+
* - `round_header`
114+
* - `event_transaction`
115+
* - Outputs
116+
* - `block_header`
117+
* - `transaction_result`
118+
* - `transaction_output`
119+
* - `state_changes`
120+
* - Any subtree (depending on what was filtered).
121+
* This item details it's path in the tree.
122+
* - `filtered_item_hash`
123+
* - Neither input nor output (and not part of the "proof" merkle tree)
124+
* - `block_proof`
125+
* - `record_file`
126+
*/
127+
message BlockItem {
128+
// Reserved for future items that are neither "input" nor "output".
129+
reserved 12,13,14,15;
130+
oneof item {
131+
/**
132+
* An header for the block, marking the start of a new block.
133+
*/
134+
com.hedera.hapi.block.stream.output.BlockHeader block_header = 1;
135+
136+
/**
137+
* An header emitted at the start of a new network "event".
138+
* <p>
139+
* This item SHALL contain the properties relevant to a single
140+
* gossip event.
141+
*/
142+
com.hedera.hapi.block.stream.input.EventHeader event_header = 2;
143+
144+
/**
145+
* An header emitted at the start of a new consensus "round".
146+
* <p>
147+
* This item SHALL contain the properties relevant to a single
148+
* consensus round.
149+
*/
150+
com.hedera.hapi.block.stream.input.RoundHeader round_header = 3;
151+
152+
/**
153+
* A single transaction.
154+
* <p>
155+
* This item SHALL contain the serialized bytes of a
156+
* single transaction.<br/>
157+
* Each event transaction SHALL be either a `SignedTransaction` or
158+
* an internal system-generated transaction.<br/>
159+
* This item MUST NOT contain data for more than one
160+
* `SignedTransaction` or system-generated transaction.
161+
*/
162+
com.hedera.hapi.platform.event.EventTransaction event_transaction = 4;
163+
164+
/**
165+
* The result of running a transaction.
166+
* <p>
167+
* This item SHALL be present immediately after an
168+
* `event_transaction` item.<br/>
169+
* This item MAY be redacted in some circumstances, and SHALL be
170+
* replaced with a `filtered_item` if removed.
171+
*/
172+
com.hedera.hapi.block.stream.output.TransactionResult transaction_result = 5;
173+
174+
/**
175+
* A transaction output.
176+
* <p>
177+
* This item MAY not be present if a transaction does not produce
178+
* an output.<br/>
179+
* If a transaction does produce an output that is not reflected
180+
* in state changes, then this item MUST be present after the
181+
* `transaction_result` for that transaction.
182+
*/
183+
com.hedera.hapi.block.stream.output.TransactionOutput transaction_output = 6;
184+
185+
/**
186+
* A set of state changes.
187+
* <p>
188+
* All changes to values in network state SHALL be described by
189+
* stream items of this type.<br/>
190+
* The source of these state changes SHALL be described by the
191+
* `reason` enumeration.
192+
*/
193+
com.hedera.hapi.block.stream.output.StateChanges state_changes = 7;
194+
195+
/**
196+
* Verification data for items filtered from the stream.<br/>
197+
* This is a hash for a merkle tree node where the contents of that
198+
* part of the merkle tree have been removed from this stream.
199+
* <p>
200+
* Items of this type SHALL NOT be present in the full (unfiltered)
201+
* block stream.<br/>
202+
* Items of this type SHALL replace any item removed from a partial
203+
* (filtered) block stream.<br/>
204+
* Presence of `filtered_item_hash` entries SHALL NOT prevent
205+
* verification of a block, but MAY preclude verification or
206+
* reconstruction of consensus state.<br/>
207+
*/
208+
FilteredItemHash filtered_item_hash = 8;
209+
210+
/**
211+
* A signed block proof.<br/>
212+
* The signed merkle proof for this block. This will validate
213+
* a "virtual" merkle tree containing the previous block "virtual"
214+
* root, an "input" subtree, an "output" subtree, and
215+
* a "state changes" subtree.
216+
* <p>
217+
* This item is not part of the block stream hash chain/tree, and
218+
* MUST follow after the end of a block.
219+
*/
220+
BlockProof block_proof = 9;
221+
222+
/**
223+
* A record file and associated data.
224+
* <p>
225+
* This MUST contain a single Record file, associated Sidecar files,
226+
* and data from related Signature files.
227+
* If this item is present, special treatment is
228+
* REQUIRED for this block.
229+
* <ul>
230+
* <li>The block SHALL NOT have a `BlockHeader`.</li>
231+
* <li>The block SHALL NOT have a `BlockProof`.</li>
232+
* <li>The block SHALL contain _exactly one_ `RecordFileItem`.</li>
233+
* <li>The block SHALL NOT contain any item other than a
234+
* `RecordFileItem`.</li>
235+
* <li>The content of the `RecordFileItem` MUST be validated using
236+
* the signature data and content provided within according to
237+
* the process used for Record Files prior to the creation
238+
* of Block Stream.</li>
239+
* </ul>
240+
*/
241+
RecordFileItem record_file = 10;
242+
243+
/**
244+
* Trace data.
245+
*/
246+
TraceData trace_data = 11;
247+
}
248+
}
249+
250+
/**
251+
* Verification data for items filtered from the stream.
252+
*
253+
* Items of this type SHALL NOT be present in the full (unfiltered) block
254+
* stream.<br/>
255+
* Items of this type SHALL replace any item removed from a partial (filtered)
256+
* block stream.<br/>
257+
* Presence of `FilteredItemHash` entries SHALL NOT prevent verification
258+
* of a block, but MAY preclude verification or reconstruction
259+
* of consensus state.<br/>
260+
*/
261+
message FilteredItemHash {
262+
/**
263+
* A hash of items filtered from the stream.
264+
* <p>
265+
* The hash algorithm used MUST match the hash algorithm specified in
266+
* the block header for the containing block.<br/>
267+
* This field is REQUIRED.
268+
*/
269+
bytes hash = 1;
270+
271+
/**
272+
* A binary tree path to a merkle subtree.
273+
* This path begins at the root of the block proof merkle tree and ends
274+
* at the merkle subtree whose leaf nodes have all been filtered.<br/>
275+
* To walk a path `01001` from the root, go left, right, left, left,
276+
* then right.
277+
* <p>
278+
* This REQUIRED field SHALL describe the full path in the virtual
279+
* merkle tree constructed for the block proof that contained the
280+
* item filtered from the stream.
281+
*/
282+
uint64 filtered_path = 2;
283+
284+
/**
285+
* The log2 value of the number of filtered items.<br/>
286+
* Since the filtered merkle subtree is a balanced binary tree, the log2
287+
* value of the filtered item count is a whole number.
288+
* <p>
289+
* The value 2^x where x is this field SHALL be the number of items filtered
290+
* in the merkle subtree indicated by the `filtered_path`.
291+
*/
292+
uint64 log2_item_count = 3;
293+
}
294+
295+
message TraceData {
296+
/**
297+
* The EVM trace data.
298+
*/
299+
EVMTraceData evm_trace_data = 1;
300+
}

0 commit comments

Comments
 (0)