diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java index e94010e23d..d92aec58cc 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutor.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.concurrent.ExecutorService; +import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; public class CliqueMinerExecutor extends AbstractMinerExecutor { @@ -41,7 +42,6 @@ public class CliqueMinerExecutor extends AbstractMinerExecutor protocolContext, @@ -62,7 +62,6 @@ public CliqueMinerExecutor( this.nodeKeys = nodeKeys; this.localAddress = Util.publicKeyToAddress(nodeKeys.getPublicKey()); this.epochManager = epochManager; - this.vanityData = miningParams.getExtraData(); } @Override @@ -94,11 +93,12 @@ public CliqueBlockMiner startAsyncMining( return currentRunningMiner; } - public BytesValue calculateExtraData(final BlockHeader parentHeader) { + @VisibleForTesting + BytesValue calculateExtraData(final BlockHeader parentHeader) { final List
validators = Lists.newArrayList(); final BytesValue vanityDataToInsert = - ConsensusHelpers.zeroLeftPad(vanityData, CliqueExtraData.EXTRA_VANITY_LENGTH); + ConsensusHelpers.zeroLeftPad(extraData, CliqueExtraData.EXTRA_VANITY_LENGTH); // Building ON TOP of canonical head, if the next block is epoch, include validators. if (epochManager.isEpochBlock(parentHeader.getNumber() + 1)) { final VoteTally voteTally = diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java index fa6463909f..1a92348974 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueMinerExecutorTest.java @@ -52,9 +52,11 @@ public class CliqueMinerExecutorTest { + private static final int EPOCH_LENGTH = 10; private static final GenesisConfigOptions GENESIS_CONFIG_OPTIONS = GenesisConfigFile.fromConfig(new JsonObject()).getConfigOptions(); private final KeyPair proposerKeyPair = KeyPair.generate(); + private final Random random = new Random(21341234L); private Address localAddress; private final List
validatorList = Lists.newArrayList(); private ProtocolContext cliqueProtocolContext; @@ -80,10 +82,7 @@ public void setup() { @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 BytesValue vanityData = generateRandomVanityData(); final CliqueMinerExecutor executor = new CliqueMinerExecutor( @@ -96,7 +95,7 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() { TestClock.fixed(), metricsSystem), proposerKeyPair, - new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), + new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, vanityData, false), mock(CliqueBlockScheduler.class), new EpochManager(EPOCH_LENGTH)); @@ -107,17 +106,14 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() { final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(extraDataBytes); - assertThat(cliqueExtraData.getVanityData()).isEqualTo(wrappedVanityData); + assertThat(cliqueExtraData.getVanityData()).isEqualTo(vanityData); 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 BytesValue vanityData = generateRandomVanityData(); final CliqueMinerExecutor executor = new CliqueMinerExecutor( @@ -130,7 +126,7 @@ public void extraDataForNonEpochBlocksDoesNotContainValidaors() { TestClock.fixed(), metricsSystem), proposerKeyPair, - new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), + new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, vanityData, false), mock(CliqueBlockScheduler.class), new EpochManager(EPOCH_LENGTH)); @@ -141,7 +137,40 @@ public void extraDataForNonEpochBlocksDoesNotContainValidaors() { final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(extraDataBytes); - assertThat(cliqueExtraData.getVanityData()).isEqualTo(wrappedVanityData); + assertThat(cliqueExtraData.getVanityData()).isEqualTo(vanityData); assertThat(cliqueExtraData.getValidators()).isEqualTo(Lists.newArrayList()); } + + @Test + public void shouldUseLatestVanityData() { + final BytesValue initialVanityData = generateRandomVanityData(); + final BytesValue modifiedVanityData = generateRandomVanityData(); + + final CliqueMinerExecutor executor = + new CliqueMinerExecutor( + cliqueProtocolContext, + Executors.newSingleThreadExecutor(), + CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), + new PendingTransactions( + PendingTransactions.DEFAULT_TX_RETENTION_HOURS, + 1, + TestClock.fixed(), + metricsSystem), + proposerKeyPair, + new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, initialVanityData, false), + mock(CliqueBlockScheduler.class), + new EpochManager(EPOCH_LENGTH)); + + executor.setExtraData(modifiedVanityData); + final BytesValue extraDataBytes = executor.calculateExtraData(blockHeaderBuilder.buildHeader()); + + final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(extraDataBytes); + assertThat(cliqueExtraData.getVanityData()).isEqualTo(modifiedVanityData); + } + + private BytesValue generateRandomVanityData() { + final byte[] vanityData = new byte[32]; + random.nextBytes(vanityData); + return BytesValue.wrap(vanityData); + } }