use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class RecentChainDataTest method initializeFromGenesis_withTimeLessThanGenesisTime.
@Test
public void initializeFromGenesis_withTimeLessThanGenesisTime() {
initPreGenesis();
final ChainBuilder chainBuilder = ChainBuilder.create(spec);
final UInt64 genesisTime = UInt64.valueOf(5000);
final SignedBlockAndState genesis = chainBuilder.generateGenesis(genesisTime, false);
recentChainData.initializeFromGenesis(genesis.getState(), UInt64.valueOf(100));
assertThat(recentChainData.getStore().getTime()).isEqualTo(genesisTime);
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class StoreTransactionTest method getOrderedBlockRoots_withNewBlocks.
@Test
public void getOrderedBlockRoots_withNewBlocks() {
final UpdatableStore store = createGenesisStore();
final SignedBlockAndState genesis = chainBuilder.getBlockAndStateAtSlot(GENESIS_SLOT);
final ChainBuilder fork = chainBuilder.fork();
final SignedBlockAndState forkBlock2 = fork.generateBlockAtSlot(2);
final SignedBlockAndState mainChainBlock1 = chainBuilder.generateBlockAtSlot(1);
final SignedBlockAndState mainChainBlock3 = chainBuilder.generateBlockAtSlot(3);
final SignedBlockAndState mainChainBlock4 = chainBuilder.generateBlockAtSlot(4);
addBlocks(store, List.of(mainChainBlock1, mainChainBlock3, mainChainBlock4));
final StoreTransaction tx = store.startTransaction(storageUpdateChannel);
// Initially we should get existing block hashes
assertThat(tx.getOrderedBlockRoots()).containsExactly(genesis.getRoot(), mainChainBlock1.getRoot(), mainChainBlock3.getRoot(), mainChainBlock4.getRoot());
// Added block should be included
tx.putBlockAndState(forkBlock2);
// Children are ordered based on hash - so check ordering depending on specific hashes
if (mainChainBlock1.getRoot().compareTo(forkBlock2.getRoot()) < 0) {
assertThat(tx.getOrderedBlockRoots()).containsExactly(genesis.getRoot(), mainChainBlock1.getRoot(), forkBlock2.getRoot(), mainChainBlock3.getRoot(), mainChainBlock4.getRoot());
} else {
assertThat(tx.getOrderedBlockRoots()).containsExactly(genesis.getRoot(), forkBlock2.getRoot(), mainChainBlock1.getRoot(), mainChainBlock3.getRoot(), mainChainBlock4.getRoot());
}
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class AbstractDatabaseTest method createForkChain.
protected CreateForkChainResult createForkChain(final boolean restartStorage) {
// Setup chains
// Both chains share block up to slot 3
final ChainBuilder primaryChain = ChainBuilder.create(spec, VALIDATOR_KEYS);
primaryChain.generateGenesis(genesisTime, true);
primaryChain.generateBlocksUpToSlot(3);
final ChainBuilder forkChain = primaryChain.fork();
// Primary chain's next block is at 7
final SignedBlockAndState finalizedBlock = primaryChain.generateBlockAtSlot(7);
final Checkpoint finalizedCheckpoint = getCheckpointForBlock(primaryChain.getBlockAtSlot(7));
final UInt64 firstHotBlockSlot = finalizedCheckpoint.getEpochStartSlot(spec).plus(UInt64.ONE);
primaryChain.generateBlockAtSlot(firstHotBlockSlot);
// Fork chain's next block is at 6
forkChain.generateBlockAtSlot(6);
forkChain.generateBlockAtSlot(firstHotBlockSlot);
// Setup database
initGenesis();
final Set<SignedBlockAndState> allBlocksAndStates = Streams.concat(primaryChain.streamBlocksAndStates(), forkChain.streamBlocksAndStates()).collect(Collectors.toSet());
// Finalize at block 7, making the fork blocks unavailable
add(allBlocksAndStates);
justifyAndFinalizeEpoch(finalizedCheckpoint.getEpoch(), finalizedBlock);
if (restartStorage) {
// Close database and rebuild from disk
restartStorage();
}
return new CreateForkChainResult(forkChain, firstHotBlockSlot);
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class ChainStorageTest method onFinalizedBlocks_nonMatchingBlocks.
@ParameterizedTest(name = "{0}")
@ArgumentsSource(StorageSystemArgumentsProvider.class)
public void onFinalizedBlocks_nonMatchingBlocks(final String storageType, final StorageSystemArgumentsProvider.StorageSystemSupplier storageSystemSupplier) {
setup(storageSystemSupplier);
final int epochs = 3;
final int chainSize = spec.slotsPerEpoch(ZERO) * epochs;
// Create fork
final ChainBuilder forkBuilder = chainBuilder.fork();
// Skip a block to create a divergent chain
forkBuilder.generateBlockAtSlot(2);
forkBuilder.generateBlocksUpToSlot(chainSize);
// Build small chain
chainBuilder.generateBlocksUpToSlot(chainSize);
// Retrieve anchor data
final Checkpoint anchorCheckpoint = chainBuilder.getCurrentCheckpointForEpoch(epochs);
final SignedBlockAndState anchorBlockAndState = chainBuilder.getBlockAndState(anchorCheckpoint.getRoot()).orElseThrow();
// Initialize from intermediate anchor
final AnchorPoint anchorPoint = AnchorPoint.create(spec, anchorCheckpoint, anchorBlockAndState.getState(), Optional.empty());
storageSystem.recentChainData().initializeFromAnchorPoint(anchorPoint, ZERO);
final long firstMissingBlockSlot = anchorBlockAndState.getSlot().longValue();
// Try to save non-matching fork blocks
final List<SignedBeaconBlock> invalidBlocks = forkBuilder.streamBlocksAndStates(0, firstMissingBlockSlot).map(SignedBlockAndState::getBlock).collect(Collectors.toList());
final SafeFuture<Void> result = chainStorage.onFinalizedBlocks(invalidBlocks);
assertThat(result).isCompletedExceptionally();
assertThatThrownBy(result::get).hasCauseInstanceOf(IllegalArgumentException.class).hasMessageContaining("Blocks must be contiguous with the earliest known block");
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class AbstractDatabaseTest method shouldPruneHotBlocksAddedOverMultipleSessions.
@Test
public void shouldPruneHotBlocksAddedOverMultipleSessions() throws Exception {
final UInt64 targetSlot = UInt64.valueOf(10);
chainBuilder.generateBlocksUpToSlot(targetSlot.minus(UInt64.ONE));
final ChainBuilder forkA = chainBuilder.fork();
final ChainBuilder forkB = chainBuilder.fork();
// Add base blocks
addBlocks(chainBuilder.streamBlocksAndStates().collect(toList()));
// Set target slot at which to create duplicate blocks
// and generate block options to make each block unique
final List<BlockOptions> blockOptions = chainBuilder.streamValidAttestationsForBlockAtSlot(targetSlot).map(attestation -> BlockOptions.create().addAttestation(attestation)).limit(2).collect(toList());
// Create several different blocks at the same slot
final SignedBlockAndState blockA = forkA.generateBlockAtSlot(targetSlot, blockOptions.get(0));
final SignedBlockAndState blockB = forkB.generateBlockAtSlot(targetSlot, blockOptions.get(1));
final SignedBlockAndState blockC = chainBuilder.generateBlockAtSlot(10);
final Set<Bytes32> block10Roots = Set.of(blockA.getRoot(), blockB.getRoot(), blockC.getRoot());
// Sanity check
assertThat(block10Roots.size()).isEqualTo(3);
// Add blocks at same height sequentially
add(List.of(blockA));
add(List.of(blockB));
add(List.of(blockC));
// Verify all blocks are available
assertThat(store.retrieveBlock(blockA.getRoot())).isCompletedWithValue(Optional.of(blockA.getBlock().getMessage()));
assertThat(store.retrieveBlock(blockB.getRoot())).isCompletedWithValue(Optional.of(blockB.getBlock().getMessage()));
assertThat(store.retrieveBlock(blockC.getRoot())).isCompletedWithValue(Optional.of(blockC.getBlock().getMessage()));
// Finalize subsequent block to prune blocks a, b, and c
final SignedBlockAndState finalBlock = chainBuilder.generateNextBlock();
add(List.of(finalBlock));
final UInt64 finalEpoch = chainBuilder.getLatestEpoch().plus(ONE);
final SignedBlockAndState finalizedBlock = chainBuilder.getLatestBlockAndStateAtEpochBoundary(finalEpoch);
justifyAndFinalizeEpoch(finalEpoch, finalizedBlock);
// Check pruning result
final Set<Bytes32> rootsToPrune = new HashSet<>(block10Roots);
rootsToPrune.add(genesisBlockAndState.getRoot());
// Check that all blocks at slot 10 were pruned
assertRecentDataWasPruned(store, rootsToPrune, Set.of(genesisCheckpoint));
}
Aggregations