use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class ChainDataProviderTest method getBlockAttestations_shouldReturnAttestationsOfBlock.
@Test
public void getBlockAttestations_shouldReturnAttestationsOfBlock() throws Exception {
final ChainDataProvider provider = new ChainDataProvider(spec, recentChainData, combinedChainDataClient);
ChainBuilder chainBuilder = storageSystem.chainBuilder();
ChainBuilder.BlockOptions blockOptions = ChainBuilder.BlockOptions.create();
AttestationGenerator attestationGenerator = new AttestationGenerator(spec, chainBuilder.getValidatorKeys());
tech.pegasys.teku.spec.datastructures.operations.Attestation attestation1 = attestationGenerator.validAttestation(bestBlock.toUnsigned(), bestBlock.getSlot());
tech.pegasys.teku.spec.datastructures.operations.Attestation attestation2 = attestationGenerator.validAttestation(bestBlock.toUnsigned(), bestBlock.getSlot().increment());
blockOptions.addAttestation(attestation1);
blockOptions.addAttestation(attestation2);
SignedBlockAndState newHead = storageSystem.chainBuilder().generateBlockAtSlot(bestBlock.getSlot().plus(10), blockOptions);
storageSystem.chainUpdater().saveBlock(newHead);
storageSystem.chainUpdater().updateBestBlock(newHead);
final Optional<ObjectAndMetaData<List<Attestation>>> response = provider.getBlockAttestations("head").get();
assertThat(response).isPresent();
assertThat(response.get().getData()).containsExactly(new Attestation(attestation1), new Attestation(attestation2));
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class AbstractBlockMetadataStoreTest method findCommonAncestor_differingChains.
@Test
void findCommonAncestor_differingChains() {
chainBuilder.generateBlockAtSlot(2);
final ChainBuilder fork = chainBuilder.fork();
chainBuilder.generateBlocksUpToSlot(4);
final SignedBlockAndState chainHead = chainBuilder.generateBlockAtSlot(5);
// Fork skips slot 3 so the chains are different
fork.generateBlockAtSlot(4);
fork.generateBlocksUpToSlot(6);
final SignedBlockAndState forkHead = fork.generateBlockAtSlot(7);
final SignedBeaconBlock commonBlock = chainBuilder.getBlockAtSlot(UInt64.valueOf(2));
assertCommonAncestorFound(chainHead.getRoot(), forkHead.getRoot(), new SlotAndBlockRoot(commonBlock.getSlot(), commonBlock.getRoot()), fork);
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class AbstractBlockMetadataStoreTest method processAllInOrder_shouldVisitParentBlocksBeforeChildBlocksInForks.
@Test
void processAllInOrder_shouldVisitParentBlocksBeforeChildBlocksInForks() {
// First chain has all blocks up to 10
// Fork chain has 0-5, skips 6 and then has 7-10
chainBuilder.generateBlocksUpToSlot(5);
final ChainBuilder forkBuilder = chainBuilder.fork();
chainBuilder.generateBlocksUpToSlot(10);
forkBuilder.generateBlockAtSlot(7);
forkBuilder.generateBlocksUpToSlot(10);
final BlockMetadataStore store = createBlockMetadataStore(chainBuilder);
store.applyUpdate(forkBuilder.streamBlocksAndStates().map(BlockAndCheckpointEpochs::fromBlockAndState).collect(toList()), Collections.emptySet(), genesisCheckpoint);
final Set<Bytes32> seenBlocks = new HashSet<>();
store.processAllInOrder((childRoot, slot, parentRoot) -> {
assertThat(seenBlocks).doesNotContain(childRoot);
if (!seenBlocks.isEmpty()) {
// First block won't have visited the parent
assertThat(seenBlocks).contains(parentRoot);
}
seenBlocks.add(childRoot);
final SignedBeaconBlock block = chainBuilder.getBlock(childRoot).or(() -> forkBuilder.getBlock(childRoot)).orElseThrow();
assertThat(childRoot).isEqualTo(block.getRoot());
assertThat(slot).isEqualTo(block.getSlot());
assertThat(parentRoot).isEqualTo(block.getParentRoot());
});
// Check every block was seen
final Set<Bytes32> expectedSeenRoots = Stream.concat(chainBuilder.streamBlocksAndStates(), forkBuilder.streamBlocksAndStates()).map(StateAndBlockSummary::getRoot).collect(toSet());
assertThat(seenBlocks).containsExactlyInAnyOrderElementsOf(expectedSeenRoots);
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class ForkChoiceTest method onBlock_shouldUpdateVotesBasedOnAttestationsInBlocks.
@Test
void onBlock_shouldUpdateVotesBasedOnAttestationsInBlocks() {
final ChainBuilder forkChain = chainBuilder.fork();
final SignedBlockAndState forkBlock1 = forkChain.generateBlockAtSlot(ONE, BlockOptions.create().setEth1Data(new Eth1Data(Bytes32.ZERO, UInt64.valueOf(6), Bytes32.ZERO)));
final SignedBlockAndState betterBlock1 = chainBuilder.generateBlockAtSlot(1);
importBlock(forkBlock1);
// Should automatically follow the fork as its the first child block
assertThat(recentChainData.getBestBlockRoot()).contains(forkBlock1.getRoot());
// Add an attestation for the fork so that it initially has higher weight
// Otherwise ties are split based on the hash which is too hard to control in the test
final BlockOptions forkBlockOptions = BlockOptions.create();
forkChain.streamValidAttestationsWithTargetBlock(forkBlock1).limit(1).forEach(forkBlockOptions::addAttestation);
final SignedBlockAndState forkBlock2 = forkChain.generateBlockAtSlot(forkBlock1.getSlot().plus(1), forkBlockOptions);
importBlock(forkBlock2);
// The fork is still the only option so gets selected
assertThat(recentChainData.getBestBlockRoot()).contains(forkBlock2.getRoot());
// Now import what will become the canonical chain
importBlock(betterBlock1);
// Process head to ensure we clear any additional proposer weighting for this first block.
// Should still pick forkBlock as it's the best option even though we have a competing chain
processHead(ONE);
assertThat(recentChainData.getBestBlockRoot()).contains(forkBlock2.getRoot());
// Import a block with two attestations which makes this chain better than the fork
final BlockOptions options = BlockOptions.create();
chainBuilder.streamValidAttestationsWithTargetBlock(betterBlock1).limit(2).forEach(options::addAttestation);
final SignedBlockAndState blockWithAttestations = chainBuilder.generateBlockAtSlot(UInt64.valueOf(2), options);
importBlock(blockWithAttestations);
// Haven't run fork choice so won't have re-orged yet - fork still has more applied votes
assertThat(recentChainData.getBestBlockRoot()).contains(forkBlock2.getRoot());
// When attestations are applied we should switch away from the fork to our better chain
processHead(blockWithAttestations.getSlot());
assertThat(recentChainData.getBestBlockRoot()).contains(blockWithAttestations.getRoot());
}
use of tech.pegasys.teku.core.ChainBuilder in project teku by ConsenSys.
the class BlockValidatorTest method shouldReturnInvalidForBlockThatDoesNotDescendFromFinalizedCheckpoint.
@TestTemplate
void shouldReturnInvalidForBlockThatDoesNotDescendFromFinalizedCheckpoint() {
List<BLSKeyPair> VALIDATOR_KEYS = BLSKeyGenerator.generateKeyPairs(4);
StorageSystem storageSystem = InMemoryStorageSystemBuilder.buildDefault();
ChainBuilder chainBuilder = ChainBuilder.create(VALIDATOR_KEYS);
ChainUpdater chainUpdater = new ChainUpdater(storageSystem.recentChainData(), chainBuilder);
BlockValidator blockValidator = new BlockValidator(spec, storageSystem.recentChainData());
chainUpdater.initializeGenesis();
chainUpdater.updateBestBlock(chainUpdater.advanceChainUntil(1));
ChainBuilder chainBuilderFork = chainBuilder.fork();
ChainUpdater chainUpdaterFork = new ChainUpdater(storageSystem.recentChainData(), chainBuilderFork);
UInt64 startSlotOfFinalizedEpoch = spec.computeStartSlotAtEpoch(UInt64.valueOf(4));
chainUpdaterFork.advanceChain(20);
chainUpdater.finalizeEpoch(4);
SignedBlockAndState blockAndState = chainBuilderFork.generateBlockAtSlot(startSlotOfFinalizedEpoch.increment());
chainUpdater.saveBlockTime(blockAndState);
final SafeFuture<InternalValidationResult> result = blockValidator.validate(blockAndState.getBlock());
assertThat(result).isCompletedWithValueMatching(InternalValidationResult::isReject);
}
Aggregations