|
| 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