From f6d3e12f8233971130f356787051488f7617295e Mon Sep 17 00:00:00 2001 From: SergioDemianLerner Date: Mon, 17 Dec 2018 20:10:43 -0300 Subject: [PATCH] Add block replayer from existing database (blockstore) --- .../java/co/rsk/BlockstoreBlockPlayer.java | 81 +++++++ .../src/main/java/co/rsk/FullNodeRunner.java | 39 +-- .../src/main/java/co/rsk/RskContext.java | 225 +++++++++++++++++ .../main/java/co/rsk/blocks/BlockPlayer.java | 28 --- .../java/co/rsk/blocks/FileBlockPlayer.java | 78 ------ .../co/rsk/config/RskSystemProperties.java | 4 - .../co/rsk/blocks/FileBlockPlayerTest.java | 47 ---- .../java/co/rsk/core/SnapshotManagerTest.java | 3 +- .../co/rsk/core/bc/BlockChainImplTest.java | 2 +- .../co/rsk/core/bc/SelectionRuleTest.java | 2 +- .../rsk/core/bc/TransactionPoolImplTest.java | 2 +- .../java/co/rsk/mine/MainNetMinerTest.java | 8 +- .../java/co/rsk/mine/MinerManagerTest.java | 4 +- .../java/co/rsk/mine/MinerServerTest.java | 3 +- .../co/rsk/test/builders/AccountBuilder.java | 6 +- .../co/rsk/test/builders/BlockBuilder.java | 12 +- .../java/org/ethereum/rpc/LogFilterTest.java | 8 +- .../org/ethereum/rpc/Web3ImplLogsTest.java | 7 +- .../ethereum/rpc/Web3ImplSnapshotTest.java | 3 +- .../org/ethereum/util/ContractRunner.java | 5 +- .../org/ethereum/util/RskTestFactory.java | 229 ++++++------------ 21 files changed, 407 insertions(+), 389 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/BlockstoreBlockPlayer.java create mode 100644 rskj-core/src/main/java/co/rsk/RskContext.java delete mode 100644 rskj-core/src/main/java/co/rsk/blocks/BlockPlayer.java delete mode 100644 rskj-core/src/main/java/co/rsk/blocks/FileBlockPlayer.java delete mode 100644 rskj-core/src/test/java/co/rsk/blocks/FileBlockPlayerTest.java diff --git a/rskj-core/src/main/java/co/rsk/BlockstoreBlockPlayer.java b/rskj-core/src/main/java/co/rsk/BlockstoreBlockPlayer.java new file mode 100644 index 00000000000..2b7ff1bbba6 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/BlockstoreBlockPlayer.java @@ -0,0 +1,81 @@ +/* + * This file is part of RskJ + * Copyright (C) 2019 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package co.rsk; + +import co.rsk.core.RskFactory; +import co.rsk.net.BlockProcessResult; +import org.ethereum.core.Block; +import org.ethereum.core.Blockchain; +import org.ethereum.core.ImportResult; +import org.ethereum.db.BlockStore; + +import java.util.Arrays; + +public class BlockstoreBlockPlayer { + private final String sourceDir; + private final Blockchain targetBlockchain; + + private long blockNumber; + + private BlockstoreBlockPlayer(String sourceDir, RskContext objects) { + this.sourceDir = sourceDir; + this.targetBlockchain = objects.getBlockchain(); + this.blockNumber = targetBlockchain.getBestBlock().getNumber() + 1; + } + + private void connectBlocks() { + BlockStore sourceBlockStore = RskFactory.buildBlockStore(sourceDir); + for (Block block = nextBlock(sourceBlockStore); block != null; block = nextBlock(sourceBlockStore)) { + if (!connectBlock(block)) { + System.err.printf("Import failed at block %s\n", block.getNumber()); + System.exit(1); + return; + } + + if (block.getNumber() % 100 == 0) { + System.out.printf("Imported block with number %7d\n", block.getNumber()); + } + } + + System.out.printf("Best block is now %7d%n", targetBlockchain.getBestBlock().getNumber()); + } + + private boolean connectBlock(Block block) { + ImportResult tryToConnectResult = targetBlockchain.tryToConnect(block); + return BlockProcessResult.importOk(tryToConnectResult); + } + + private Block nextBlock(BlockStore sourceBlockStore) { + return sourceBlockStore.getChainBlockByNumber(blockNumber++); + } + + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("usage: BlockstoreBlockPlayer [] "); + System.exit(0); + return; + } + + String[] nodeCliArgs = Arrays.copyOf(args, args.length - 1); + RskContext objects = new RskContext(nodeCliArgs); + BlockstoreBlockPlayer bplayer = new BlockstoreBlockPlayer(args[args.length - 1], objects); + bplayer.connectBlocks(); + System.exit(0); + } +} diff --git a/rskj-core/src/main/java/co/rsk/FullNodeRunner.java b/rskj-core/src/main/java/co/rsk/FullNodeRunner.java index e23c4b80401..41c8eb4f120 100644 --- a/rskj-core/src/main/java/co/rsk/FullNodeRunner.java +++ b/rskj-core/src/main/java/co/rsk/FullNodeRunner.java @@ -17,23 +17,24 @@ */ package co.rsk; -import co.rsk.blocks.BlockPlayer; -import co.rsk.blocks.FileBlockPlayer; import co.rsk.blocks.FileBlockRecorder; import co.rsk.config.RskSystemProperties; import co.rsk.core.Rsk; -import co.rsk.core.RskImpl; import co.rsk.db.PruneConfiguration; import co.rsk.db.PruneService; import co.rsk.mine.MinerClient; import co.rsk.mine.MinerServer; import co.rsk.mine.TxBuilder; import co.rsk.mine.TxBuilderEx; -import co.rsk.net.*; +import co.rsk.net.BlockProcessor; +import co.rsk.net.MessageHandler; +import co.rsk.net.TransactionGateway; import co.rsk.net.discovery.UDPServer; import co.rsk.rpc.netty.Web3HttpServer; import co.rsk.rpc.netty.Web3WebSocketServer; -import org.ethereum.core.*; +import org.ethereum.core.Blockchain; +import org.ethereum.core.Repository; +import org.ethereum.core.TransactionPool; import org.ethereum.net.eth.EthVersion; import org.ethereum.net.server.ChannelManager; import org.ethereum.net.server.PeerServer; @@ -146,7 +147,6 @@ public void run() throws Exception { } if (rskSystemProperties.isBlocksEnabled()) { setupRecorder(rskSystemProperties.blocksRecorder()); - setupPlayer(rsk, channelManager, blockchain, rskSystemProperties.blocksPlayer()); } if (!"".equals(rskSystemProperties.blocksLoader())) { @@ -290,31 +290,4 @@ private void setupRecorder(@Nullable String blocksRecorderFileName) { blockchain.setBlockRecorder(new FileBlockRecorder(blocksRecorderFileName)); } } - - private void setupPlayer(Rsk rsk, ChannelManager cm, Blockchain bc, @Nullable String blocksPlayerFileName) { - if (blocksPlayerFileName == null) { - return; - } - - new Thread(() -> { - RskImpl rskImpl = (RskImpl) rsk; - try (FileBlockPlayer bplayer = new FileBlockPlayer(rskSystemProperties, blocksPlayerFileName)) { - rskImpl.setIsPlayingBlocks(true); - connectBlocks(bplayer, bc, cm); - } catch (Exception e) { - logger.error("Error", e); - } finally { - rskImpl.setIsPlayingBlocks(false); - } - }).start(); - } - - private void connectBlocks(BlockPlayer bplayer, Blockchain bc, ChannelManager cm) { - for (Block block = bplayer.readBlock(); block != null; block = bplayer.readBlock()) { - ImportResult tryToConnectResult = bc.tryToConnect(block); - if (BlockProcessResult.importOk(tryToConnectResult)) { - cm.broadcastBlock(block); - } - } - } } diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java new file mode 100644 index 00000000000..753f8c201fb --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -0,0 +1,225 @@ +/* + * This file is part of RskJ + * Copyright (C) 2019 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package co.rsk; + +import co.rsk.cli.CliArgs; +import co.rsk.config.NodeCliFlags; +import co.rsk.config.NodeCliOptions; +import co.rsk.config.RskSystemProperties; +import co.rsk.core.DifficultyCalculator; +import co.rsk.core.RskFactory; +import co.rsk.core.bc.BlockValidatorImpl; +import co.rsk.validators.BlockParentDependantValidationRule; +import co.rsk.validators.BlockValidationRule; +import co.rsk.validators.BlockValidator; +import co.rsk.validators.ProofOfWorkRule; +import org.ethereum.core.Blockchain; +import org.ethereum.core.Genesis; +import org.ethereum.core.Repository; +import org.ethereum.core.TransactionPool; +import org.ethereum.core.genesis.BlockChainLoader; +import org.ethereum.db.BlockStore; +import org.ethereum.db.ReceiptStore; +import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; + +/** + * Creates the initial object graph without a DI framework. + */ +public class RskContext { + private final RskFactory factory; + private final CliArgs cliArgs; + + private RskSystemProperties rskSystemProperties; + private Blockchain blockchain; + private BlockChainLoader blockChainLoader; + private BlockStore blockStore; + private Repository repository; + private Genesis genesis; + private CompositeEthereumListener compositeEthereumListener; + private DifficultyCalculator difficultyCalculator; + private ProofOfWorkRule proofOfWorkRule; + private BlockParentDependantValidationRule blockParentDependantValidationRule; + private BlockValidationRule blockValidationRule; + private BlockValidatorImpl blockValidator; + private ReceiptStore receiptStore; + private ProgramInvokeFactoryImpl programInvokeFactory; + private TransactionPool transactionPool; + + public RskContext(String[] args) { + this(new CliArgs.Parser<>( + NodeCliOptions.class, + NodeCliFlags.class + ).parse(args)); + } + + private RskContext(CliArgs cliArgs) { + this.factory = new RskFactory(); + this.cliArgs = cliArgs; + } + + public Blockchain getBlockchain() { + if (blockchain == null) { + blockchain = factory.getBlockchain(getBlockChainLoader()); + } + + return blockchain; + } + + private BlockChainLoader getBlockChainLoader() { + if (blockChainLoader == null) { + blockChainLoader = new BlockChainLoader( + getRskSystemProperties(), + getRepository(), + getBlockStore(), + getReceiptStore(), + getTransactionPool(), + getCompositeEthereumListener(), + getBlockValidator(), + getGenesis() + ); + } + + return blockChainLoader; + } + + public TransactionPool getTransactionPool() { + if (transactionPool == null) { + transactionPool = factory.getTransactionPool( + getBlockStore(), + getReceiptStore(), + getRepository(), + getRskSystemProperties(), + getProgramInvokeFactory(), + getCompositeEthereumListener() + ); + } + + return transactionPool; + } + + public ProgramInvokeFactoryImpl getProgramInvokeFactory() { + if (programInvokeFactory == null) { + programInvokeFactory = new ProgramInvokeFactoryImpl(); + } + + return programInvokeFactory; + } + + public ReceiptStore getReceiptStore() { + if (receiptStore == null) { + receiptStore = factory.receiptStore(getRskSystemProperties()); + } + + return receiptStore; + } + + public BlockValidator getBlockValidator() { + if (blockValidator == null) { + blockValidator = new BlockValidatorImpl( + getBlockStore(), + getBlockParentDependantValidationRule(), + getBlockValidationRule() + ); + } + + return blockValidator; + } + + private BlockValidationRule getBlockValidationRule() { + if (blockValidationRule == null) { + blockValidationRule = factory.blockValidationRule( + getBlockStore(), + getRskSystemProperties(), + getDifficultyCalculator(), + getProofOfWorkRule() + ); + } + + return blockValidationRule; + } + + private BlockParentDependantValidationRule getBlockParentDependantValidationRule() { + if (blockParentDependantValidationRule == null) { + blockParentDependantValidationRule = factory.blockParentDependantValidationRule( + getRepository(), + getRskSystemProperties(), + getDifficultyCalculator() + ); + } + + return blockParentDependantValidationRule; + } + + private ProofOfWorkRule getProofOfWorkRule() { + if (proofOfWorkRule == null) { + proofOfWorkRule = new ProofOfWorkRule(getRskSystemProperties()); + } + + return proofOfWorkRule; + } + + private DifficultyCalculator getDifficultyCalculator() { + if (difficultyCalculator == null) { + difficultyCalculator = new DifficultyCalculator(getRskSystemProperties()); + } + + return difficultyCalculator; + } + + public CompositeEthereumListener getCompositeEthereumListener() { + if (compositeEthereumListener == null) { + compositeEthereumListener = factory.getCompositeEthereumListener(); + } + + return compositeEthereumListener; + } + + public Genesis getGenesis() { + if (genesis == null) { + genesis = factory.getGenesis(getRskSystemProperties()); + } + + return genesis; + } + + public Repository getRepository() { + if (repository == null) { + repository = factory.repository(getRskSystemProperties()); + } + + return repository; + } + + public BlockStore getBlockStore() { + if (blockStore == null) { + blockStore = factory.blockStore(getRskSystemProperties()); + } + + return blockStore; + } + + public RskSystemProperties getRskSystemProperties() { + if (rskSystemProperties == null) { + rskSystemProperties = factory.rskSystemProperties(cliArgs); + } + + return rskSystemProperties; + } +} diff --git a/rskj-core/src/main/java/co/rsk/blocks/BlockPlayer.java b/rskj-core/src/main/java/co/rsk/blocks/BlockPlayer.java deleted file mode 100644 index 242d01c19b9..00000000000 --- a/rskj-core/src/main/java/co/rsk/blocks/BlockPlayer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of RskJ - * Copyright (C) 2017 RSK Labs Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package co.rsk.blocks; - -import org.ethereum.core.Block; - -/** - * Created by ajlopez on 5/8/2016. - */ -public interface BlockPlayer { - Block readBlock(); -} diff --git a/rskj-core/src/main/java/co/rsk/blocks/FileBlockPlayer.java b/rskj-core/src/main/java/co/rsk/blocks/FileBlockPlayer.java deleted file mode 100644 index 72841a26e7b..00000000000 --- a/rskj-core/src/main/java/co/rsk/blocks/FileBlockPlayer.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of RskJ - * Copyright (C) 2017 RSK Labs Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package co.rsk.blocks; - -import co.rsk.config.RskSystemProperties; -import org.ethereum.core.Block; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.bouncycastle.util.encoders.Hex; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; - -/** - * Created by ajlopez on 5/8/2016. - */ -public class FileBlockPlayer implements BlockPlayer, AutoCloseable { - private static final Logger logger = LoggerFactory.getLogger("blockplayer"); - private BufferedReader reader; - private FileReader freader; - private final RskSystemProperties config; - - public FileBlockPlayer(RskSystemProperties config, String filename) { - this.config = config; - try { - this.freader = new FileReader(filename); - this.reader = new BufferedReader(this.freader); - } - catch (IOException ex) { - logger.error("Exception opening file block player", ex); - } - } - - public Block readBlock() { - try { - String line = this.reader.readLine(); - - if (line == null) { - return null; - } - - String[] parts = line.split(","); - - return new Block(Hex.decode(parts[parts.length - 1])); - } - catch (IOException ex) { - logger.error("Exception reader block", ex); - } - - return null; - } - - @Override - public void close() throws Exception { - if (this.freader != null) { - this.freader.close(); - this.freader = null; - } - } - -} diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index e6c31e3f2c0..52d484bcf85 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -201,10 +201,6 @@ public String blocksRecorder() { return getString("blocks.recorder", null); } - public String blocksPlayer() { - return getString("blocks.player", null); - } - public boolean isFlushEnabled() { return getBoolean("blockchain.flush", true); } diff --git a/rskj-core/src/test/java/co/rsk/blocks/FileBlockPlayerTest.java b/rskj-core/src/test/java/co/rsk/blocks/FileBlockPlayerTest.java deleted file mode 100644 index 6a4472f9a00..00000000000 --- a/rskj-core/src/test/java/co/rsk/blocks/FileBlockPlayerTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of RskJ - * Copyright (C) 2017 RSK Labs Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package co.rsk.blocks; - -import co.rsk.config.TestSystemProperties; -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; - -/** - * Created by ajloopez on 23/01/2017. - */ -public class FileBlockPlayerTest { - @Test - public void createPlayer() throws Exception { - FileBlockRecorder recorder = new FileBlockRecorder("testblocks.txt"); - recorder.close(); - - FileBlockPlayer player = new FileBlockPlayer(new TestSystemProperties(), "testblocks.txt"); - - File file = new File("testblocks.txt"); - Assert.assertTrue(file.exists()); - - Assert.assertNull(player.readBlock()); - - player.close(); - - Assert.assertTrue(file.delete()); - } -} diff --git a/rskj-core/src/test/java/co/rsk/core/SnapshotManagerTest.java b/rskj-core/src/test/java/co/rsk/core/SnapshotManagerTest.java index 63a3c7d1aaf..74a1d0f9c6d 100644 --- a/rskj-core/src/test/java/co/rsk/core/SnapshotManagerTest.java +++ b/rskj-core/src/test/java/co/rsk/core/SnapshotManagerTest.java @@ -19,7 +19,6 @@ package co.rsk.core; import co.rsk.blockchain.utils.BlockGenerator; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.core.bc.BlockChainStatus; import co.rsk.mine.MinerServer; import co.rsk.test.builders.AccountBuilder; @@ -40,7 +39,7 @@ */ public class SnapshotManagerTest { - private BlockChainImpl blockchain; + private Blockchain blockchain; private Repository repository; private TransactionPool transactionPool; private SnapshotManager manager; diff --git a/rskj-core/src/test/java/co/rsk/core/bc/BlockChainImplTest.java b/rskj-core/src/test/java/co/rsk/core/bc/BlockChainImplTest.java index 62a37e3d069..5e02c31237c 100644 --- a/rskj-core/src/test/java/co/rsk/core/bc/BlockChainImplTest.java +++ b/rskj-core/src/test/java/co/rsk/core/bc/BlockChainImplTest.java @@ -950,7 +950,7 @@ private static BlockChainImpl createBlockChain(Repository repository, IndexedBlo ))); } - public static Block getGenesisBlock(BlockChainImpl blockChain) { + public static Block getGenesisBlock(Blockchain blockChain) { Repository repository = blockChain.getRepository(); Genesis genesis = GenesisLoader.loadGenesis("rsk-unittests.json", BigInteger.ZERO, true); diff --git a/rskj-core/src/test/java/co/rsk/core/bc/SelectionRuleTest.java b/rskj-core/src/test/java/co/rsk/core/bc/SelectionRuleTest.java index edc90c576da..dad3716f474 100644 --- a/rskj-core/src/test/java/co/rsk/core/bc/SelectionRuleTest.java +++ b/rskj-core/src/test/java/co/rsk/core/bc/SelectionRuleTest.java @@ -43,7 +43,7 @@ public void addBlockTest() { //Low hash is proved in smallerBlockHashTest } - private static BlockChainImpl createBlockchain() { + private static Blockchain createBlockchain() { RskTestFactory factory = new RskTestFactory(); return factory.getBlockchain(); } diff --git a/rskj-core/src/test/java/co/rsk/core/bc/TransactionPoolImplTest.java b/rskj-core/src/test/java/co/rsk/core/bc/TransactionPoolImplTest.java index c8a70599ee1..abf6886ccc8 100644 --- a/rskj-core/src/test/java/co/rsk/core/bc/TransactionPoolImplTest.java +++ b/rskj-core/src/test/java/co/rsk/core/bc/TransactionPoolImplTest.java @@ -45,7 +45,7 @@ public class TransactionPoolImplTest { private static final TestSystemProperties config = new TestSystemProperties(); private TransactionPoolImpl transactionPool; - private BlockChainImpl blockChain; + private Blockchain blockChain; @Before public void setUp() { diff --git a/rskj-core/src/test/java/co/rsk/mine/MainNetMinerTest.java b/rskj-core/src/test/java/co/rsk/mine/MainNetMinerTest.java index 79d239bb1ad..7c41f08d361 100644 --- a/rskj-core/src/test/java/co/rsk/mine/MainNetMinerTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/MainNetMinerTest.java @@ -8,15 +8,11 @@ import co.rsk.core.bc.BlockChainImpl; import co.rsk.core.bc.BlockChainImplTest; import co.rsk.net.NodeBlockProcessor; -import co.rsk.peg.Federation; import co.rsk.test.builders.BlockChainBuilder; import co.rsk.validators.BlockUnclesValidationRule; import co.rsk.validators.ProofOfWorkRule; import org.ethereum.config.blockchain.FallbackMainNetConfig; -import org.ethereum.core.Genesis; -import org.ethereum.core.ImportResult; -import org.ethereum.core.Repository; -import org.ethereum.core.TransactionPool; +import org.ethereum.core.*; import org.ethereum.db.BlockStore; import org.ethereum.facade.EthereumImpl; import org.ethereum.util.RskTestFactory; @@ -37,7 +33,7 @@ * Created by SerAdmin on 1/3/2018. */ public class MainNetMinerTest { - private BlockChainImpl blockchain; + private Blockchain blockchain; @Rule public TemporaryFolder folder = new TemporaryFolder(); diff --git a/rskj-core/src/test/java/co/rsk/mine/MinerManagerTest.java b/rskj-core/src/test/java/co/rsk/mine/MinerManagerTest.java index 448bb63e5df..3e9f1393b7f 100644 --- a/rskj-core/src/test/java/co/rsk/mine/MinerManagerTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/MinerManagerTest.java @@ -23,12 +23,12 @@ import co.rsk.core.DifficultyCalculator; import co.rsk.core.RskImpl; import co.rsk.core.SnapshotManager; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.validators.BlockValidationRule; import co.rsk.validators.ProofOfWorkRule; import org.awaitility.Awaitility; import org.awaitility.Duration; import org.ethereum.core.Block; +import org.ethereum.core.Blockchain; import org.ethereum.core.Repository; import org.ethereum.core.TransactionPool; import org.ethereum.db.BlockStore; @@ -49,7 +49,7 @@ public class MinerManagerTest { private static final TestSystemProperties config = new TestSystemProperties(); - private BlockChainImpl blockchain; + private Blockchain blockchain; private TransactionPool transactionPool; private Repository repository; private BlockStore blockStore; diff --git a/rskj-core/src/test/java/co/rsk/mine/MinerServerTest.java b/rskj-core/src/test/java/co/rsk/mine/MinerServerTest.java index 220a5dfa7cc..bd5c18a9fb1 100644 --- a/rskj-core/src/test/java/co/rsk/mine/MinerServerTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/MinerServerTest.java @@ -25,7 +25,6 @@ import co.rsk.config.TestSystemProperties; import co.rsk.core.Coin; import co.rsk.core.DifficultyCalculator; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.crypto.Keccak256; import co.rsk.remasc.RemascTransaction; import co.rsk.validators.BlockUnclesValidationRule; @@ -60,7 +59,7 @@ public class MinerServerTest extends ParameterizedNetworkUpgradeTest { private final DifficultyCalculator difficultyCalculator; - private BlockChainImpl blockchain; + private Blockchain blockchain; private Repository repository; private BlockStore blockStore; private TransactionPool transactionPool; diff --git a/rskj-core/src/test/java/co/rsk/test/builders/AccountBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/AccountBuilder.java index cae3bfe792a..a0f7ec47c84 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/AccountBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/AccountBuilder.java @@ -20,10 +20,10 @@ import co.rsk.core.BlockDifficulty; import co.rsk.core.Coin; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.test.World; import org.ethereum.core.Account; import org.ethereum.core.Block; +import org.ethereum.core.Blockchain; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; @@ -35,7 +35,7 @@ public class AccountBuilder { private String name; private Coin balance; private byte[] code; - private BlockChainImpl blockChain; + private Blockchain blockChain; public AccountBuilder() { } @@ -44,7 +44,7 @@ public AccountBuilder(World world) { this(world.getBlockChain()); } - public AccountBuilder(BlockChainImpl blockChain) { + public AccountBuilder(Blockchain blockChain) { this.blockChain = blockChain; } diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BlockBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BlockBuilder.java index 69619b9c7b2..d5c3e19075c 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BlockBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BlockBuilder.java @@ -20,14 +20,10 @@ import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.TestSystemProperties; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.core.bc.BlockExecutor; import co.rsk.test.World; -import org.ethereum.core.Block; -import org.ethereum.core.BlockHeader; -import org.ethereum.core.Transaction; import org.bouncycastle.util.BigIntegers; -import org.ethereum.core.TransactionExecutor; +import org.ethereum.core.*; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; @@ -38,7 +34,7 @@ * Created by ajlopez on 8/6/2016. */ public class BlockBuilder { - private BlockChainImpl blockChain; + private Blockchain blockChain; private final BlockGenerator blockGenerator; private Block parent; private long difficulty; @@ -55,11 +51,11 @@ public BlockBuilder(World world) { this(world.getBlockChain(), new BlockGenerator()); } - public BlockBuilder(BlockChainImpl blockChain) { + public BlockBuilder(Blockchain blockChain) { this(blockChain, new BlockGenerator()); } - public BlockBuilder(BlockChainImpl blockChain, BlockGenerator blockGenerator) { + public BlockBuilder(Blockchain blockChain, BlockGenerator blockGenerator) { this.blockChain = blockChain; this.blockGenerator = blockGenerator; // sane defaults diff --git a/rskj-core/src/test/java/org/ethereum/rpc/LogFilterTest.java b/rskj-core/src/test/java/org/ethereum/rpc/LogFilterTest.java index 39c0c386eb3..f159e0b65e7 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/LogFilterTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/LogFilterTest.java @@ -20,8 +20,8 @@ import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.core.RskAddress; -import co.rsk.core.bc.BlockChainImpl; import org.ethereum.core.Block; +import org.ethereum.core.Blockchain; import org.ethereum.util.RskTestFactory; import org.junit.Assert; import org.junit.Test; @@ -56,7 +56,7 @@ public void noEventsAfterEmptyBlock() { @Test public void eventAfterBlockWithEvent() { - BlockChainImpl blockchain = new RskTestFactory().getBlockchain(); + Blockchain blockchain = new RskTestFactory().getBlockchain(); Web3ImplLogsTest.addEmptyBlockToBlockchain(blockchain); Block block = blockchain.getBestBlock(); @@ -74,7 +74,7 @@ public void eventAfterBlockWithEvent() { @Test public void twoEventsAfterTwoBlocksWithEventAndToLatestBlock() { - BlockChainImpl blockchain = new RskTestFactory().getBlockchain(); + Blockchain blockchain = new RskTestFactory().getBlockchain(); Web3ImplLogsTest.addEmptyBlockToBlockchain(blockchain); Block block = blockchain.getBestBlock(); @@ -93,7 +93,7 @@ public void twoEventsAfterTwoBlocksWithEventAndToLatestBlock() { @Test public void onlyOneEventAfterTwoBlocksWithEventAndFromLatestBlock() { - BlockChainImpl blockchain = new RskTestFactory().getBlockchain(); + Blockchain blockchain = new RskTestFactory().getBlockchain(); Web3ImplLogsTest.addEmptyBlockToBlockchain(blockchain); Block block = blockchain.getBestBlock(); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java index 15989b4e473..09bac164764 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java @@ -23,7 +23,6 @@ import co.rsk.core.RskImpl; import co.rsk.core.Wallet; import co.rsk.core.WalletFactory; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.rpc.ExecutionBlockRetriever; import co.rsk.rpc.Web3RskImpl; import co.rsk.rpc.modules.debug.DebugModule; @@ -38,6 +37,7 @@ import co.rsk.test.builders.AccountBuilder; import co.rsk.test.builders.BlockBuilder; import co.rsk.test.builders.TransactionBuilder; +import org.bouncycastle.util.encoders.Hex; import org.ethereum.core.*; import org.ethereum.db.ReceiptStore; import org.ethereum.rpc.Simples.SimpleConfigCapabilities; @@ -46,7 +46,6 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.bouncycastle.util.encoders.Hex; import java.math.BigInteger; import java.util.ArrayList; @@ -86,7 +85,7 @@ public class Web3ImplLogsTest { private final static String INCREMENT_METHOD_SIGNATURE = "371303c0"; private final static String GET_VALUE_METHOD_SIGNATURE = "20965255"; private final TestSystemProperties config = new TestSystemProperties(); - private BlockChainImpl blockChain; + private Blockchain blockChain; private TransactionPool transactionPool; private RskImpl eth; private ReceiptStore receiptStore; @@ -753,7 +752,7 @@ private void addEventInContractCreation() { web3.personal_newAccountWithSeed("notDefault"); } - public static void addEmptyBlockToBlockchain(BlockChainImpl blockChain) { + public static void addEmptyBlockToBlockchain(Blockchain blockChain) { Account acc1 = new AccountBuilder(blockChain).name("notDefault").balance(Coin.valueOf(10000000)).build(); Block genesis = blockChain.getBlockByNumber(0); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplSnapshotTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplSnapshotTest.java index 0a466c22d28..7bff86bb620 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplSnapshotTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplSnapshotTest.java @@ -22,7 +22,6 @@ import co.rsk.config.ConfigUtils; import co.rsk.config.TestSystemProperties; import co.rsk.core.DifficultyCalculator; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.core.bc.BlockChainStatus; import co.rsk.mine.*; import co.rsk.rpc.modules.debug.DebugModule; @@ -53,7 +52,7 @@ public class Web3ImplSnapshotTest { private static final TestSystemProperties config = new TestSystemProperties(); private RskTestFactory factory; - private BlockChainImpl blockchain; + private Blockchain blockchain; @Before public void setUp() { diff --git a/rskj-core/src/test/java/org/ethereum/util/ContractRunner.java b/rskj-core/src/test/java/org/ethereum/util/ContractRunner.java index a95d290ff5b..13b7e805945 100644 --- a/rskj-core/src/test/java/org/ethereum/util/ContractRunner.java +++ b/rskj-core/src/test/java/org/ethereum/util/ContractRunner.java @@ -5,7 +5,6 @@ import co.rsk.config.TestSystemProperties; import co.rsk.core.Coin; import co.rsk.core.RskAddress; -import co.rsk.core.bc.BlockChainImpl; import co.rsk.test.builders.AccountBuilder; import co.rsk.test.builders.BlockBuilder; import co.rsk.test.builders.TransactionBuilder; @@ -25,7 +24,7 @@ */ public class ContractRunner { private final Repository repository; - private final BlockChainImpl blockchain; + private final Blockchain blockchain; private final BlockStore blockStore; private final ReceiptStore receiptStore; @@ -40,7 +39,7 @@ public ContractRunner(RskTestFactory factory) { } private ContractRunner(Repository repository, - BlockChainImpl blockchain, + Blockchain blockchain, BlockStore blockStore, ReceiptStore receiptStore) { this.blockchain = blockchain; diff --git a/rskj-core/src/test/java/org/ethereum/util/RskTestFactory.java b/rskj-core/src/test/java/org/ethereum/util/RskTestFactory.java index 56eb9552aca..82e380d10a7 100644 --- a/rskj-core/src/test/java/org/ethereum/util/RskTestFactory.java +++ b/rskj-core/src/test/java/org/ethereum/util/RskTestFactory.java @@ -1,198 +1,123 @@ package org.ethereum.util; +import co.rsk.RskContext; import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.RskSystemProperties; import co.rsk.config.TestSystemProperties; -import co.rsk.core.Coin; import co.rsk.core.ReversibleTransactionExecutor; -import co.rsk.core.RskAddress; import co.rsk.core.RskImpl; -import co.rsk.core.bc.BlockChainImpl; -import co.rsk.core.bc.BlockExecutor; -import co.rsk.core.bc.TransactionPoolImpl; import co.rsk.db.RepositoryImpl; -import org.ethereum.db.TrieStorePoolOnMemory; import co.rsk.net.BlockNodeInformation; import co.rsk.net.BlockSyncService; import co.rsk.net.NodeBlockProcessor; import co.rsk.net.sync.SyncConfiguration; -import co.rsk.test.builders.AccountBuilder; -import co.rsk.test.builders.TransactionBuilder; import co.rsk.trie.Trie; import co.rsk.trie.TrieStoreImpl; +import co.rsk.validators.BlockValidator; import co.rsk.validators.DummyBlockValidator; -import org.ethereum.core.*; +import org.ethereum.core.Genesis; +import org.ethereum.core.Repository; import org.ethereum.core.genesis.GenesisLoader; import org.ethereum.datasource.HashMapDB; import org.ethereum.db.*; import org.ethereum.listener.CompositeEthereumListener; -import org.ethereum.listener.EthereumListenerAdapter; import org.ethereum.listener.TestCompositeEthereumListener; -import org.ethereum.vm.PrecompiledContracts; -import org.ethereum.vm.program.ProgramResult; -import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl; -import java.math.BigInteger; import java.util.HashMap; /** - * This is the test version of {@link co.rsk.core.RskFactory}, but without Spring. + * This is the test version of {@link RskContext}. * * We try to recreate the objects used in production as best as we can, * replacing persistent storage with in-memory storage. * There are many nulls in place of objects that aren't part of our * tests yet. */ -public class RskTestFactory { +public class RskTestFactory extends RskContext { private final TestSystemProperties config; - private BlockChainImpl blockchain; + private IndexedBlockStore blockStore; - private TransactionPool transactionPool; private RepositoryImpl repository; - private ProgramInvokeFactoryImpl programInvokeFactory; private ReversibleTransactionExecutor reversibleTransactionExecutor; private NodeBlockProcessor blockProcessor; private RskImpl rskImpl; private CompositeEthereumListener compositeEthereumListener; private ReceiptStoreImpl receiptStore; + private DummyBlockValidator blockValidator; + private Genesis genesis; public RskTestFactory() { this(new TestSystemProperties()); } public RskTestFactory(TestSystemProperties config) { + super(new String[0]); this.config = config; - Genesis genesis = new BlockGenerator().getGenesisBlock(); - genesis.setStateRoot(getRepository().getRoot()); - genesis.flushRLP(); - BlockChainImpl blockchain = getBlockchain(); - blockchain.setStatus(genesis, genesis.getCumulativeDifficulty()); } - public static Genesis getGenesisInstance(RskSystemProperties config) { - return GenesisLoader.loadGenesis(config.genesisInfo(), config.getBlockchainConfig().getCommonConstants().getInitialNonce(), false); + @Override + public RskSystemProperties getRskSystemProperties() { + return config; } - public ProgramResult executeRawContract(byte[] bytecode, byte[] encodedCall, BigInteger value) { - Account sender = new AccountBuilder(getBlockchain()) - .name("sender") - // a large balance will allow running any contract - .balance(Coin.valueOf(10000000L)) - .build(); - BigInteger nonceCreate = getRepository().getNonce(sender.getAddress()); - Transaction creationTx = new TransactionBuilder() - .gasLimit(BigInteger.valueOf(3000000)) - .sender(sender) - .data(bytecode) - .nonce(nonceCreate.longValue()) - .build(); - executeTransaction(creationTx); - BigInteger nonceExecute = getRepository().getNonce(sender.getAddress()); - Transaction transaction = new TransactionBuilder() - // a large gas limit will allow running any contract - .gasLimit(BigInteger.valueOf(3000000)) - .sender(sender) - .receiverAddress(creationTx.getContractAddress().getBytes()) - .data(encodedCall) - .nonce(nonceExecute.longValue()) - .value(value) - .build(); - return executeTransaction(transaction).getResult(); + @Override + public BlockValidator getBlockValidator() { + if (blockValidator == null) { + blockValidator = new DummyBlockValidator(); + } + + return blockValidator; } - private TransactionExecutor executeTransaction(Transaction transaction) { - Repository track = getRepository().startTracking(); - TransactionExecutor executor = new TransactionExecutor( - transaction, - 0, - RskAddress.nullAddress(), - getRepository(), - getBlockStore(), - getReceiptStore(), - getProgramInvokeFactory(), - getBlockchain().getBestBlock(), - new EthereumListenerAdapter(), - 0, - config.getVmConfig(), - config.getBlockchainConfig(), - config.playVM(), - config.isRemascEnabled(), - config.vmTrace(), - new PrecompiledContracts(config), - config.databaseDir(), - config.vmTraceDir(), - config.vmTraceCompressed() - ); - executor.init(); - executor.execute(); - executor.go(); - executor.finalization(); - track.commit(); - return executor; + @Override + public ReceiptStore getReceiptStore() { + if (receiptStore == null) { + receiptStore = new ReceiptStoreImpl(new HashMapDB()); + } + + return receiptStore; } - private ProgramInvokeFactoryImpl getProgramInvokeFactory() { - if (programInvokeFactory == null) { - programInvokeFactory = new ProgramInvokeFactoryImpl(); + @Override + public BlockStore getBlockStore() { + if (blockStore == null) { + blockStore = new IndexedBlockStore(new HashMap<>(), new HashMapDB(), null); } - return programInvokeFactory; + return blockStore; } - public BlockChainImpl getBlockchain() { - if (blockchain == null) { - final ProgramInvokeFactoryImpl programInvokeFactory1 = new ProgramInvokeFactoryImpl(); - blockchain = new BlockChainImpl( - getRepository(), - getBlockStore(), - getReceiptStore(), - getTransactionPool(), - getCompositeEthereumListener(), - new DummyBlockValidator(), - false, - 1, - new BlockExecutor(getRepository(), (tx, txindex, coinbase, repository, block, totalGasUsed) -> new TransactionExecutor( - tx, - txindex, - block.getCoinbase(), - repository, - getBlockStore(), - getReceiptStore(), - programInvokeFactory1, - block, - getCompositeEthereumListener(), - totalGasUsed, - config.getVmConfig(), - config.getBlockchainConfig(), - config.playVM(), - config.isRemascEnabled(), - config.vmTrace(), - new PrecompiledContracts(config), - config.databaseDir(), - config.vmTraceDir(), - config.vmTraceCompressed() - )) + @Override + public Repository getRepository() { + if (repository == null) { + HashMapDB stateStore = new HashMapDB(); + repository = new RepositoryImpl( + new Trie(new TrieStoreImpl(stateStore), true), + new HashMapDB(), + new TrieStorePoolOnMemory(), + getRskSystemProperties().detailsInMemoryStorageLimit() ); } - return blockchain; + return repository; } - public ReceiptStore getReceiptStore() { - if (receiptStore == null) { - HashMapDB inMemoryStore = new HashMapDB(); - receiptStore = new ReceiptStoreImpl(inMemoryStore); + @Override + public CompositeEthereumListener getCompositeEthereumListener() { + if (compositeEthereumListener == null) { + compositeEthereumListener = new TestCompositeEthereumListener(); } - return receiptStore; + return compositeEthereumListener; } - public BlockStore getBlockStore() { - if (blockStore == null) { - this.blockStore = new IndexedBlockStore(new HashMap<>(), new HashMapDB(), null); + @Override + public Genesis getGenesis() { + if (genesis == null) { + genesis = new BlockGenerator().getGenesisBlock(); } - return blockStore; + return genesis; } public NodeBlockProcessor getBlockProcessor() { @@ -200,41 +125,29 @@ public NodeBlockProcessor getBlockProcessor() { co.rsk.net.BlockStore store = new co.rsk.net.BlockStore(); BlockNodeInformation nodeInformation = new BlockNodeInformation(); SyncConfiguration syncConfiguration = SyncConfiguration.IMMEDIATE_FOR_TESTING; - BlockSyncService blockSyncService = new BlockSyncService(config, store, getBlockchain(), nodeInformation, syncConfiguration); - this.blockProcessor = new NodeBlockProcessor(store, getBlockchain(), nodeInformation, blockSyncService, syncConfiguration); - } - - return blockProcessor; - } - - public TransactionPool getTransactionPool() { - if (transactionPool == null) { - transactionPool = new TransactionPoolImpl( - getBlockStore(), - getReceiptStore(), - getCompositeEthereumListener(), - getProgramInvokeFactory(), - getRepository(), - config + BlockSyncService blockSyncService = new BlockSyncService( + getRskSystemProperties(), + store, + getBlockchain(), + nodeInformation, + syncConfiguration + ); + blockProcessor = new NodeBlockProcessor( + store, + getBlockchain(), + nodeInformation, + blockSyncService, + syncConfiguration ); } - return transactionPool; - } - - public Repository getRepository() { - if (repository == null) { - HashMapDB stateStore = new HashMapDB(); - repository = new RepositoryImpl(new Trie(new TrieStoreImpl(stateStore), true), new HashMapDB(), new TrieStorePoolOnMemory(), config.detailsInMemoryStorageLimit()); - } - - return repository; + return blockProcessor; } public ReversibleTransactionExecutor getReversibleTransactionExecutor() { if (reversibleTransactionExecutor == null) { reversibleTransactionExecutor = new ReversibleTransactionExecutor( - config, + getRskSystemProperties(), getRepository(), getBlockStore(), getReceiptStore(), @@ -259,11 +172,7 @@ public RskImpl getRskImpl() { return rskImpl; } - private CompositeEthereumListener getCompositeEthereumListener() { - if (compositeEthereumListener == null) { - compositeEthereumListener = new TestCompositeEthereumListener(); - } - - return compositeEthereumListener; + public static Genesis getGenesisInstance(RskSystemProperties config) { + return GenesisLoader.loadGenesis(config.genesisInfo(), config.getBlockchainConfig().getCommonConstants().getInitialNonce(), false); } }