From 8a3aedd5d0f87dc9582d26c0dde74db3160d3095 Mon Sep 17 00:00:00 2001 From: Rob Dawson Date: Tue, 5 Mar 2019 23:01:57 +0100 Subject: [PATCH] Clock.systemUTC only used once. TestClock class added with a factory method for a fixed clock. --- consensus/clique/build.gradle | 1 + .../blockcreation/CliqueBlockCreatorTest.java | 10 ++++---- .../CliqueMinerExecutorTest.java | 6 ++--- consensus/ibft/build.gradle | 1 + .../ibft/support/TestContextBuilder.java | 3 ++- .../blockcreation/IbftBlockCreatorTest.java | 4 ++-- consensus/ibftlegacy/build.gradle | 1 + .../blockcreation/IbftBlockCreatorTest.java | 4 ++-- ethereum/blockcreation/build.gradle | 1 + .../BlockTransactionSelectorTest.java | 18 +++++++-------- .../EthHashBlockCreatorTest.java | 4 ++-- .../EthHashMinerExecutorTest.java | 10 ++++---- .../core/PendingTransactionsTest.java | 4 ++-- .../ethereum/core/TransactionPoolTest.java | 4 ++-- .../eth/manager/EthProtocolManagerTest.java | 4 ++-- .../ethereum/eth/transactions/TestNode.java | 4 ++-- .../EthGetFilterChangesIntegrationTest.java | 4 ++-- .../results/TransactionInfoResult.java | 4 ++-- .../TxPoolPendingTransactionsTest.java | 2 +- .../cli/PantheonControllerBuilder.java | 6 +++-- .../controller/CliquePantheonController.java | 7 +++--- .../IbftLegacyPantheonController.java | 5 ++-- .../controller/IbftPantheonController.java | 12 ++++------ .../controller/MainnetPantheonController.java | 7 +++--- .../controller/PantheonController.java | 16 +++++++++---- .../tech/pegasys/pantheon/PrivacyTest.java | 4 +++- .../tech/pegasys/pantheon/RunnerTest.java | 10 +++++--- .../pantheon/util/BlockImporterTest.java | 7 ++++-- .../pegasys/pantheon/testutil/TestClock.java | 23 +++++++++++++++++++ 29 files changed, 116 insertions(+), 70 deletions(-) create mode 100644 testutil/src/main/java/tech/pegasys/pantheon/testutil/TestClock.java diff --git a/consensus/clique/build.gradle b/consensus/clique/build.gradle index c8111e5667..ade80f4f63 100644 --- a/consensus/clique/build.gradle +++ b/consensus/clique/build.gradle @@ -46,6 +46,7 @@ dependencies { testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation project(path: ':consensus:common', configuration: 'testArtifacts') + testImplementation project(':testutil') testImplementation 'junit:junit' testImplementation 'org.assertj:assertj-core' diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java index 95705248ee..919148c16a 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/blockcreation/CliqueBlockCreatorTest.java @@ -44,9 +44,9 @@ import tech.pegasys.pantheon.ethereum.core.Wei; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; -import java.time.Clock; import java.util.List; import com.google.common.collect.Lists; @@ -110,7 +110,7 @@ public void proposerAddressCanBeExtractFromAConstructedBlock() { new CliqueBlockCreator( coinbase, parent -> extraData.encode(), - new PendingTransactions(5, Clock.systemUTC()), + new PendingTransactions(5, TestClock.fixed()), protocolContext, protocolSchedule, gasLimit -> gasLimit, @@ -137,7 +137,7 @@ public void insertsValidVoteIntoConstructedBlock() { new CliqueBlockCreator( coinbase, parent -> extraData.encode(), - new PendingTransactions(5, Clock.systemUTC()), + new PendingTransactions(5, TestClock.fixed()), protocolContext, protocolSchedule, gasLimit -> gasLimit, @@ -163,7 +163,7 @@ public void insertsNoVoteWhenAuthInValidators() { new CliqueBlockCreator( coinbase, parent -> extraData.encode(), - new PendingTransactions(5, Clock.systemUTC()), + new PendingTransactions(5, TestClock.fixed()), protocolContext, protocolSchedule, gasLimit -> gasLimit, @@ -192,7 +192,7 @@ public void insertsNoVoteWhenAtEpoch() { new CliqueBlockCreator( coinbase, parent -> extraData.encode(), - new PendingTransactions(5, Clock.systemUTC()), + new PendingTransactions(5, TestClock.fixed()), protocolContext, protocolSchedule, gasLimit -> gasLimit, 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 f565b081e8..acf4cc6121 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 @@ -36,9 +36,9 @@ import tech.pegasys.pantheon.ethereum.core.PendingTransactions; import tech.pegasys.pantheon.ethereum.core.Util; import tech.pegasys.pantheon.ethereum.core.Wei; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; -import java.time.Clock; import java.util.List; import java.util.Random; import java.util.concurrent.Executors; @@ -87,7 +87,7 @@ public void extraDataCreatedOnEpochBlocksContainsValidators() { cliqueProtocolContext, Executors.newSingleThreadExecutor(), CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), proposerKeyPair, new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), mock(CliqueBlockScheduler.class), @@ -117,7 +117,7 @@ public void extraDataForNonEpochBlocksDoesNotContainValidaors() { cliqueProtocolContext, Executors.newSingleThreadExecutor(), CliqueProtocolSchedule.create(GENESIS_CONFIG_OPTIONS, proposerKeyPair), - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), proposerKeyPair, new MiningParameters(AddressHelpers.ofValue(1), Wei.ZERO, wrappedVanityData, false), mock(CliqueBlockScheduler.class), diff --git a/consensus/ibft/build.gradle b/consensus/ibft/build.gradle index 829fd80fd0..0724edba26 100644 --- a/consensus/ibft/build.gradle +++ b/consensus/ibft/build.gradle @@ -46,6 +46,7 @@ dependencies { testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation project(path: ':config:', configuration: 'testSupportArtifacts') testImplementation project(path: ':consensus:common', configuration: 'testArtifacts') + testImplementation project(':testutil') integrationTestImplementation 'junit:junit' integrationTestImplementation 'org.assertj:assertj-core' diff --git a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestContextBuilder.java b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestContextBuilder.java index 7ad3f22d6f..bc2e34dbcc 100644 --- a/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestContextBuilder.java +++ b/consensus/ibft/src/integration-test/java/tech/pegasys/pantheon/consensus/ibft/support/TestContextBuilder.java @@ -64,6 +64,7 @@ import tech.pegasys.pantheon.ethereum.core.Wei; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.Subscribers; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.uint.UInt256; @@ -303,7 +304,7 @@ private static ControllerAndState createControllerAndFinalState( ibftEventQueue, BLOCK_TIMER_SEC * 1000, Executors.newScheduledThreadPool(1), - Clock.systemUTC()), + TestClock.fixed()), blockCreatorFactory, new MessageFactory(nodeKeys), clock); diff --git a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorTest.java b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorTest.java index 4e8f65226a..5c39056d65 100644 --- a/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorTest.java +++ b/consensus/ibft/src/test/java/tech/pegasys/pantheon/consensus/ibft/blockcreation/IbftBlockCreatorTest.java @@ -38,9 +38,9 @@ import tech.pegasys.pantheon.ethereum.mainnet.BlockHeaderValidator; import tech.pegasys.pantheon.ethereum.mainnet.HeaderValidationMode; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; -import java.time.Clock; import java.time.Instant; import java.util.Collections; import java.util.List; @@ -92,7 +92,7 @@ public void createdBlockPassesValidationRulesAndHasAppropriateHashAndMixHash() { 0, initialValidatorList) .encode(), - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), protContext, protocolSchedule, parentGasLimit -> parentGasLimit, diff --git a/consensus/ibftlegacy/build.gradle b/consensus/ibftlegacy/build.gradle index e45c0bb85a..19e5bde444 100644 --- a/consensus/ibftlegacy/build.gradle +++ b/consensus/ibftlegacy/build.gradle @@ -31,6 +31,7 @@ dependencies { testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation project(path: ':consensus:ibft', configuration: 'testSupportArtifacts') + testImplementation project(':testutil') testImplementation 'junit:junit' testImplementation 'org.assertj:assertj-core' diff --git a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java index fd7ad7cdc7..8173eadfba 100644 --- a/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java +++ b/consensus/ibftlegacy/src/test/java/tech/pegasys/pantheon/consensus/ibftlegacy/blockcreation/IbftBlockCreatorTest.java @@ -38,9 +38,9 @@ import tech.pegasys.pantheon.ethereum.mainnet.BlockHeaderValidator; import tech.pegasys.pantheon.ethereum.mainnet.HeaderValidationMode; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSchedule; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; -import java.time.Clock; import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -97,7 +97,7 @@ public void headerProducedPassesValidationRules() { null, initialValidatorList) .encode(), - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), protContext, protocolSchedule, parentGasLimit -> parentGasLimit, diff --git a/ethereum/blockcreation/build.gradle b/ethereum/blockcreation/build.gradle index 1e2a7e74f0..63e682930e 100644 --- a/ethereum/blockcreation/build.gradle +++ b/ethereum/blockcreation/build.gradle @@ -26,6 +26,7 @@ dependencies { testImplementation project(path: ':config', configuration: 'testSupportArtifacts') testImplementation project(path: ':ethereum:core', configuration: 'testSupportArtifacts') testImplementation project(path: ':ethereum:core', configuration: 'testArtifacts') + testImplementation project(':testutil') testImplementation 'junit:junit' testImplementation 'org.assertj:assertj-core' diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java index 2f4e23bfd8..c52d9d28a5 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/BlockTransactionSelectorTest.java @@ -47,10 +47,10 @@ import tech.pegasys.pantheon.ethereum.vm.TestBlockchain; import tech.pegasys.pantheon.ethereum.worldstate.DefaultMutableWorldState; import tech.pegasys.pantheon.services.kvstore.InMemoryKeyValueStorage; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.uint.UInt256; -import java.time.Clock; import java.time.Instant; import java.util.List; import java.util.function.Supplier; @@ -71,7 +71,7 @@ public void emptyPendingTransactionsResultsInEmptyVettingResult() { final TransactionProcessor transactionProcessor = protocolSchedule.getByBlockNumber(0).getTransactionProcessor(); final DefaultMutableWorldState worldState = inMemoryWorldState(); - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final Supplier isCancelled = () -> false; final ProcessableBlockHeader blockHeader = @@ -108,7 +108,7 @@ public void emptyPendingTransactionsResultsInEmptyVettingResult() { @Test public void failedTransactionsAreIncludedInTheBlock() { - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final Transaction transaction = createTransaction(1); pendingTransactions.addRemoteTransaction(transaction); @@ -159,7 +159,7 @@ public void failedTransactionsAreIncludedInTheBlock() { @Test public void invalidTransactionsTransactionProcessingAreSkippedButBlockStillFills() { - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final List transactionsToInject = Lists.newArrayList(); for (int i = 0; i < 5; i++) { @@ -221,7 +221,7 @@ public void invalidTransactionsTransactionProcessingAreSkippedButBlockStillFills @Test public void subsetOfPendingTransactionsIncludedWhenBlockGasLimitHit() { - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final List transactionsToInject = Lists.newArrayList(); // Transactions are reported in reverse order. @@ -286,7 +286,7 @@ public void subsetOfPendingTransactionsIncludedWhenBlockGasLimitHit() { @Test public void transactionOfferingGasPriceLessThanMinimumIsIdentifiedAndRemovedFromPending() { - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final Blockchain blockchain = new TestBlockchain(); @@ -330,7 +330,7 @@ public void transactionOfferingGasPriceLessThanMinimumIsIdentifiedAndRemovedFrom @Test public void transactionTooLargeForBlockDoesNotPreventMoreBeingAddedIfBlockOccupancyNotReached() { - final PendingTransactions pendingTransactions = new PendingTransactions(5, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(5, TestClock.fixed()); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState(); final Supplier isCancelled = () -> false; @@ -400,7 +400,7 @@ public void transactionTooLargeForBlockDoesNotPreventMoreBeingAddedIfBlockOccupa @Test public void transactionSelectionStopsWhenSufficientBlockOccupancyIsReached() { - final PendingTransactions pendingTransactions = new PendingTransactions(10, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(10, TestClock.fixed()); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState(); final Supplier isCancelled = () -> false; @@ -481,7 +481,7 @@ public void transactionSelectionStopsWhenSufficientBlockOccupancyIsReached() { @Test public void shouldDiscardTransactionsThatFailValidation() { - final PendingTransactions pendingTransactions = new PendingTransactions(10, Clock.systemUTC()); + final PendingTransactions pendingTransactions = new PendingTransactions(10, TestClock.fixed()); final TransactionProcessor transactionProcessor = mock(TransactionProcessor.class); final Blockchain blockchain = new TestBlockchain(); final DefaultMutableWorldState worldState = inMemoryWorldState(); diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java index 2520f0aac7..5bb405a96c 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashBlockCreatorTest.java @@ -23,10 +23,10 @@ import tech.pegasys.pantheon.ethereum.mainnet.EthHasher.Light; import tech.pegasys.pantheon.ethereum.mainnet.ProtocolScheduleBuilder; import tech.pegasys.pantheon.ethereum.mainnet.ValidationTestUtils; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.io.IOException; -import java.time.Clock; import java.util.function.Function; import com.google.common.collect.Lists; @@ -63,7 +63,7 @@ public void createMainnetBlock1() throws IOException { new EthHashBlockCreator( BLOCK_1_COINBASE, parent -> BLOCK_1_EXTRA_DATA, - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), executionContextTestFixture.getProtocolContext(), executionContextTestFixture.getProtocolSchedule(), gasLimit -> gasLimit, diff --git a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashMinerExecutorTest.java b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashMinerExecutorTest.java index 2a57a484ab..fd88a672a4 100644 --- a/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashMinerExecutorTest.java +++ b/ethereum/blockcreation/src/test/java/tech/pegasys/pantheon/ethereum/blockcreation/EthHashMinerExecutorTest.java @@ -17,9 +17,9 @@ import tech.pegasys.pantheon.ethereum.core.MiningParameters; import tech.pegasys.pantheon.ethereum.core.MiningParametersTestBuilder; import tech.pegasys.pantheon.ethereum.core.PendingTransactions; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.Subscribers; -import java.time.Clock; import java.util.concurrent.Executors; import org.junit.Test; @@ -36,9 +36,9 @@ public void startingMiningWithoutCoinbaseThrowsException() { null, Executors.newCachedThreadPool(), null, - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), miningParameters, - new DefaultBlockScheduler(1, 10, Clock.systemUTC())); + new DefaultBlockScheduler(1, 10, TestClock.fixed())); assertThatExceptionOfType(CoinbaseNotSetException.class) .isThrownBy(() -> executor.startAsyncMining(new Subscribers<>(), null)) @@ -54,9 +54,9 @@ public void settingCoinbaseToNullThrowsException() { null, Executors.newCachedThreadPool(), null, - new PendingTransactions(1, Clock.systemUTC()), + new PendingTransactions(1, TestClock.fixed()), miningParameters, - new DefaultBlockScheduler(1, 10, Clock.systemUTC())); + new DefaultBlockScheduler(1, 10, TestClock.fixed())); assertThatExceptionOfType(IllegalArgumentException.class) .isThrownBy(() -> executor.setCoinbase(null)) diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/PendingTransactionsTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/PendingTransactionsTest.java index b805daf0b6..5eccd26a06 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/PendingTransactionsTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/PendingTransactionsTest.java @@ -19,8 +19,8 @@ import tech.pegasys.pantheon.crypto.SECP256K1.KeyPair; import tech.pegasys.pantheon.ethereum.core.PendingTransactions.TransactionSelectionResult; +import tech.pegasys.pantheon.testutil.TestClock; -import java.time.Clock; import java.util.ArrayList; import java.util.List; import java.util.OptionalLong; @@ -34,7 +34,7 @@ public class PendingTransactionsTest { private static final KeyPair KEYS1 = KeyPair.generate(); private static final KeyPair KEYS2 = KeyPair.generate(); private final PendingTransactions transactions = - new PendingTransactions(MAX_TRANSACTIONS, Clock.systemUTC()); + new PendingTransactions(MAX_TRANSACTIONS, TestClock.fixed()); private final Transaction transaction1 = createTransaction(2); private final Transaction transaction2 = createTransaction(1); diff --git a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java index a7e21d61e1..fcabf4198e 100644 --- a/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java +++ b/ethereum/core/src/test/java/tech/pegasys/pantheon/ethereum/core/TransactionPoolTest.java @@ -41,9 +41,9 @@ import tech.pegasys.pantheon.ethereum.mainnet.ProtocolSpec; import tech.pegasys.pantheon.ethereum.mainnet.TransactionValidator; import tech.pegasys.pantheon.ethereum.mainnet.ValidationResult; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.uint.UInt256; -import java.time.Clock; import java.util.List; import java.util.OptionalLong; @@ -68,7 +68,7 @@ public class TransactionPoolTest { private final TransactionValidator transactionValidator = mock(TransactionValidator.class); private MutableBlockchain blockchain; private final PendingTransactions transactions = - new PendingTransactions(MAX_TRANSACTIONS, Clock.systemUTC()); + new PendingTransactions(MAX_TRANSACTIONS, TestClock.fixed()); private final Transaction transaction1 = createTransaction(1); private final Transaction transaction2 = createTransaction(2); private TransactionPool transactionPool; diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/manager/EthProtocolManagerTest.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/manager/EthProtocolManagerTest.java index 2165d30c1f..d4d84704d7 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/manager/EthProtocolManagerTest.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/manager/EthProtocolManagerTest.java @@ -58,10 +58,10 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.RawMessage; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.uint.UInt256; -import java.time.Clock; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1015,7 +1015,7 @@ public void transactionMessagesGoToTheCorrectExecutor() { // Create a transaction pool. This has a side effect of registring a listener for the // transactions message. TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethManager.ethContext(), Clock.systemUTC()); + protocolSchedule, protocolContext, ethManager.ethContext(), TestClock.fixed()); // Send just a transaction message. final PeerConnection peer = setupPeer(ethManager, (cap, msg, connection) -> {}); diff --git a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java index b0efd86f87..e2f62cd8a9 100644 --- a/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java +++ b/ethereum/eth/src/test/java/tech/pegasys/pantheon/ethereum/eth/transactions/TestNode.java @@ -46,12 +46,12 @@ import tech.pegasys.pantheon.ethereum.p2p.wire.messages.DisconnectMessage.DisconnectReason; import tech.pegasys.pantheon.ethereum.worldstate.WorldStateArchive; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; import java.io.Closeable; import java.io.IOException; import java.net.InetAddress; -import java.time.Clock; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -133,7 +133,7 @@ public TestNode( final EthContext ethContext = ethProtocolManager.ethContext(); transactionPool = TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethContext, Clock.systemUTC()); + protocolSchedule, protocolContext, ethContext, TestClock.fixed()); networkRunner.start(); selfPeer = new DefaultPeer(id(), endpoint()); diff --git a/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java b/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java index 81c0c2ee33..dbee2c7a16 100644 --- a/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java +++ b/ethereum/jsonrpc/src/integration-test/java/tech/pegasys/pantheon/ethereum/jsonrpc/methods/EthGetFilterChangesIntegrationTest.java @@ -43,10 +43,10 @@ import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcErrorResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcResponse; import tech.pegasys.pantheon.ethereum.jsonrpc.internal.response.JsonRpcSuccessResponse; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.bytes.BytesValue; import tech.pegasys.pantheon.util.uint.UInt256; -import java.time.Clock; import java.util.List; import org.assertj.core.util.Lists; @@ -65,7 +65,7 @@ public class EthGetFilterChangesIntegrationTest { private final String JSON_RPC_VERSION = "2.0"; private TransactionPool transactionPool; private final PendingTransactions transactions = - new PendingTransactions(MAX_TRANSACTIONS, Clock.systemUTC()); + new PendingTransactions(MAX_TRANSACTIONS, TestClock.fixed()); private static final int MAX_TRANSACTIONS = 5; private static final KeyPair keyPair = KeyPair.generate(); private final Transaction transaction = createTransaction(1); diff --git a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionInfoResult.java b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionInfoResult.java index 1027074d7e..b81180b09a 100644 --- a/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionInfoResult.java +++ b/ethereum/jsonrpc/src/main/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/results/TransactionInfoResult.java @@ -38,8 +38,8 @@ public String getHash() { } @JsonGetter(value = "addedToPoolAt") - public long getAddedToPoolAt() { - return addedToPoolAt.toEpochMilli(); + public String getAddedToPoolAt() { + return addedToPoolAt.toString(); } @JsonGetter(value = "isReceivedFromLocalSource") diff --git a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/TxPoolPendingTransactionsTest.java b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/TxPoolPendingTransactionsTest.java index 4e50f93fda..d453bddffa 100644 --- a/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/TxPoolPendingTransactionsTest.java +++ b/ethereum/jsonrpc/src/test/java/tech/pegasys/pantheon/ethereum/jsonrpc/internal/methods/TxPoolPendingTransactionsTest.java @@ -73,6 +73,6 @@ public void shouldReturnPendingTransactions() { result.getResults().stream().findFirst().get(); assertEquals(TRANSACTION_HASH, actualTransactionInfo.getHash()); assertEquals(true, actualTransactionInfo.isReceivedFromLocalSource()); - assertEquals(addedAt.toEpochMilli(), actualTransactionInfo.getAddedToPoolAt()); + assertEquals(addedAt.toString(), actualTransactionInfo.getAddedToPoolAt()); } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java index e4e3251c30..39337b299c 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonControllerBuilder.java @@ -28,6 +28,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.time.Clock; public class PantheonControllerBuilder { @@ -102,7 +103,7 @@ public PantheonController build() throws IOException { final String genesisConfig = ethNetworkConfig.getGenesisConfig(); genesisConfigFile = GenesisConfigFile.fromConfig(genesisConfig); } - + Clock clock = Clock.systemUTC(); return PantheonController.fromConfig( genesisConfigFile, synchronizerConfiguration, @@ -113,6 +114,7 @@ public PantheonController build() throws IOException { nodeKeys, metricsSystem, privacyParameters, - homePath); + homePath, + clock); } } diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonController.java index aad3368383..9c628b84ab 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/CliquePantheonController.java @@ -110,7 +110,8 @@ static PantheonController init( final int networkId, final KeyPair nodeKeys, final Path dataDirectory, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final Clock clock) { final Address localAddress = Util.publicKeyToAddress(nodeKeys.getPublicKey()); final CliqueConfigOptions cliqueConfig = genesisConfig.getConfigOptions().getCliqueConfigOptions(); @@ -165,7 +166,7 @@ static PantheonController init( final TransactionPool transactionPool = TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethProtocolManager.ethContext(), Clock.systemUTC()); + protocolSchedule, protocolContext, ethProtocolManager.ethContext(), clock); final ExecutorService minerThreadPool = Executors.newCachedThreadPool(); final CliqueMinerExecutor miningExecutor = @@ -177,7 +178,7 @@ static PantheonController init( nodeKeys, miningParams, new CliqueBlockScheduler( - Clock.systemUTC(), + clock, protocolContext.getConsensusState().getVoteTallyCache(), localAddress, secondsBetweenBlocks), diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonController.java index 2eaf26fdbd..aea79711b5 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftLegacyPantheonController.java @@ -102,7 +102,8 @@ static PantheonController init( final int networkId, final KeyPair nodeKeys, final Path dataDirectory, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final Clock clock) { final ProtocolSchedule protocolSchedule = IbftProtocolSchedule.create(genesisConfig.getConfigOptions()); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); @@ -183,7 +184,7 @@ static PantheonController init( final TransactionPool transactionPool = TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethProtocolManager.ethContext(), Clock.systemUTC()); + protocolSchedule, protocolContext, ethProtocolManager.ethContext(), clock); return new IbftLegacyPantheonController( protocolSchedule, diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java index 85f17d098e..e95ed346ff 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/IbftPantheonController.java @@ -138,7 +138,8 @@ static PantheonController init( final int networkId, final KeyPair nodeKeys, final Path dataDirectory, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final Clock clock) { final ProtocolSchedule protocolSchedule = IbftProtocolSchedule.create(genesisConfig.getConfigOptions()); final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); @@ -195,7 +196,7 @@ static PantheonController init( final TransactionPool transactionPool = TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethContext, Clock.systemUTC()); + protocolSchedule, protocolContext, ethContext, clock); final IbftEventQueue ibftEventQueue = new IbftEventQueue(ibftConfig.getMessageQueueLimit()); @@ -233,13 +234,10 @@ static PantheonController init( uniqueMessageMulticaster, new RoundTimer(ibftEventQueue, ibftConfig.getRequestTimeoutSeconds(), timerExecutor), new BlockTimer( - ibftEventQueue, - ibftConfig.getBlockPeriodSeconds(), - timerExecutor, - Clock.systemUTC()), + ibftEventQueue, ibftConfig.getBlockPeriodSeconds(), timerExecutor, clock), blockCreatorFactory, new MessageFactory(nodeKeys), - Clock.systemUTC()); + clock); final MessageValidatorFactory messageValidatorFactory = new MessageValidatorFactory(proposerSelector, protocolSchedule, protocolContext); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonController.java index 6b3c89379e..376ab10c2b 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/MainnetPantheonController.java @@ -103,7 +103,8 @@ public static PantheonController init( final KeyPair nodeKeys, final PrivacyParameters privacyParameters, final Path dataDirectory, - final MetricsSystem metricsSystem) { + final MetricsSystem metricsSystem, + final Clock clock) { final GenesisState genesisState = GenesisState.fromConfig(genesisConfig, protocolSchedule); final ProtocolContext protocolContext = @@ -147,7 +148,7 @@ public static PantheonController init( final TransactionPool transactionPool = TransactionPoolFactory.createTransactionPool( - protocolSchedule, protocolContext, ethProtocolManager.ethContext(), Clock.systemUTC()); + protocolSchedule, protocolContext, ethProtocolManager.ethContext(), clock); final ExecutorService minerThreadPool = Executors.newCachedThreadPool(); final EthHashMinerExecutor executor = @@ -160,7 +161,7 @@ public static PantheonController init( new DefaultBlockScheduler( MainnetBlockHeaderValidator.MINIMUM_SECONDS_SINCE_PARENT, MainnetBlockHeaderValidator.TIMESTAMP_TOLERANCE_S, - Clock.systemUTC())); + clock)); final EthHashMiningCoordinator miningCoordinator = new EthHashMiningCoordinator(blockchain, executor, syncState); diff --git a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java index 2e85c2bf1d..dba52c98a8 100644 --- a/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java +++ b/pantheon/src/main/java/tech/pegasys/pantheon/controller/PantheonController.java @@ -34,6 +34,7 @@ import java.io.Closeable; import java.nio.file.Path; +import java.time.Clock; import java.util.Collection; import java.util.Map; @@ -51,7 +52,8 @@ static PantheonController fromConfig( final KeyPair nodeKeys, final MetricsSystem metricsSystem, final PrivacyParameters privacyParameters, - final Path dataDirectory) { + final Path dataDirectory, + final Clock clock) { final GenesisConfigOptions configOptions = genesisConfigFile.getConfigOptions(); @@ -66,7 +68,8 @@ static PantheonController fromConfig( nodeKeys, privacyParameters, dataDirectory, - metricsSystem); + metricsSystem, + clock); } else if (configOptions.isIbft2()) { return IbftPantheonController.init( storageProvider, @@ -76,7 +79,8 @@ static PantheonController fromConfig( networkId, nodeKeys, dataDirectory, - metricsSystem); + metricsSystem, + clock); } else if (configOptions.isIbftLegacy()) { return IbftLegacyPantheonController.init( storageProvider, @@ -86,7 +90,8 @@ static PantheonController fromConfig( networkId, nodeKeys, dataDirectory, - metricsSystem); + metricsSystem, + clock); } else if (configOptions.isClique()) { return CliquePantheonController.init( storageProvider, @@ -96,7 +101,8 @@ static PantheonController fromConfig( networkId, nodeKeys, dataDirectory, - metricsSystem); + metricsSystem, + clock); } else { throw new IllegalArgumentException("Unknown consensus mechanism defined"); } diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/PrivacyTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/PrivacyTest.java index 9005ba235c..70d62ac792 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/PrivacyTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/PrivacyTest.java @@ -25,6 +25,7 @@ import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; import tech.pegasys.pantheon.ethereum.mainnet.PrecompiledContract; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; +import tech.pegasys.pantheon.testutil.TestClock; import java.io.IOException; import java.nio.file.Path; @@ -57,7 +58,8 @@ public void privacyPrecompiled() throws IOException { SECP256K1.KeyPair.generate(), new NoOpMetricsSystem(), privacyParameters, - dataDir); + dataDir, + TestClock.fixed()); Address privacyContractAddress = Address.privacyPrecompiled(ADDRESS); PrecompiledContract precompiledContract = diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java index 557b1fb944..952ae12878 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/RunnerTest.java @@ -44,6 +44,7 @@ import tech.pegasys.pantheon.metrics.MetricsSystem; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.uint.UInt256; import java.io.IOException; @@ -112,7 +113,8 @@ private void syncFromGenesis(final SyncMode mode) throws Exception { aheadDbNodeKeys, PrivacyParameters.noPrivacy(), dataDirAhead, - noOpMetricsSystem)) { + noOpMetricsSystem, + TestClock.fixed())) { setupState(blockCount, controller.getProtocolSchedule(), controller.getProtocolContext()); } @@ -128,7 +130,8 @@ private void syncFromGenesis(final SyncMode mode) throws Exception { aheadDbNodeKeys, PrivacyParameters.noPrivacy(), dataDirAhead, - noOpMetricsSystem); + noOpMetricsSystem, + TestClock.fixed()); final String listenHost = InetAddress.getLoopbackAddress().getHostAddress(); final ExecutorService executorService = Executors.newFixedThreadPool(2); final JsonRpcConfiguration aheadJsonRpcConfiguration = jsonRpcConfiguration(); @@ -182,7 +185,8 @@ private void syncFromGenesis(final SyncMode mode) throws Exception { KeyPair.generate(), PrivacyParameters.noPrivacy(), dataDirBehind, - noOpMetricsSystem); + noOpMetricsSystem, + TestClock.fixed()); final Peer advertisedPeer = runnerAhead.getAdvertisedPeer().get(); final EthNetworkConfig behindEthNetworkConfiguration = new EthNetworkConfig( diff --git a/pantheon/src/test/java/tech/pegasys/pantheon/util/BlockImporterTest.java b/pantheon/src/test/java/tech/pegasys/pantheon/util/BlockImporterTest.java index ed7837b5a0..6e231580a3 100644 --- a/pantheon/src/test/java/tech/pegasys/pantheon/util/BlockImporterTest.java +++ b/pantheon/src/test/java/tech/pegasys/pantheon/util/BlockImporterTest.java @@ -24,6 +24,7 @@ import tech.pegasys.pantheon.ethereum.eth.sync.SynchronizerConfiguration; import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem; import tech.pegasys.pantheon.testutil.BlockTestUtil; +import tech.pegasys.pantheon.testutil.TestClock; import tech.pegasys.pantheon.util.uint.UInt256; import java.io.IOException; @@ -59,7 +60,8 @@ public void blockImport() throws IOException { KeyPair.generate(), new NoOpMetricsSystem(), PrivacyParameters.noPrivacy(), - dataDir); + dataDir, + TestClock.fixed()); final BlockImporter.ImportResult result = blockImporter.importBlockchain(source, targetController); // Don't count the Genesis block @@ -95,7 +97,8 @@ public void ibftImport() throws IOException { KeyPair.generate(), new NoOpMetricsSystem(), PrivacyParameters.noPrivacy(), - dataDir); + dataDir, + TestClock.fixed()); final BlockImporter.ImportResult result = blockImporter.importBlockchain(source, controller); // Don't count the Genesis block diff --git a/testutil/src/main/java/tech/pegasys/pantheon/testutil/TestClock.java b/testutil/src/main/java/tech/pegasys/pantheon/testutil/TestClock.java new file mode 100644 index 0000000000..73e495d07b --- /dev/null +++ b/testutil/src/main/java/tech/pegasys/pantheon/testutil/TestClock.java @@ -0,0 +1,23 @@ +/* + * Copyright 2019 ConsenSys AG. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package tech.pegasys.pantheon.testutil; + +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; + +public class TestClock { + public static Clock fixed() { + return Clock.fixed(Instant.ofEpochSecond(10_000_000), ZoneId.systemDefault()); + } +}