@Test public void createMainnetBlock1() throws IOException { final EthHashSolver solver = new EthHashSolver(Lists.newArrayList(BLOCK_1_NONCE), new Light()); final EthHashBlockCreator blockCreator = new EthHashBlockCreator( BLOCK_1_COINBASE, parent -> BLOCK_1_EXTRA_DATA, new PendingTransactions(1), executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), gasLimit -> gasLimit, solver, Wei.ZERO, executionContextTestFixture.getBlockchain().getChainHeadHeader()); // A Hashrate should not exist in the block creator prior to creating a block Assertions.assertThat(blockCreator.getHashesPerSecond().isPresent()).isFalse(); final Block actualBlock = blockCreator.createBlock(BLOCK_1_TIMESTAMP); final Block expectedBlock = ValidationTestUtils.readBlock(1); Assertions.assertThat(actualBlock).isEqualTo(expectedBlock); Assertions.assertThat(blockCreator.getHashesPerSecond().isPresent()).isTrue(); } }
@Test public void settingCoinbaseToNullThrowsException() { final MiningParameters miningParameters = new MiningParametersTestBuilder().build(); final EthHashMinerExecutor executor = new EthHashMinerExecutor( null, Executors.newCachedThreadPool(), null, new PendingTransactions(1), miningParameters, new DefaultBlockScheduler(1, 10, Clock.systemUTC())); assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> executor.setCoinbase(null)) .withMessageContaining("Coinbase cannot be unset."); } }
@Test public void extraDataCreatedOnEpochBlocksContainsValidators() { final byte[] vanityData = new byte[32]; new Random().nextBytes(vanityData); final BytesValue wrappedVanityData = BytesValue.wrap(vanityData); final int EPOCH_LENGTH = 10; final CliqueMinerExecutor executor = new CliqueMinerExecutor( cliqueProtocolContext, Executors.newSingleThreadExecutor(), CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), new PendingTransactions(1), proposerKeyPair, new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), mock(CliqueBlockScheduler.class), new EpochManager(EPOCH_LENGTH)); // NOTE: Passing in the *parent* block, so must be 1 less than EPOCH final BlockHeader header = blockHeaderBuilder.number(EPOCH_LENGTH - 1).buildHeader(); final BytesValue extraDataBytes = executor.calculateExtraData(header); final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(extraDataBytes); assertThat(cliqueExtraData.getVanityData()).isEqualTo(wrappedVanityData); assertThat(cliqueExtraData.getValidators()) .containsExactly(validatorList.toArray(new Address[0])); }
@Test public void extraDataForNonEpochBlocksDoesNotContainValidaors() { final byte[] vanityData = new byte[32]; new Random().nextBytes(vanityData); final BytesValue wrappedVanityData = BytesValue.wrap(vanityData); final int EPOCH_LENGTH = 10; final CliqueMinerExecutor executor = new CliqueMinerExecutor( cliqueProtocolContext, Executors.newSingleThreadExecutor(), CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), new PendingTransactions(1), proposerKeyPair, new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), mock(CliqueBlockScheduler.class), new EpochManager(EPOCH_LENGTH)); // Parent block was epoch, so the next block should contain no validators. final BlockHeader header = blockHeaderBuilder.number(EPOCH_LENGTH).buildHeader(); final BytesValue extraDataBytes = executor.calculateExtraData(header); final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(extraDataBytes); assertThat(cliqueExtraData.getVanityData()).isEqualTo(wrappedVanityData); assertThat(cliqueExtraData.getValidators()).isEqualTo(Lists.newArrayList()); } }
@Test public void invalidTransactionsTransactionProcessingAreSkippedButBlockStillFills() { final PendingTransactions pendingTransactions = new PendingTransactions(5);
@Test public void startingMiningWithoutCoinbaseThrowsException() { final MiningParameters miningParameters = new MiningParametersTestBuilder().coinbase(null).build(); final EthHashMinerExecutor executor = new EthHashMinerExecutor( null, Executors.newCachedThreadPool(), null, new PendingTransactions(1), miningParameters, new DefaultBlockScheduler(1, 10, Clock.systemUTC())); assertThatExceptionOfType(CoinbaseNotSetException.class) .isThrownBy(() -> executor.startAsyncMining(new Subscribers<>(), null)) .withMessageContaining("Unable to start mining without a coinbase."); }
@Test public void subsetOfPendingTransactionsIncludedWhenBlockGasLimitHit() { final PendingTransactions pendingTransactions = new PendingTransactions(5);
@Test public void proposerAddressCanBeExtractFromAConstructedBlock() { final CliqueExtraData extraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validatorList); final Address coinbase = AddressHelpers.ofValue(1); final CliqueBlockCreator blockCreator = new CliqueBlockCreator( coinbase, parent -> extraData.encode(), new PendingTransactions(5), protocolContext, protocolSchedule, gasLimit -> gasLimit, proposerKeyPair, Wei.ZERO, blockchain.getChainHeadHeader()); final Block createdBlock = blockCreator.createBlock(5L); assertThat(CliqueHelpers.getProposerOfBlock(createdBlock.getHeader())) .isEqualTo(proposerAddress); }
@Test public void failedTransactionsAreIncludedInTheBlock() { final PendingTransactions pendingTransactions = new PendingTransactions(5);
@Test public void transactionTooLargeForBlockDoesNotPreventMoreBeingAddedIfBlockOccupancyNotReached() { final PendingTransactions pendingTransactions = new PendingTransactions(5); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState();
@Test public void shouldDiscardTransactionsThatFailValidation() { final PendingTransactions pendingTransactions = new PendingTransactions(10); final TransactionProcessor transactionProcessor = mock(TransactionProcessor.class); final Blockchain blockchain = new TestBlockchain();
@Test public void transactionOfferingGasPriceLessThanMinimumIsIdentifiedAndRemovedFromPending() { final PendingTransactions pendingTransactions = new PendingTransactions(5);
@Test public void insertsValidVoteIntoConstructedBlock() { final CliqueExtraData extraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validatorList); final Address a1 = Address.fromHexString("5"); voteProposer.auth(a1); final Address coinbase = AddressHelpers.ofValue(1); final CliqueBlockCreator blockCreator = new CliqueBlockCreator( coinbase, parent -> extraData.encode(), new PendingTransactions(5), protocolContext, protocolSchedule, gasLimit -> gasLimit, proposerKeyPair, Wei.ZERO, blockchain.getChainHeadHeader()); final Block createdBlock = blockCreator.createBlock(0L); assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.ADD_NONCE); assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(a1); }
initialValidatorList) .encode(), new PendingTransactions(1), protContext, protocolSchedule,
protocolSchedule.getByBlockNumber(0).getTransactionProcessor(); final DefaultMutableWorldState worldState = inMemoryWorldState(); final PendingTransactions pendingTransactions = new PendingTransactions(5); final Supplier<Boolean> isCancelled = () -> false;
initialValidatorList) .encode(), new PendingTransactions(1), protContext, protocolSchedule,
@Test public void transactionSelectionStopsWhenSufficientBlockOccupancyIsReached() { final PendingTransactions pendingTransactions = new PendingTransactions(10); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState();
@Test public void insertsNoVoteWhenAuthInValidators() { final CliqueExtraData extraData = new CliqueExtraData(BytesValue.wrap(new byte[32]), null, validatorList); final Address a1 = Util.publicKeyToAddress(otherKeyPair.getPublicKey()); voteProposer.auth(a1); final Address coinbase = AddressHelpers.ofValue(1); final CliqueBlockCreator blockCreator = new CliqueBlockCreator( coinbase, parent -> extraData.encode(), new PendingTransactions(5), protocolContext, protocolSchedule, gasLimit -> gasLimit, proposerKeyPair, Wei.ZERO, blockchain.getChainHeadHeader()); final Block createdBlock = blockCreator.createBlock(0L); assertThat(createdBlock.getHeader().getNonce()).isEqualTo(CliqueBlockInterface.DROP_NONCE); assertThat(createdBlock.getHeader().getCoinbase()).isEqualTo(Address.fromHexString("0")); } }