|
1 | 1 | // SPDX-License-Identifier: Apache-2.0
|
2 | 2 | package org.hiero.block.node.app.fixtures.blocks;
|
3 | 3 |
|
| 4 | +import com.hedera.hapi.block.stream.Block; |
4 | 5 | import com.hedera.hapi.block.stream.BlockItem;
|
5 | 6 | import com.hedera.hapi.block.stream.BlockItem.ItemOneOfType;
|
6 | 7 | import com.hedera.hapi.block.stream.BlockProof;
|
| 8 | +import com.hedera.hapi.block.stream.input.EventHeader; |
7 | 9 | import com.hedera.hapi.block.stream.input.RoundHeader;
|
8 | 10 | import com.hedera.hapi.block.stream.output.BlockHeader;
|
9 | 11 | import com.hedera.hapi.node.base.BlockHashAlgorithm;
|
10 | 12 | import com.hedera.hapi.node.base.SemanticVersion;
|
11 | 13 | import com.hedera.hapi.node.base.Timestamp;
|
| 14 | +import com.hedera.hapi.platform.event.EventCore; |
12 | 15 | import com.hedera.pbj.runtime.OneOf;
|
13 | 16 | import com.hedera.pbj.runtime.io.buffer.Bytes;
|
| 17 | +import java.time.Duration; |
| 18 | +import java.time.Instant; |
14 | 19 | import java.util.ArrayList;
|
| 20 | +import java.util.Arrays; |
15 | 21 | import java.util.Collections;
|
16 | 22 | import java.util.List;
|
| 23 | +import java.util.Random; |
| 24 | +import java.util.stream.LongStream; |
17 | 25 | import org.hiero.block.internal.BlockItemUnparsed;
|
18 | 26 | import org.hiero.block.node.spi.blockmessaging.BlockItems;
|
| 27 | +import org.hiero.block.node.spi.historicalblocks.BlockAccessor; |
19 | 28 |
|
20 | 29 | /**
|
21 | 30 | * A utility class to create sample BlockItem objects for testing purposes.
|
22 | 31 | */
|
23 | 32 | public final class SimpleTestBlockItemBuilder {
|
| 33 | + private static final Bytes RANDOM_HALF_MB; |
| 34 | + |
| 35 | + static { |
| 36 | + final Random random = new Random(1435134141854542L); |
| 37 | + final byte[] randomBytes = new byte[512 * 1024]; |
| 38 | + random.nextBytes(randomBytes); |
| 39 | + RANDOM_HALF_MB = Bytes.wrap(randomBytes); |
| 40 | + } |
| 41 | + |
24 | 42 | public static BlockHeader createBlockHeader(final long blockNumber) {
|
25 | 43 | return new BlockHeader(
|
26 | 44 | new SemanticVersion(1, 2, 3, "a", "b"),
|
@@ -65,10 +83,43 @@ public static BlockItemUnparsed sampleBlockHeaderUnparsed(final long blockNumber
|
65 | 83 | .build();
|
66 | 84 | }
|
67 | 85 |
|
| 86 | + /** |
| 87 | + * Creates a sample BlockItem representing a block header with the given block number and consensus time. |
| 88 | + */ |
| 89 | + public static BlockItem sampleBlockHeader(final long blockNumber, Instant consensusTime) { |
| 90 | + return new BlockItem(new OneOf<>( |
| 91 | + ItemOneOfType.BLOCK_HEADER, |
| 92 | + new BlockHeader( |
| 93 | + new SemanticVersion(1, 2, 3, "a", "b"), |
| 94 | + new SemanticVersion(4, 5, 6, "c", "d"), |
| 95 | + blockNumber, |
| 96 | + new Timestamp(consensusTime.getEpochSecond(), consensusTime.getNano()), |
| 97 | + BlockHashAlgorithm.SHA2_384))); |
| 98 | + } |
| 99 | + |
| 100 | + /** |
| 101 | + * Creates a sample BlockItemUnparsed representing a block header with the given block number and consensus time. |
| 102 | + */ |
| 103 | + public static BlockItemUnparsed sampleBlockHeaderUnparsed(final long blockNumber, Instant consensusTime) { |
| 104 | + //noinspection DataFlowIssue |
| 105 | + return BlockItemUnparsed.newBuilder() |
| 106 | + .blockHeader(BlockHeader.PROTOBUF.toBytes( |
| 107 | + sampleBlockHeader(blockNumber, consensusTime).blockHeader())) |
| 108 | + .build(); |
| 109 | + } |
| 110 | + |
68 | 111 | public static BlockItem sampleRoundHeader(final long roundNumber) {
|
69 | 112 | return new BlockItem(new OneOf<>(ItemOneOfType.ROUND_HEADER, createRoundHeader(roundNumber)));
|
70 | 113 | }
|
71 | 114 |
|
| 115 | + /** |
| 116 | + * Create an EventHeader with a large 0.5MB signature data. |
| 117 | + */ |
| 118 | + public static BlockItem sampleLargeEventHeader() { |
| 119 | + return new BlockItem( |
| 120 | + new OneOf<>(ItemOneOfType.EVENT_HEADER, new EventHeader(EventCore.DEFAULT, RANDOM_HALF_MB))); |
| 121 | + } |
| 122 | + |
72 | 123 | public static BlockItemUnparsed sampleRoundHeaderUnparsed(final long roundNumber) {
|
73 | 124 | return BlockItemUnparsed.newBuilder()
|
74 | 125 | .roundHeader(createRoundHeaderUnparsed(roundNumber))
|
@@ -97,26 +148,113 @@ public static BlockItem[] createNumberOfVerySimpleBlocks(final int numberOfBlock
|
97 | 148 |
|
98 | 149 | /**
|
99 | 150 | * Creates an array of BlockItem objects representing a very simple block stream of blocks from startBlockNumber to
|
100 |
| - * but not including endBlockNumber. |
| 151 | + * endBlockNumber inclusive. |
101 | 152 | *
|
102 | 153 | * @param startBlockNumber the starting block number
|
103 | 154 | * @param endBlockNumber the ending block number, inclusive
|
104 | 155 | * @return an array of BlockItem objects
|
105 | 156 | */
|
106 |
| - public static BlockItem[] createNumberOfVerySimpleBlocks(final int startBlockNumber, final int endBlockNumber) { |
| 157 | + public static BlockItem[] createNumberOfVerySimpleBlocks(final long startBlockNumber, final long endBlockNumber) { |
107 | 158 | assert startBlockNumber <= endBlockNumber;
|
108 | 159 | assert startBlockNumber >= 0;
|
109 |
| - final int numberOfBlocks = endBlockNumber - startBlockNumber + 1; |
| 160 | + final int numberOfBlocks = (int) (endBlockNumber - startBlockNumber + 1); |
110 | 161 | final BlockItem[] blockItems = new BlockItem[numberOfBlocks * 3];
|
111 |
| - for (int blockNumber = startBlockNumber; blockNumber <= endBlockNumber; blockNumber++) { |
112 |
| - final int i = (blockNumber - startBlockNumber) * 3; |
| 162 | + for (int blockNumber = (int) startBlockNumber; blockNumber <= endBlockNumber; blockNumber++) { |
| 163 | + final int i = (blockNumber - (int) startBlockNumber) * 3; |
113 | 164 | blockItems[i] = sampleBlockHeader(blockNumber);
|
114 | 165 | blockItems[i + 1] = sampleRoundHeader(blockNumber * 10L);
|
115 | 166 | blockItems[i + 2] = sampleBlockProof(blockNumber);
|
116 | 167 | }
|
117 | 168 | return blockItems;
|
118 | 169 | }
|
119 | 170 |
|
| 171 | + /** |
| 172 | + * Creates an array of BlockItem objects representing a simple block stream of blocks with large 2.5MB data each |
| 173 | + * from startBlockNumber to endBlockNumber inclusive. |
| 174 | + * |
| 175 | + * @param startBlockNumber the starting block number |
| 176 | + * @param endBlockNumber the ending block number, inclusive |
| 177 | + * @return an array of BlockItem objects |
| 178 | + */ |
| 179 | + public static BlockItem[] createNumberOfLargeBlocks(final long startBlockNumber, final long endBlockNumber) { |
| 180 | + assert startBlockNumber <= endBlockNumber; |
| 181 | + assert startBlockNumber >= 0; |
| 182 | + final int numberOfBlocks = (int) (endBlockNumber - startBlockNumber + 1); |
| 183 | + final BlockItem[] blockItems = new BlockItem[numberOfBlocks * 8]; |
| 184 | + for (int blockNumber = (int) startBlockNumber; blockNumber <= endBlockNumber; blockNumber++) { |
| 185 | + final int i = (blockNumber - (int) startBlockNumber) * 8; |
| 186 | + blockItems[i] = sampleBlockHeader(blockNumber); |
| 187 | + blockItems[i + 1] = sampleRoundHeader(blockNumber * 10L); |
| 188 | + blockItems[i + 2] = sampleLargeEventHeader(); |
| 189 | + blockItems[i + 3] = sampleLargeEventHeader(); |
| 190 | + blockItems[i + 4] = sampleLargeEventHeader(); |
| 191 | + blockItems[i + 5] = sampleLargeEventHeader(); |
| 192 | + blockItems[i + 6] = sampleLargeEventHeader(); |
| 193 | + blockItems[i + 7] = sampleBlockProof(blockNumber); |
| 194 | + } |
| 195 | + return blockItems; |
| 196 | + } |
| 197 | + |
| 198 | + /** |
| 199 | + * Creates an array of BlockItem objects representing a very simple block stream of blocks from startBlockNumber to |
| 200 | + * but not including endBlockNumber. |
| 201 | + * |
| 202 | + * @param startBlockNumber the starting block number |
| 203 | + * @param endBlockNumber the ending block number, inclusive |
| 204 | + * @param firstBlockConsensusTime the consensus time of the first block |
| 205 | + * @param consensusTimeBetweenBlocks the time between blocks starts with the first block at 2025-01-01T00:00:00Z |
| 206 | + * @return an array of BlockItem objects |
| 207 | + */ |
| 208 | + public static BlockItemUnparsed[] createNumberOfVerySimpleBlocksUnparsed( |
| 209 | + final long startBlockNumber, |
| 210 | + final long endBlockNumber, |
| 211 | + Instant firstBlockConsensusTime, |
| 212 | + Duration consensusTimeBetweenBlocks) { |
| 213 | + assert startBlockNumber <= endBlockNumber; |
| 214 | + assert startBlockNumber >= 0; |
| 215 | + final int numberOfBlocks = (int) (endBlockNumber - startBlockNumber + 1); |
| 216 | + final BlockItemUnparsed[] blockItems = new BlockItemUnparsed[numberOfBlocks * 3]; |
| 217 | + Instant blockTime = firstBlockConsensusTime; |
| 218 | + for (int blockNumber = (int) startBlockNumber; blockNumber <= endBlockNumber; blockNumber++) { |
| 219 | + final int i = (blockNumber - (int) startBlockNumber) * 3; |
| 220 | + blockItems[i] = sampleBlockHeaderUnparsed(blockNumber, blockTime); |
| 221 | + blockItems[i + 1] = sampleRoundHeaderUnparsed(blockNumber * 10L); |
| 222 | + blockItems[i + 2] = sampleBlockProofUnparsed(blockNumber); |
| 223 | + // Increment the block time by the consensus time between blocks |
| 224 | + blockTime = blockTime.plus(consensusTimeBetweenBlocks); |
| 225 | + } |
| 226 | + return blockItems; |
| 227 | + } |
| 228 | + |
| 229 | + /** |
| 230 | + * Creates an array of BlockAccessor objects representing a very simple block stream of blocks from startBlockNumber |
| 231 | + * to but endBlockNumber inclusive. |
| 232 | + * |
| 233 | + * @param startBlockNumber the starting block number |
| 234 | + * @param endBlockNumber the ending block number, inclusive |
| 235 | + * @return an array of BlockAccessor objects |
| 236 | + */ |
| 237 | + public static BlockAccessor[] createNumberOfVerySimpleBlockAccessors( |
| 238 | + final int startBlockNumber, final int endBlockNumber) { |
| 239 | + return LongStream.range(startBlockNumber, endBlockNumber + 1) |
| 240 | + .mapToObj(bn -> { |
| 241 | + BlockItem[] blockItems = createNumberOfVerySimpleBlocks(bn, bn); |
| 242 | + Block block = new Block(Arrays.asList(blockItems)); |
| 243 | + return new BlockAccessor() { |
| 244 | + @Override |
| 245 | + public long blockNumber() { |
| 246 | + return bn; |
| 247 | + } |
| 248 | + |
| 249 | + @Override |
| 250 | + public Block block() { |
| 251 | + return block; |
| 252 | + } |
| 253 | + }; |
| 254 | + }) |
| 255 | + .toArray(BlockAccessor[]::new); |
| 256 | + } |
| 257 | + |
120 | 258 | /**
|
121 | 259 | * Creates an array of BlockItem objects representing a very simple block stream of N blocks.
|
122 | 260 | *
|
|
0 commit comments