Search in sources :

Example 1 with StoreTransaction

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);
}
Also used : Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) StateAndBlockSummary(tech.pegasys.teku.spec.datastructures.blocks.StateAndBlockSummary) AttestationGenerator(tech.pegasys.teku.core.AttestationGenerator) StoreTransaction(tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) SignedBeaconBlock(tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock) Bytes32(org.apache.tuweni.bytes.Bytes32) Attestation(tech.pegasys.teku.spec.datastructures.operations.Attestation) BlockImportResult(tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) Test(org.junit.jupiter.api.Test)

Example 2 with StoreTransaction

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());
    }
}
Also used : ChainBuilder(tech.pegasys.teku.core.ChainBuilder) Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) StoreTransaction(tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction) ArrayList(java.util.ArrayList) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) SignedBlockAndState(tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState) Bytes32(org.apache.tuweni.bytes.Bytes32)

Example 3 with StoreTransaction

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();
}
Also used : StoreTransaction(tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction)

Example 4 with StoreTransaction

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);
}
Also used : Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) StoreTransaction(tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction) UInt64(tech.pegasys.teku.infrastructure.unsigned.UInt64) SignedBlockAndState(tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState) Test(org.junit.jupiter.api.Test)

Example 5 with StoreTransaction

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());
}
Also used : Checkpoint(tech.pegasys.teku.spec.datastructures.state.Checkpoint) StoreTransaction(tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction) StubStorageUpdateChannel(tech.pegasys.teku.storage.api.StubStorageUpdateChannel) CheckpointState(tech.pegasys.teku.spec.datastructures.state.CheckpointState) SignedBlockAndState(tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState) Test(org.junit.jupiter.api.Test)

Aggregations

StoreTransaction (tech.pegasys.teku.storage.store.UpdatableStore.StoreTransaction)60 Test (org.junit.jupiter.api.Test)38 Checkpoint (tech.pegasys.teku.spec.datastructures.state.Checkpoint)34 SignedBlockAndState (tech.pegasys.teku.spec.datastructures.blocks.SignedBlockAndState)33 UInt64 (tech.pegasys.teku.infrastructure.unsigned.UInt64)20 Bytes32 (org.apache.tuweni.bytes.Bytes32)9 UpdatableStore (tech.pegasys.teku.storage.store.UpdatableStore)8 SlotAndExecutionPayload (tech.pegasys.teku.spec.datastructures.execution.SlotAndExecutionPayload)7 CheckpointState (tech.pegasys.teku.spec.datastructures.state.CheckpointState)6 StubStorageUpdateChannel (tech.pegasys.teku.storage.api.StubStorageUpdateChannel)6 ChainBuilder (tech.pegasys.teku.core.ChainBuilder)5 SignedBeaconBlock (tech.pegasys.teku.spec.datastructures.blocks.SignedBeaconBlock)5 ArrayList (java.util.ArrayList)4 BlockImportResult (tech.pegasys.teku.spec.logic.common.statetransition.results.BlockImportResult)4 Optional (java.util.Optional)2 BlockOptions (tech.pegasys.teku.core.ChainBuilder.BlockOptions)2 FatalServiceFailureException (tech.pegasys.teku.infrastructure.exceptions.FatalServiceFailureException)2 BeaconState (tech.pegasys.teku.spec.datastructures.state.beaconstate.BeaconState)2 PayloadStatus (tech.pegasys.teku.spec.executionengine.PayloadStatus)2 AbstractStorageBackedDatabaseTest (tech.pegasys.teku.storage.server.AbstractStorageBackedDatabaseTest)2