use of tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction in project teku by ConsenSys.
the class BlockImporterTest method importBlock_wrongChain.
@Test
public void importBlock_wrongChain() throws Exception {
UInt64 currentSlot = recentChainData.getHeadSlot();
for (int i = 0; i < 3; i++) {
currentSlot = currentSlot.plus(UInt64.ONE);
localChain.createAndImportBlockAtSlot(currentSlot);
}
// Update finalized epoch
final StoreTransaction tx = recentChainData.startStoreTransaction();
final Bytes32 finalizedRoot = recentChainData.getBestBlockRoot().orElseThrow();
final UInt64 finalizedEpoch = UInt64.ONE;
final Checkpoint finalized = new Checkpoint(finalizedEpoch, finalizedRoot);
tx.setFinalizedCheckpoint(finalized);
tx.commit().join();
// Now create a new block that is not descendant from the finalized block
AttestationGenerator attestationGenerator = new AttestationGenerator(spec, validatorKeys);
final StateAndBlockSummary blockAndState = safeJoin(otherStorage.getChainHead().orElseThrow().asStateAndBlockSummary());
final Attestation attestation = attestationGenerator.validAttestation(blockAndState);
final SignedBeaconBlock block = otherChain.createAndImportBlockAtSlotWithAttestations(currentSlot, List.of(attestation));
final BlockImportResult result = blockImporter.importBlock(block).get();
assertImportFailed(result, FailureReason.UNKNOWN_PARENT);
}
use of tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction in project teku by ConsenSys.
the class RecentChainDataTest method testCommitPruningOfParallelBlocks.
/**
* Builds 2 parallel chains, one of which will get pruned when a block in the middle of the other
* chain is finalized. Keep one chain in the finalizing transaction, the other chain is already
* saved to the store.
*
* @param pruneNewBlocks Whether to keep the blocks to be pruned in the finalizing transaction, or
* keep the blocks to be kept in the finalizing transaction @
*/
private void testCommitPruningOfParallelBlocks(final boolean pruneNewBlocks) {
final UInt64 epoch2Slot = spec.computeStartSlotAtEpoch(UInt64.valueOf(2));
// Create a fork by skipping the next slot on the fork chain
ChainBuilder fork = chainBuilder.fork();
// Generate the next 2 blocks on the primary chain
final SignedBlockAndState firstCanonicalBlock = chainBuilder.generateNextBlock();
saveBlock(recentChainData, firstCanonicalBlock);
saveBlock(recentChainData, chainBuilder.generateNextBlock());
// Skip a block and then generate the next block on the fork chain
final SignedBlockAndState firstForkBlock = fork.generateNextBlock(1);
saveBlock(recentChainData, firstForkBlock);
// Build both the primary and fork chain past epoch1
// Make sure both chains are at the same slot
assertThat(chainBuilder.getLatestSlot()).isEqualTo(fork.getLatestSlot());
while (chainBuilder.getLatestSlot().compareTo(epoch2Slot) < 0) {
chainBuilder.generateNextBlock();
fork.generateNextBlock();
}
// Save one chain to the store, setup the other chain to be saved in the finalizing transaction
final List<SignedBlockAndState> newBlocks = new ArrayList<>();
if (pruneNewBlocks) {
// Save canonical blocks now, put fork blocks in the transaction
chainBuilder.streamBlocksAndStates(firstCanonicalBlock.getSlot()).forEach(b -> saveBlock(recentChainData, b));
fork.streamBlocksAndStates(firstForkBlock.getSlot()).forEach(newBlocks::add);
} else {
// Save fork blocks now, put canonical blocks in the transaction
chainBuilder.streamBlocksAndStates(firstCanonicalBlock.getSlot()).forEach(newBlocks::add);
fork.streamBlocksAndStates(firstForkBlock.getSlot()).forEach(b -> saveBlock(recentChainData, b));
}
// Add blocks and finalize epoch 1, so that blocks will be pruned
final StoreTransaction tx = recentChainData.startStoreTransaction();
final Checkpoint finalizedCheckpoint = chainBuilder.getCurrentCheckpointForEpoch(1);
tx.setFinalizedCheckpoint(finalizedCheckpoint);
newBlocks.forEach(tx::putBlockAndState);
tx.commit().reportExceptions();
// Check that only recent, canonical blocks at or after the latest finalized block are left in
// the store
final List<SignedBlockAndState> expectedBlocks = chainBuilder.streamBlocksAndStates(finalizedCheckpoint.getEpochStartSlot(spec)).collect(Collectors.toList());
final Set<Bytes32> blockRoots = expectedBlocks.stream().map(SignedBlockAndState::getRoot).collect(Collectors.toSet());
// Collect blocks that should be pruned
final Set<Bytes32> prunedBlocks = fork.streamBlocksAndStates(firstForkBlock.getSlot()).map(SignedBlockAndState::getRoot).collect(Collectors.toSet());
// Check expected blocks
assertThat(recentChainData.getStore().getOrderedBlockRoots()).containsExactlyInAnyOrderElementsOf(blockRoots);
for (SignedBlockAndState expectedBlock : expectedBlocks) {
assertThat(recentChainData.retrieveSignedBlockByRoot(expectedBlock.getRoot())).isCompletedWithValue(Optional.of(expectedBlock.getBlock()));
assertThat(recentChainData.retrieveBlockState(expectedBlock.getRoot())).isCompletedWithValue(Optional.of(expectedBlock.getState()));
}
// Check pruned blocks
for (Bytes32 prunedBlock : prunedBlocks) {
assertThatSafeFuture(recentChainData.retrieveSignedBlockByRoot(prunedBlock)).isCompletedWithEmptyOptional();
assertThat(recentChainData.retrieveBlockState(prunedBlock)).isCompletedWithValue(Optional.empty());
}
}
use of tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction in project teku by ConsenSys.
the class RecentChainDataTest method importBlocksAndStates.
private void importBlocksAndStates(final RecentChainData client, final ChainBuilder... chainBuilders) {
final StoreTransaction transaction = client.startStoreTransaction();
Stream.of(chainBuilders).flatMap(ChainBuilder::streamBlocksAndStates).forEach(transaction::putBlockAndState);
transaction.commit().join();
}
use of tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction in project teku by ConsenSys.
the class RecentChainDataTest method getLatestFinalizedBlockSlot_postGenesisFinalizedBlockOutsideOfEpochBoundary.
@Test
public void getLatestFinalizedBlockSlot_postGenesisFinalizedBlockOutsideOfEpochBoundary() {
initPostGenesis();
final UInt64 epoch = ONE;
final UInt64 epochBoundarySlot = spec.computeStartSlotAtEpoch(epoch);
final UInt64 finalizedBlockSlot = epochBoundarySlot.minus(ONE);
final SignedBlockAndState finalizedBlock = chainBuilder.generateBlockAtSlot(finalizedBlockSlot);
saveBlock(recentChainData, finalizedBlock);
// Start tx to update finalized checkpoint
final StoreTransaction tx = recentChainData.startStoreTransaction();
// Initially finalized slot should match store
assertThat(tx.getLatestFinalizedBlockSlot()).isEqualTo(genesis.getSlot());
// Update checkpoint and check finalized slot accessors
tx.setFinalizedCheckpoint(new Checkpoint(epoch, finalizedBlock.getRoot()));
assertThat(tx.getLatestFinalizedBlockSlot()).isEqualTo(finalizedBlockSlot);
assertThat(recentChainData.getStore().getLatestFinalizedBlockSlot()).isEqualTo(genesis.getSlot());
// Commit tx
tx.commit().reportExceptions();
assertThat(recentChainData.getStore().getLatestFinalizedBlockSlot()).isEqualTo(finalizedBlockSlot);
}
use of tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction in project teku by ConsenSys.
the class StoreTransactionTest method retrieveFinalizedCheckpointAndState_finalizedCheckpointPruned.
@Test
public void retrieveFinalizedCheckpointAndState_finalizedCheckpointPruned() {
final UpdatableStore store = createGenesisStore();
final SignedBlockAndState finalizedBlockAndState = chainBuilder.generateBlockAtSlot(spec.slotsPerEpoch(ZERO) - 1);
final Checkpoint finalizedCheckpoint = new Checkpoint(UInt64.ONE, finalizedBlockAndState.getRoot());
final SignedBlockAndState newerFinalizedBlockAndState = chainBuilder.generateBlockAtSlot(spec.slotsPerEpoch(ZERO) * 2);
final Checkpoint newerFinalizedCheckpoint = new Checkpoint(UInt64.valueOf(2), newerFinalizedBlockAndState.getRoot());
// Save blocks
final StoreTransaction blockTx = store.startTransaction(new StubStorageUpdateChannel());
blockTx.putBlockAndState(finalizedBlockAndState);
blockTx.putBlockAndState(newerFinalizedBlockAndState);
assertThat(blockTx.commit()).isCompleted();
// Start tx finalizing epoch 1
final StoreTransaction tx = store.startTransaction(new StubStorageUpdateChannel());
tx.setFinalizedCheckpoint(finalizedCheckpoint);
// Finalize epoch 2
final StoreTransaction otherTx = store.startTransaction(new StubStorageUpdateChannel());
otherTx.putBlockAndState(newerFinalizedBlockAndState);
otherTx.setFinalizedCheckpoint(newerFinalizedCheckpoint);
assertThat(otherTx.commit()).isCompleted();
// Check response from tx1 for finalized value
final SafeFuture<CheckpointState> result = tx.retrieveFinalizedCheckpointAndState();
assertThat(result).isCompleted();
assertThat(result.join().getCheckpoint()).isEqualTo(newerFinalizedCheckpoint);
assertThat(result.join().getRoot()).isEqualTo(newerFinalizedBlockAndState.getRoot());
assertThat(result.join().getState()).isEqualTo(newerFinalizedBlockAndState.getState());
}
Aggregations