Skip to content

Commit

Permalink
Add block replayer from existing database (blockstore)
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioDemianLerner authored and colltoaction committed Mar 25, 2019
1 parent 6402db4 commit f6d3e12
Show file tree
Hide file tree
Showing 21 changed files with 407 additions and 389 deletions.
81 changes: 81 additions & 0 deletions rskj-core/src/main/java/co/rsk/BlockstoreBlockPlayer.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

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 [<node cli args>] <block store source dir>");
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);
}
}
39 changes: 6 additions & 33 deletions rskj-core/src/main/java/co/rsk/FullNodeRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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())) {
Expand Down Expand Up @@ -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);
}
}
}
}
225 changes: 225 additions & 0 deletions rskj-core/src/main/java/co/rsk/RskContext.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

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<NodeCliOptions, NodeCliFlags> 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<NodeCliOptions, NodeCliFlags> 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;
}
}
Loading

0 comments on commit f6d3e12

Please sign in to comment.