Coverage Summary for Class: RskContext (co.rsk)
Class |
Class, %
|
Method, %
|
Line, %
|
RskContext |
0%
(0/1)
|
0%
(0/121)
|
0%
(0/808)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2019 RSK Labs Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package co.rsk;
20
21 import co.rsk.bitcoinj.core.NetworkParameters;
22 import co.rsk.cli.CliArgs;
23 import co.rsk.config.*;
24 import co.rsk.core.*;
25 import co.rsk.core.bc.*;
26 import co.rsk.crypto.Keccak256;
27 import co.rsk.db.MapDBBlocksIndex;
28 import co.rsk.db.RepositoryLocator;
29 import co.rsk.db.StateRootHandler;
30 import co.rsk.db.importer.BootstrapImporter;
31 import co.rsk.db.importer.BootstrapURLProvider;
32 import co.rsk.db.importer.provider.BootstrapDataProvider;
33 import co.rsk.db.importer.provider.BootstrapDataVerifier;
34 import co.rsk.db.importer.provider.BootstrapFileHandler;
35 import co.rsk.db.importer.provider.Unzipper;
36 import co.rsk.db.importer.provider.index.BootstrapIndexCandidateSelector;
37 import co.rsk.db.importer.provider.index.BootstrapIndexRetriever;
38 import co.rsk.logfilter.BlocksBloomService;
39 import co.rsk.logfilter.BlocksBloomStore;
40 import co.rsk.metrics.BlockHeaderElement;
41 import co.rsk.metrics.HashRateCalculator;
42 import co.rsk.metrics.HashRateCalculatorMining;
43 import co.rsk.metrics.HashRateCalculatorNonMining;
44 import co.rsk.mine.*;
45 import co.rsk.net.*;
46 import co.rsk.net.discovery.PeerExplorer;
47 import co.rsk.net.discovery.UDPServer;
48 import co.rsk.net.discovery.table.KademliaOptions;
49 import co.rsk.net.discovery.table.NodeDistanceTable;
50 import co.rsk.net.eth.MessageFilter;
51 import co.rsk.net.eth.MessageRecorder;
52 import co.rsk.net.eth.RskWireProtocol;
53 import co.rsk.net.eth.WriterMessageRecorder;
54 import co.rsk.net.sync.PeersInformation;
55 import co.rsk.net.sync.SyncConfiguration;
56 import co.rsk.peg.BridgeSupportFactory;
57 import co.rsk.peg.BtcBlockStoreWithCache;
58 import co.rsk.peg.RepositoryBtcBlockStoreWithCache;
59 import co.rsk.rpc.*;
60 import co.rsk.rpc.modules.debug.DebugModule;
61 import co.rsk.rpc.modules.debug.DebugModuleImpl;
62 import co.rsk.rpc.modules.eth.*;
63 import co.rsk.rpc.modules.eth.subscribe.BlockHeaderNotificationEmitter;
64 import co.rsk.rpc.modules.eth.subscribe.LogsNotificationEmitter;
65 import co.rsk.rpc.modules.evm.EvmModule;
66 import co.rsk.rpc.modules.evm.EvmModuleImpl;
67 import co.rsk.rpc.modules.mnr.MnrModule;
68 import co.rsk.rpc.modules.mnr.MnrModuleImpl;
69 import co.rsk.rpc.modules.personal.PersonalModule;
70 import co.rsk.rpc.modules.personal.PersonalModuleWalletDisabled;
71 import co.rsk.rpc.modules.personal.PersonalModuleWalletEnabled;
72 import co.rsk.rpc.modules.rsk.RskModule;
73 import co.rsk.rpc.modules.rsk.RskModuleImpl;
74 import co.rsk.rpc.modules.trace.TraceModule;
75 import co.rsk.rpc.modules.trace.TraceModuleImpl;
76 import co.rsk.rpc.modules.txpool.TxPoolModule;
77 import co.rsk.rpc.modules.txpool.TxPoolModuleImpl;
78 import co.rsk.rpc.netty.*;
79 import co.rsk.scoring.PeerScoring;
80 import co.rsk.scoring.PeerScoringManager;
81 import co.rsk.scoring.PeerScoringReporterService;
82 import co.rsk.scoring.PunishmentParameters;
83 import co.rsk.trie.MultiTrieStore;
84 import co.rsk.trie.TrieConverter;
85 import co.rsk.trie.TrieStore;
86 import co.rsk.trie.TrieStoreImpl;
87 import co.rsk.util.RskCustomCache;
88 import co.rsk.validators.*;
89 import com.fasterxml.jackson.databind.ObjectMapper;
90 import org.ethereum.config.Constants;
91 import org.ethereum.config.blockchain.upgrades.ActivationConfig;
92 import org.ethereum.config.blockchain.upgrades.ConsensusRule;
93 import org.ethereum.core.*;
94 import org.ethereum.core.genesis.BlockChainLoader;
95 import org.ethereum.core.genesis.GenesisLoader;
96 import org.ethereum.core.genesis.GenesisLoaderImpl;
97 import org.ethereum.crypto.ECKey;
98 import org.ethereum.crypto.signature.Secp256k1;
99 import org.ethereum.datasource.DataSourceWithCache;
100 import org.ethereum.datasource.KeyValueDataSource;
101 import org.ethereum.datasource.LevelDbDataSource;
102 import org.ethereum.db.IndexedBlockStore;
103 import org.ethereum.db.ReceiptStore;
104 import org.ethereum.db.ReceiptStoreImpl;
105 import org.ethereum.facade.Ethereum;
106 import org.ethereum.facade.EthereumImpl;
107 import org.ethereum.listener.CompositeEthereumListener;
108 import org.ethereum.net.EthereumChannelInitializerFactory;
109 import org.ethereum.net.NodeManager;
110 import org.ethereum.net.client.ConfigCapabilities;
111 import org.ethereum.net.client.ConfigCapabilitiesImpl;
112 import org.ethereum.net.client.PeerClient;
113 import org.ethereum.net.eth.message.Eth62MessageFactory;
114 import org.ethereum.net.message.StaticMessages;
115 import org.ethereum.net.rlpx.Node;
116 import org.ethereum.net.server.*;
117 import org.ethereum.rpc.Web3;
118 import org.ethereum.solidity.compiler.SolidityCompiler;
119 import org.ethereum.sync.SyncPool;
120 import org.ethereum.util.BuildInfo;
121 import org.ethereum.util.FileUtil;
122 import org.ethereum.vm.PrecompiledContracts;
123 import org.ethereum.vm.program.invoke.ProgramInvokeFactory;
124 import org.ethereum.vm.program.invoke.ProgramInvokeFactoryImpl;
125 import org.mapdb.DB;
126 import org.mapdb.DBMaker;
127 import org.slf4j.Logger;
128 import org.slf4j.LoggerFactory;
129
130 import java.io.*;
131 import java.net.InetSocketAddress;
132 import java.nio.charset.StandardCharsets;
133 import java.nio.file.Files;
134 import java.nio.file.Path;
135 import java.nio.file.Paths;
136 import java.time.Clock;
137 import java.util.*;
138 import java.util.stream.Collectors;
139 import java.util.stream.Stream;
140
141 /**
142 * Creates the initial object graph without a DI framework.
143 * <p>
144 * When an object construction has to be tweaked, create a buildXXX method and call it from getXXX.
145 * This way derived classes don't have to store their own instances.
146 * <p>
147 * Note that many methods are public to allow the fed node overriding.
148 */
149 public class RskContext implements NodeBootstrapper {
150 private static Logger logger = LoggerFactory.getLogger(RskContext.class);
151
152 private final CliArgs<NodeCliOptions, NodeCliFlags> cliArgs;
153
154 private RskSystemProperties rskSystemProperties;
155 private Blockchain blockchain;
156 private MiningMainchainView miningMainchainView;
157 private ConsensusValidationMainchainView consensusValidationMainchainView;
158 private BlockFactory blockFactory;
159 private BlockChainLoader blockChainLoader;
160 private org.ethereum.db.BlockStore blockStore;
161 private NetBlockStore netBlockStore;
162 private TrieStore trieStore;
163 private GenesisLoader genesisLoader;
164 private Genesis genesis;
165 private CompositeEthereumListener compositeEthereumListener;
166 private DifficultyCalculator difficultyCalculator;
167 private ForkDetectionDataCalculator forkDetectionDataCalculator;
168 private ProofOfWorkRule proofOfWorkRule;
169 private ForkDetectionDataRule forkDetectionDataRule;
170 private BlockParentDependantValidationRule blockParentDependantValidationRule;
171 private BlockValidationRule blockValidationRule;
172 private BlockValidationRule minerServerBlockValidationRule;
173 private BlockValidator blockValidator;
174 private BlockValidator blockHeaderValidator;
175 private BlockValidator blockRelayValidator;
176 private ReceiptStore receiptStore;
177 private ProgramInvokeFactory programInvokeFactory;
178 private TransactionPool transactionPool;
179 private RepositoryLocator repositoryLocator;
180 private StateRootHandler stateRootHandler;
181 private TrieConverter trieConverter;
182 private EvmModule evmModule;
183 private BlockToMineBuilder blockToMineBuilder;
184 private BlockNodeInformation blockNodeInformation;
185 private Ethereum rsk;
186 private PeerScoringManager peerScoringManager;
187 private NodeBlockProcessor nodeBlockProcessor;
188 private SyncProcessor syncProcessor;
189 private BlockSyncService blockSyncService;
190 private SyncPool syncPool;
191 private Web3 web3;
192 private JsonRpcWeb3FilterHandler jsonRpcWeb3FilterHandler;
193 private JsonRpcWeb3ServerHandler jsonRpcWeb3ServerHandler;
194 private Web3WebSocketServer web3WebSocketServer;
195 private JacksonBasedRpcSerializer jacksonBasedRpcSerializer;
196 private Web3HttpServer web3HttpServer;
197 private WriterMessageRecorder writerMessageRecorder;
198 private Wallet wallet;
199 private PeerServer peerServer;
200 private PersonalModule personalModule;
201 private EthModuleWallet ethModuleWallet;
202 private EthModuleTransaction ethModuleTransaction;
203 private MinerClient minerClient;
204 private SyncConfiguration syncConfiguration;
205 private TransactionGateway transactionGateway;
206 private BuildInfo buildInfo;
207 private MinerClock minerClock;
208 private MiningConfig miningConfig;
209 private NetworkStateExporter networkStateExporter;
210 private PeerExplorer peerExplorer;
211 private EthereumChannelInitializerFactory ethereumChannelInitializerFactory;
212 private HashRateCalculator hashRateCalculator;
213 private EthModule ethModule;
214 private ChannelManager channelManager;
215 private NodeRunner nodeRunner;
216 private NodeMessageHandler nodeMessageHandler;
217 private ConfigCapabilities configCapabilities;
218 private DebugModule debugModule;
219 private TraceModule traceModule;
220 private MnrModule mnrModule;
221 private TxPoolModule txPoolModule;
222 private RskModule rskModule;
223 private RskWireProtocol.Factory rskWireProtocolFactory;
224 private Eth62MessageFactory eth62MessageFactory;
225 private GasLimitCalculator gasLimitCalculator;
226 private ReversibleTransactionExecutor reversibleTransactionExecutor;
227 private TransactionExecutorFactory transactionExecutorFactory;
228 private ExecutionBlockRetriever executionBlockRetriever;
229 private NodeManager nodeManager;
230 private StaticMessages staticMessages;
231 private MinerServer minerServer;
232 private BlocksBloomStore blocksBloomStore;
233 private KeyValueDataSource blocksBloomDataSource;
234 private BlockExecutor blockExecutor;
235 private BtcBlockStoreWithCache.Factory btcBlockStoreFactory;
236 private PrecompiledContracts precompiledContracts;
237 private BridgeSupportFactory bridgeSupportFactory;
238 private PeersInformation peersInformation;
239 private StatusResolver statusResolver;
240 private Web3InformationRetriever web3InformationRetriever;
241 private BootstrapImporter bootstrapImporter;
242 private ReceivedTxSignatureCache receivedTxSignatureCache;
243 private BlockTxSignatureCache blockTxSignatureCache;
244 private PeerScoringReporterService peerScoringReporterService;
245
246 public RskContext(String[] args) {
247 this(new CliArgs.Parser<>(
248 NodeCliOptions.class,
249 NodeCliFlags.class
250 ).parse(args));
251 }
252
253 private RskContext(CliArgs<NodeCliOptions, NodeCliFlags> cliArgs) {
254 this.cliArgs = cliArgs;
255 initializeSingletons();
256 }
257
258 private void initializeSingletons() {
259 Secp256k1.initialize(getRskSystemProperties());
260 }
261
262 public BootstrapImporter getBootstrapImporter() {
263 if (bootstrapImporter == null) {
264 RskSystemProperties systemProperties = getRskSystemProperties();
265 List<String> publicKeys = systemProperties.importTrustedKeys();
266 int minimumRequired = publicKeys.size() / 2 + 1;
267 if (minimumRequired < 2) {
268 logger.warn("Configuration has less trusted sources than the minimum required {} of 2", minimumRequired);
269 minimumRequired = 2;
270 }
271
272 BootstrapURLProvider bootstrapUrlProvider = new BootstrapURLProvider(systemProperties.importUrl());
273
274 bootstrapImporter = new BootstrapImporter(
275 getBlockStore(),
276 getTrieStore(),
277 blockFactory,
278 new BootstrapDataProvider(
279 new BootstrapDataVerifier(),
280 new BootstrapFileHandler(bootstrapUrlProvider, new Unzipper()),
281 new BootstrapIndexCandidateSelector(publicKeys, minimumRequired),
282 new BootstrapIndexRetriever(publicKeys, bootstrapUrlProvider, new ObjectMapper()),
283 minimumRequired
284 )
285 );
286 }
287 return bootstrapImporter;
288 }
289
290 @Override
291 public NodeRunner getNodeRunner() {
292 if (nodeRunner == null) {
293 RskSystemProperties rskSystemProperties = getRskSystemProperties();
294 if (rskSystemProperties.databaseReset() || rskSystemProperties.importEnabled()) {
295 FileUtil.recursiveDelete(rskSystemProperties.databaseDir());
296 }
297
298 if (rskSystemProperties.importEnabled()) {
299 getBootstrapImporter().importData();
300 }
301
302 nodeRunner = buildNodeRunner();
303 }
304
305 return nodeRunner;
306 }
307
308 public Blockchain getBlockchain() {
309 if (blockchain == null) {
310 blockchain = getBlockChainLoader().loadBlockchain();
311 }
312
313 return blockchain;
314 }
315
316 public MiningMainchainView getMiningMainchainView() {
317 // One would expect getBlockStore to be used here. However, when the BlockStore is created,
318 // it does not have any blocks, resulting in a NullPointerException when trying to initially
319 // fill the mainchain view. Hence why we wait for the blockchain to perform its required
320 // initialization tasks and then we ask for the store
321 getBlockchain();
322 if (miningMainchainView == null) {
323 miningMainchainView = new MiningMainchainViewImpl(
324 getBlockStore(),
325 MiningConfig.REQUIRED_NUMBER_OF_BLOCKS_FOR_FORK_DETECTION_CALCULATION
326 );
327 }
328
329 return miningMainchainView;
330 }
331
332 public ConsensusValidationMainchainView getConsensusValidationMainchainView() {
333 if (consensusValidationMainchainView == null) {
334 consensusValidationMainchainView = new ConsensusValidationMainchainViewImpl(getBlockStore());
335 }
336
337 return consensusValidationMainchainView;
338 }
339
340 public BlockFactory getBlockFactory() {
341 if (blockFactory == null) {
342 blockFactory = new BlockFactory(getRskSystemProperties().getActivationConfig());
343 }
344
345 return blockFactory;
346 }
347
348 public TransactionPool getTransactionPool() {
349 if (transactionPool == null) {
350 RskSystemProperties rskSystemProperties = getRskSystemProperties();
351 transactionPool = new TransactionPoolImpl(
352 rskSystemProperties,
353 getRepositoryLocator(),
354 getBlockStore(),
355 getBlockFactory(),
356 getCompositeEthereumListener(),
357 getTransactionExecutorFactory(),
358 getReceivedTxSignatureCache(),
359 rskSystemProperties.txOutdatedThreshold(),
360 rskSystemProperties.txOutdatedTimeout());
361 }
362
363 return transactionPool;
364 }
365
366 public ReceivedTxSignatureCache getReceivedTxSignatureCache() {
367 if (receivedTxSignatureCache == null) {
368 receivedTxSignatureCache = new ReceivedTxSignatureCache();
369 }
370
371 return receivedTxSignatureCache;
372 }
373
374 private BlockTxSignatureCache getBlockTxSignatureCache() {
375 if (blockTxSignatureCache == null) {
376 blockTxSignatureCache = new BlockTxSignatureCache(getReceivedTxSignatureCache());
377 }
378
379 return blockTxSignatureCache;
380 }
381
382 public RepositoryLocator getRepositoryLocator() {
383 if (repositoryLocator == null) {
384 repositoryLocator = buildRepositoryLocator();
385 }
386
387 return repositoryLocator;
388 }
389
390 public StateRootHandler getStateRootHandler() {
391 if (stateRootHandler == null) {
392 stateRootHandler = buildStateRootHandler();
393 }
394
395 return stateRootHandler;
396 }
397
398 public TrieConverter getTrieConverter() {
399 if (trieConverter == null) {
400 trieConverter = new TrieConverter();
401 }
402
403 return trieConverter;
404 }
405
406 public ReceiptStore getReceiptStore() {
407 if (receiptStore == null) {
408 receiptStore = buildReceiptStore();
409 }
410
411 return receiptStore;
412 }
413
414 public TrieStore getTrieStore() {
415 if (trieStore == null) {
416 trieStore = buildAbstractTrieStore(Paths.get(getRskSystemProperties().databaseDir()));
417 }
418
419 return trieStore;
420 }
421
422 public BlockExecutor getBlockExecutor() {
423 if (blockExecutor == null) {
424 blockExecutor = new BlockExecutor(
425 getRskSystemProperties().getActivationConfig(),
426 getRepositoryLocator(),
427 getStateRootHandler(),
428 getTransactionExecutorFactory()
429 );
430 }
431
432 return blockExecutor;
433 }
434
435 public PrecompiledContracts getPrecompiledContracts() {
436 if (precompiledContracts == null) {
437 precompiledContracts = new PrecompiledContracts(getRskSystemProperties(), getBridgeSupportFactory());
438 }
439
440 return precompiledContracts;
441 }
442
443 public BridgeSupportFactory getBridgeSupportFactory() {
444 if (bridgeSupportFactory == null) {
445 bridgeSupportFactory = new BridgeSupportFactory(getBtcBlockStoreFactory(),
446 getRskSystemProperties().getNetworkConstants().getBridgeConstants(),
447 getRskSystemProperties().getActivationConfig());
448 }
449
450 return bridgeSupportFactory;
451 }
452
453 public BtcBlockStoreWithCache.Factory getBtcBlockStoreFactory() {
454 if (btcBlockStoreFactory == null) {
455 NetworkParameters btcParams = getRskSystemProperties().getNetworkConstants().getBridgeConstants().getBtcParams();
456 btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory(
457 btcParams,
458 getRskSystemProperties().getBtcBlockStoreCacheDepth(),
459 getRskSystemProperties().getBtcBlockStoreCacheSize()
460 );
461 }
462
463 return btcBlockStoreFactory;
464 }
465
466 public org.ethereum.db.BlockStore getBlockStore() {
467 if (blockStore == null) {
468 blockStore = buildBlockStore();
469 }
470
471 return blockStore;
472 }
473
474 public Ethereum getRsk() {
475 if (rsk == null) {
476 rsk = new EthereumImpl(
477 getChannelManager(),
478 getTransactionGateway(),
479 getCompositeEthereumListener(),
480 getBlockchain()
481 );
482 }
483
484 return rsk;
485 }
486
487 public ReversibleTransactionExecutor getReversibleTransactionExecutor() {
488 if (reversibleTransactionExecutor == null) {
489 reversibleTransactionExecutor = new ReversibleTransactionExecutor(
490 getRepositoryLocator(),
491 getTransactionExecutorFactory()
492 );
493 }
494
495 return reversibleTransactionExecutor;
496 }
497
498 public TransactionExecutorFactory getTransactionExecutorFactory() {
499 if (transactionExecutorFactory == null) {
500 transactionExecutorFactory = new TransactionExecutorFactory(
501 getRskSystemProperties(),
502 getBlockStore(),
503 getReceiptStore(),
504 getBlockFactory(),
505 getProgramInvokeFactory(),
506 getPrecompiledContracts(),
507 getBlockTxSignatureCache()
508 );
509 }
510
511 return transactionExecutorFactory;
512 }
513
514 public NodeBlockProcessor getNodeBlockProcessor() {
515 if (nodeBlockProcessor == null) {
516 RskSystemProperties rskSystemProperties = getRskSystemProperties();
517 if (rskSystemProperties.fastBlockPropagation()) {
518 nodeBlockProcessor = new AsyncNodeBlockProcessor(
519 getNetBlockStore(),
520 getBlockchain(),
521 getBlockNodeInformation(),
522 getBlockSyncService(),
523 getSyncConfiguration(),
524 getBlockHeaderValidator(),
525 getBlockRelayValidator()
526 );
527 } else {
528 nodeBlockProcessor = new NodeBlockProcessor(
529 getNetBlockStore(),
530 getBlockchain(),
531 getBlockNodeInformation(),
532 getBlockSyncService(),
533 getSyncConfiguration()
534 );
535 }
536 }
537
538 return nodeBlockProcessor;
539 }
540
541 public RskSystemProperties getRskSystemProperties() {
542 if (rskSystemProperties == null) {
543 rskSystemProperties = buildRskSystemProperties();
544 }
545
546 return rskSystemProperties;
547 }
548
549 public PeerScoringManager getPeerScoringManager() {
550 if (peerScoringManager == null) {
551 RskSystemProperties rskSystemProperties = getRskSystemProperties();
552 peerScoringManager = new PeerScoringManager(
553 () -> new PeerScoring(rskSystemProperties.scoringPunishmentEnabled()),
554 rskSystemProperties.scoringNumberOfNodes(),
555 new PunishmentParameters(
556 rskSystemProperties.scoringNodesPunishmentDuration(),
557 rskSystemProperties.scoringNodesPunishmentIncrement(),
558 rskSystemProperties.scoringNodesPunishmentMaximumDuration()
559 ),
560 new PunishmentParameters(
561 rskSystemProperties.scoringAddressesPunishmentDuration(),
562 rskSystemProperties.scoringAddressesPunishmentIncrement(),
563 rskSystemProperties.scoringAddressesPunishmentMaximumDuration()
564 )
565 );
566 }
567
568 return peerScoringManager;
569 }
570
571 public HashRateCalculator getHashRateCalculator() {
572 if (hashRateCalculator == null) {
573 RskCustomCache<Keccak256, BlockHeaderElement> cache = new RskCustomCache<>(60000L);
574 if (!getRskSystemProperties().isMinerServerEnabled()) {
575 hashRateCalculator = new HashRateCalculatorNonMining(getBlockStore(), cache);
576 } else {
577 RskAddress coinbase = getMiningConfig().getCoinbaseAddress();
578 hashRateCalculator = new HashRateCalculatorMining(getBlockStore(), cache, coinbase);
579 }
580 }
581
582 return hashRateCalculator;
583 }
584
585 public EthModule getEthModule() {
586 if (ethModule == null) {
587 Constants networkConstants = getRskSystemProperties().getNetworkConstants();
588 ethModule = new EthModule(
589 networkConstants.getBridgeConstants(),
590 networkConstants.getChainId(),
591 getBlockchain(),
592 getTransactionPool(),
593 getReversibleTransactionExecutor(),
594 getExecutionBlockRetriever(),
595 getRepositoryLocator(),
596 getEthModuleWallet(),
597 getEthModuleTransaction(),
598 getBridgeSupportFactory()
599 );
600 }
601
602 return ethModule;
603 }
604
605 public EvmModule getEvmModule() {
606 if (evmModule == null) {
607 evmModule = new EvmModuleImpl(
608 getMinerServer(),
609 getMinerClient(),
610 getMinerClock(),
611 new SnapshotManager(getBlockchain(), getBlockStore(), getTransactionPool(), getMinerServer())
612 );
613 }
614
615 return evmModule;
616 }
617
618 public PeerServer getPeerServer() {
619 if (peerServer == null) {
620 peerServer = new PeerServerImpl(
621 getRskSystemProperties(),
622 getCompositeEthereumListener(),
623 getEthereumChannelInitializerFactory()
624 );
625 }
626
627 return peerServer;
628 }
629
630 public PersonalModule getPersonalModule() {
631 if (personalModule == null) {
632 Wallet wallet = getWallet();
633 if (wallet == null) {
634 personalModule = new PersonalModuleWalletDisabled();
635 } else {
636 personalModule = new PersonalModuleWalletEnabled(
637 getRskSystemProperties(),
638 getRsk(),
639 wallet,
640 getTransactionPool()
641 );
642 }
643 }
644
645 return personalModule;
646 }
647
648 public CliArgs<NodeCliOptions, NodeCliFlags> getCliArgs() {
649 return cliArgs;
650 }
651
652 public BuildInfo getBuildInfo() {
653 if (buildInfo == null) {
654 try {
655 Properties props = new Properties();
656 InputStream buildInfoFile = RskContext.class.getClassLoader().getResourceAsStream("build-info.properties");
657 props.load(buildInfoFile);
658 buildInfo = new BuildInfo(props.getProperty("build.hash"), props.getProperty("build.branch"));
659 } catch (IOException | NullPointerException e) {
660 logger.trace("Can't find build info class, using dev configuration", e);
661 buildInfo = new BuildInfo("dev", "dev");
662 }
663 }
664
665 return buildInfo;
666 }
667
668 public ChannelManager getChannelManager() {
669 if (channelManager == null) {
670 channelManager = new ChannelManagerImpl(getRskSystemProperties(), getSyncPool());
671 }
672
673 return channelManager;
674 }
675
676 public ConfigCapabilities getConfigCapabilities() {
677 if (configCapabilities == null) {
678 configCapabilities = new ConfigCapabilitiesImpl(getRskSystemProperties());
679 }
680
681 return configCapabilities;
682 }
683
684 public DebugModule getDebugModule() {
685 if (debugModule == null) {
686 debugModule = new DebugModuleImpl(
687 getBlockStore(),
688 getReceiptStore(),
689 getNodeMessageHandler(),
690 getBlockExecutor()
691 );
692 }
693
694 return debugModule;
695 }
696
697 public TraceModule getTraceModule() {
698 if (traceModule == null) {
699 traceModule = new TraceModuleImpl(
700 getBlockchain(),
701 getBlockStore(),
702 getReceiptStore(),
703 getBlockExecutor()
704 );
705 }
706
707 return traceModule;
708 }
709
710 public MnrModule getMnrModule() {
711 if (mnrModule == null) {
712 mnrModule = new MnrModuleImpl(getMinerServer());
713 }
714
715 return mnrModule;
716 }
717
718 public TxPoolModule getTxPoolModule() {
719 if (txPoolModule == null) {
720 txPoolModule = new TxPoolModuleImpl(getTransactionPool());
721 }
722
723 return txPoolModule;
724 }
725
726 public RskModule getRskModule() {
727 if (rskModule == null) {
728 rskModule = new RskModuleImpl(
729 getBlockchain(),
730 getBlockStore(),
731 getReceiptStore(),
732 getWeb3InformationRetriever());
733 }
734
735 return rskModule;
736 }
737
738 public NetworkStateExporter getNetworkStateExporter() {
739 if (networkStateExporter == null) {
740 networkStateExporter = new NetworkStateExporter(getRepositoryLocator(), getBlockchain());
741 }
742
743 return networkStateExporter;
744 }
745
746 public MinerClient getMinerClient() {
747 if (minerClient == null) {
748 RskSystemProperties rskSystemProperties = getRskSystemProperties();
749 if (rskSystemProperties.minerClientAutoMine()) {
750 minerClient = new AutoMinerClient(getMinerServer());
751 } else {
752 minerClient = new MinerClientImpl(
753 getNodeBlockProcessor(),
754 getMinerServer(),
755 rskSystemProperties.minerClientDelayBetweenBlocks(),
756 rskSystemProperties.minerClientDelayBetweenRefreshes()
757 );
758 }
759 }
760
761 return minerClient;
762 }
763
764 public MinerServer getMinerServer() {
765 if (minerServer == null) {
766 minerServer = new MinerServerImpl(
767 getRskSystemProperties(),
768 getRsk(),
769 getMiningMainchainView(),
770 getNodeBlockProcessor(),
771 getProofOfWorkRule(),
772 getBlockToMineBuilder(),
773 getMinerClock(),
774 getBlockFactory(),
775 getBuildInfo(),
776 getMiningConfig()
777 );
778 }
779
780 return minerServer;
781 }
782
783 public ProgramInvokeFactory getProgramInvokeFactory() {
784 if (programInvokeFactory == null) {
785 programInvokeFactory = new ProgramInvokeFactoryImpl();
786 }
787
788 return programInvokeFactory;
789 }
790
791 public CompositeEthereumListener getCompositeEthereumListener() {
792 if (compositeEthereumListener == null) {
793 compositeEthereumListener = buildCompositeEthereumListener();
794 }
795
796 return compositeEthereumListener;
797 }
798
799 public BlocksBloomStore getBlocksBloomStore() {
800 if (blocksBloomStore == null) {
801 blocksBloomStore = new BlocksBloomStore(getRskSystemProperties().bloomNumberOfBlocks(), getRskSystemProperties().bloomNumberOfConfirmations(), getBlocksBloomDataSource());
802 }
803
804 return blocksBloomStore;
805 }
806
807 private KeyValueDataSource getBlocksBloomDataSource() {
808 if (this.blocksBloomDataSource == null) {
809 this.blocksBloomDataSource = this.buildBlocksBloomDataSource();
810 }
811
812 return this.blocksBloomDataSource;
813 }
814
815 protected KeyValueDataSource buildBlocksBloomDataSource() {
816 return LevelDbDataSource.makeDataSource(Paths.get(getRskSystemProperties().databaseDir(), "blooms"));
817 }
818
819 protected NodeRunner buildNodeRunner() {
820 return new FullNodeRunner(
821 buildInternalServices(),
822 getRskSystemProperties(),
823 getBuildInfo()
824 );
825 }
826
827 public List<InternalService> buildInternalServices() {
828 List<InternalService> internalServices = new ArrayList<>();
829 internalServices.add(getTransactionPool());
830 internalServices.add(getChannelManager());
831 internalServices.add(getNodeMessageHandler());
832 internalServices.add(getPeerServer());
833 boolean rpcHttpEnabled = getRskSystemProperties().isRpcHttpEnabled();
834 boolean rpcWebSocketEnabled = getRskSystemProperties().isRpcWebSocketEnabled();
835 boolean bloomServiceEnabled = getRskSystemProperties().bloomServiceEnabled();
836
837 if (bloomServiceEnabled) {
838 internalServices.add(new BlocksBloomService(getCompositeEthereumListener(), getBlocksBloomStore(), getBlockStore()));
839 }
840
841 if (rpcHttpEnabled || rpcWebSocketEnabled) {
842 internalServices.add(getWeb3());
843 }
844
845 if (rpcHttpEnabled) {
846 internalServices.add(getWeb3HttpServer());
847 }
848
849 if (rpcWebSocketEnabled) {
850 internalServices.add(getWeb3WebSocketServer());
851 }
852
853 if (getRskSystemProperties().isPeerDiscoveryEnabled()) {
854 internalServices.add(new UDPServer(
855 getRskSystemProperties().getBindAddress().getHostAddress(),
856 getRskSystemProperties().getPeerPort(),
857 getPeerExplorer()
858 ));
859 }
860 if (getRskSystemProperties().isSyncEnabled()) {
861 internalServices.add(getSyncPool());
862 }
863
864 if (getRskSystemProperties().isMinerServerEnabled()) {
865 internalServices.add(getMinerServer());
866
867 if (getRskSystemProperties().isMinerClientEnabled()) {
868 internalServices.add(getMinerClient());
869 }
870 }
871
872 internalServices.add(new BlockChainFlusher(
873 getRskSystemProperties().flushNumberOfBlocks(),
874 getCompositeEthereumListener(),
875 getTrieStore(),
876 getBlockStore(),
877 getReceiptStore(),
878 getBlocksBloomStore()));
879
880 NodeBlockProcessor nodeBlockProcessor = getNodeBlockProcessor();
881 if (nodeBlockProcessor instanceof InternalService) {
882 internalServices.add((InternalService) nodeBlockProcessor);
883 }
884
885 GarbageCollectorConfig gcConfig = getRskSystemProperties().garbageCollectorConfig();
886
887 if (gcConfig.enabled()) {
888 internalServices.add(new GarbageCollector(
889 getCompositeEthereumListener(),
890 gcConfig.blocksPerEpoch(),
891 gcConfig.numberOfEpochs(),
892 (MultiTrieStore) getTrieStore(),
893 getBlockStore(),
894 getRepositoryLocator()
895 ));
896 }
897 if(getRskSystemProperties().isPeerScoringStatsReportEnabled()) {
898 internalServices.add(getPeerScoringReporterService());
899 }
900 return Collections.unmodifiableList(internalServices);
901 }
902
903 protected SolidityCompiler buildSolidityCompiler() {
904 return new SolidityCompiler(getRskSystemProperties());
905 }
906
907 private TrieStore buildAbstractTrieStore(Path databasePath) {
908 TrieStore newTrieStore;
909 GarbageCollectorConfig gcConfig = getRskSystemProperties().garbageCollectorConfig();
910 final String multiTrieStoreNamePrefix = "unitrie_";
911 if (gcConfig.enabled()) {
912 try {
913 newTrieStore = buildMultiTrieStore(databasePath, multiTrieStoreNamePrefix, gcConfig.numberOfEpochs());
914 } catch (IOException e) {
915 throw new IllegalStateException("Unable to build multi trie store", e);
916 }
917 } else {
918 Path trieStorePath = databasePath.resolve("unitrie");
919 try (Stream<Path> databasePathFilesStream = Files.list(databasePath)) {
920 List<Path> multiTrieStorePaths = databasePathFilesStream
921 .filter(p -> p.getFileName().toString().startsWith(multiTrieStoreNamePrefix))
922 .collect(Collectors.toList());
923
924 boolean gcWasEnabled = !multiTrieStorePaths.isEmpty();
925 if (gcWasEnabled) {
926 LevelDbDataSource.mergeDataSources(trieStorePath, multiTrieStorePaths);
927 // cleanup MultiTrieStore data sources
928 multiTrieStorePaths.stream()
929 .map(Path::toString)
930 .forEach(FileUtil::recursiveDelete);
931 }
932 } catch (IOException e) {
933 logger.error("Unable to check if GC was ever enabled", e);
934 }
935 newTrieStore = buildTrieStore(trieStorePath);
936 }
937 return newTrieStore;
938 }
939
940 protected Web3 buildWeb3() {
941 return new Web3RskImpl(
942 getRsk(),
943 getBlockchain(),
944 getRskSystemProperties(),
945 getMinerClient(),
946 getMinerServer(),
947 getPersonalModule(),
948 getEthModule(),
949 getEvmModule(),
950 getTxPoolModule(),
951 getMnrModule(),
952 getDebugModule(),
953 getTraceModule(),
954 getRskModule(),
955 getChannelManager(),
956 getPeerScoringManager(),
957 getNetworkStateExporter(),
958 getBlockStore(),
959 getReceiptStore(),
960 getPeerServer(),
961 getNodeBlockProcessor(),
962 getHashRateCalculator(),
963 getConfigCapabilities(),
964 getBuildInfo(),
965 getBlocksBloomStore(),
966 getWeb3InformationRetriever());
967 }
968
969 protected Web3InformationRetriever getWeb3InformationRetriever() {
970 if (web3InformationRetriever == null) {
971 web3InformationRetriever = new Web3InformationRetriever(
972 getTransactionPool(),
973 getBlockchain(),
974 getRepositoryLocator());
975 }
976 return web3InformationRetriever;
977 }
978
979 protected ReceiptStore buildReceiptStore() {
980 int receiptsCacheSize = getRskSystemProperties().getReceiptsCacheSize();
981 KeyValueDataSource ds = LevelDbDataSource.makeDataSource(Paths.get(getRskSystemProperties().databaseDir(), "receipts"));
982
983 if (receiptsCacheSize != 0) {
984 ds = new DataSourceWithCache(ds, receiptsCacheSize);
985 }
986
987 return new ReceiptStoreImpl(ds);
988 }
989
990 protected BlockValidator buildBlockValidator() {
991 return new BlockValidatorImpl(
992 getBlockStore(),
993 getBlockParentDependantValidationRule(),
994 getBlockValidationRule()
995 );
996 }
997
998 protected GenesisLoader buildGenesisLoader() {
999 RskSystemProperties systemProperties = getRskSystemProperties();
1000 ActivationConfig.ForBlock genesisActivations = systemProperties.getActivationConfig().forBlock(0L);
1001 return new GenesisLoaderImpl(
1002 systemProperties.getActivationConfig(),
1003 getStateRootHandler(),
1004 getTrieStore(),
1005 systemProperties.genesisInfo(),
1006 systemProperties.getNetworkConstants().getInitialNonce(),
1007 true,
1008 genesisActivations.isActive(ConsensusRule.RSKIP92),
1009 genesisActivations.isActive(ConsensusRule.RSKIP126)
1010 );
1011 }
1012
1013 protected TrieStore buildTrieStore(Path trieStorePath) {
1014 int statesCacheSize = getRskSystemProperties().getStatesCacheSize();
1015 KeyValueDataSource ds = LevelDbDataSource.makeDataSource(trieStorePath);
1016
1017 if (statesCacheSize != 0) {
1018 ds = new DataSourceWithCache(ds, statesCacheSize);
1019 }
1020
1021 return new TrieStoreImpl(ds);
1022 }
1023
1024 private TrieStore buildMultiTrieStore(Path databasePath, String namePrefix, int numberOfEpochs) throws IOException {
1025 int currentEpoch = numberOfEpochs;
1026 if (!getRskSystemProperties().databaseReset()) {
1027 try (Stream<Path> databasePaths = Files.list(databasePath)) {
1028 currentEpoch = databasePaths
1029 .map(Path::getFileName)
1030 .map(Path::toString)
1031 .filter(fileName -> fileName.startsWith(namePrefix))
1032 .map(multiTrieStoreName -> multiTrieStoreName.replaceFirst(namePrefix, ""))
1033 .map(Integer::valueOf)
1034 .max(Comparator.naturalOrder())
1035 .orElse(numberOfEpochs);
1036 }
1037 Path unitriePath = databasePath.resolve("unitrie");
1038 if (Files.exists(unitriePath)) {
1039 // moves the unitrie directory as the currentEpoch. It "knows" the internals of the MultiTrieStore constructor
1040 // to assign currentEpoch - 1 as the name
1041 Files.move(
1042 unitriePath,
1043 databasePath.resolve(namePrefix + (currentEpoch - 1))
1044 );
1045 }
1046 }
1047
1048 return new MultiTrieStore(
1049 currentEpoch + 1,
1050 numberOfEpochs,
1051 name -> buildTrieStore(databasePath.resolve(namePrefix + name)),
1052 disposedEpoch -> FileUtil.recursiveDelete(databasePath.resolve(namePrefix + disposedEpoch).toString())
1053 );
1054 }
1055
1056 protected RepositoryLocator buildRepositoryLocator() {
1057 return new RepositoryLocator(getTrieStore(), getStateRootHandler());
1058 }
1059
1060 protected org.ethereum.db.BlockStore buildBlockStore() {
1061 return buildBlockStore(getRskSystemProperties().databaseDir());
1062 }
1063
1064 protected RskSystemProperties buildRskSystemProperties() {
1065 return new RskSystemProperties(new ConfigLoader(cliArgs));
1066 }
1067
1068 protected SyncConfiguration buildSyncConfiguration() {
1069 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1070 return new SyncConfiguration(
1071 rskSystemProperties.getExpectedPeers(),
1072 rskSystemProperties.getTimeoutWaitingPeers(),
1073 rskSystemProperties.getTimeoutWaitingRequest(),
1074 rskSystemProperties.getExpirationTimePeerStatus(),
1075 rskSystemProperties.getMaxSkeletonChunks(),
1076 rskSystemProperties.getChunkSize(),
1077 rskSystemProperties.getMaxRequestedBodies(),
1078 rskSystemProperties.getLongSyncLimit());
1079 }
1080
1081 protected StateRootHandler buildStateRootHandler() {
1082 KeyValueDataSource stateRootsDB = LevelDbDataSource.makeDataSource(Paths.get(getRskSystemProperties().databaseDir(), "stateRoots"));
1083 return new StateRootHandler(getRskSystemProperties().getActivationConfig(), getTrieConverter(), stateRootsDB, new HashMap<>());
1084 }
1085
1086 protected CompositeEthereumListener buildCompositeEthereumListener() {
1087 return new CompositeEthereumListener();
1088 }
1089
1090 private PeerExplorer getPeerExplorer() {
1091 if (peerExplorer == null) {
1092 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1093 ECKey key = rskSystemProperties.getMyKey();
1094 Node localNode = new Node(
1095 key.getNodeId(),
1096 rskSystemProperties.getPublicIp(),
1097 rskSystemProperties.getPeerPort()
1098 );
1099 List<String> initialBootNodes = rskSystemProperties.peerDiscoveryIPList();
1100 List<Node> activePeers = rskSystemProperties.peerActive();
1101 if (activePeers != null) {
1102 for (Node n : activePeers) {
1103 InetSocketAddress address = n.getAddress();
1104 initialBootNodes.add(address.getHostName() + ":" + address.getPort());
1105 }
1106 }
1107 peerExplorer = new PeerExplorer(
1108 initialBootNodes,
1109 localNode,
1110 new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, localNode),
1111 key,
1112 rskSystemProperties.peerDiscoveryMessageTimeOut(),
1113 rskSystemProperties.peerDiscoveryRefreshPeriod(),
1114 rskSystemProperties.peerDiscoveryCleanPeriod(),
1115 rskSystemProperties.networkId()
1116 );
1117 }
1118
1119 return peerExplorer;
1120 }
1121
1122 protected Wallet buildWallet() {
1123 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1124 if (!rskSystemProperties.isWalletEnabled()) {
1125 return null;
1126 }
1127
1128 KeyValueDataSource ds = LevelDbDataSource.makeDataSource(Paths.get(rskSystemProperties.databaseDir(), "wallet"));
1129 return new Wallet(ds);
1130 }
1131
1132 public GenesisLoader getGenesisLoader() {
1133 if (genesisLoader == null) {
1134 genesisLoader = buildGenesisLoader();
1135 }
1136
1137 return genesisLoader;
1138 }
1139
1140 public Genesis getGenesis() {
1141 if (genesis == null) {
1142 genesis = getGenesisLoader().load();
1143 }
1144
1145 return genesis;
1146 }
1147
1148 private BlockChainLoader getBlockChainLoader() {
1149 if (blockChainLoader == null) {
1150 blockChainLoader = new BlockChainLoader(
1151 getBlockStore(),
1152 getReceiptStore(),
1153 getTransactionPool(),
1154 getCompositeEthereumListener(),
1155 getBlockValidator(),
1156 getBlockExecutor(),
1157 getGenesis(),
1158 getStateRootHandler()
1159 );
1160 }
1161
1162 return blockChainLoader;
1163 }
1164
1165 private SyncConfiguration getSyncConfiguration() {
1166 if (syncConfiguration == null) {
1167 syncConfiguration = buildSyncConfiguration();
1168 }
1169
1170 return syncConfiguration;
1171 }
1172
1173 public Wallet getWallet() {
1174 if (wallet == null) {
1175 wallet = buildWallet();
1176 }
1177
1178 return wallet;
1179 }
1180
1181 private BlockSyncService getBlockSyncService() {
1182 if (blockSyncService == null) {
1183 blockSyncService = new BlockSyncService(
1184 getRskSystemProperties(),
1185 getNetBlockStore(),
1186 getBlockchain(),
1187 getBlockNodeInformation(),
1188 getSyncConfiguration(),
1189 getBlockHeaderValidator());
1190 }
1191
1192 return blockSyncService;
1193 }
1194
1195 private BlockValidator getBlockValidator() {
1196 if (blockValidator == null) {
1197 blockValidator = buildBlockValidator();
1198 }
1199
1200 return blockValidator;
1201 }
1202
1203 private BlockValidator getBlockRelayValidator() {
1204 if (blockRelayValidator == null) {
1205 final RskSystemProperties rskSystemProperties = getRskSystemProperties();
1206 final Constants commonConstants = rskSystemProperties.getNetworkConstants();
1207 final BlockTimeStampValidationRule blockTimeStampValidationRule = new BlockTimeStampValidationRule(
1208 commonConstants.getNewBlockMaxSecondsInTheFuture(),
1209 rskSystemProperties.getActivationConfig()
1210 );
1211
1212 final BlockHeaderParentDependantValidationRule blockParentValidator = new BlockHeaderParentCompositeRule(
1213 new PrevMinGasPriceRule(),
1214 new BlockParentGasLimitRule(commonConstants.getGasLimitBoundDivisor()),
1215 new BlockDifficultyRule(getDifficultyCalculator()),
1216 new BlockParentNumberRule(),
1217 blockTimeStampValidationRule
1218 );
1219
1220 final BlockValidationRule blockValidator = new ExtraDataRule(commonConstants.getMaximumExtraDataSize());
1221
1222 blockRelayValidator = new BlockRelayValidatorImpl(
1223 getBlockStore(),
1224 blockParentValidator,
1225 blockValidator
1226 );
1227 }
1228
1229 return blockRelayValidator;
1230 }
1231
1232 private BlockValidator getBlockHeaderValidator() {
1233 if (blockHeaderValidator == null) {
1234 final RskSystemProperties rskSystemProperties = getRskSystemProperties();
1235 final Constants commonConstants = rskSystemProperties.getNetworkConstants();
1236 final BlockTimeStampValidationRule blockTimeStampValidationRule = new BlockTimeStampValidationRule(
1237 commonConstants.getNewBlockMaxSecondsInTheFuture(),
1238 rskSystemProperties.getActivationConfig()
1239 );
1240
1241 final BlockHeaderValidationRule blockHeaderValidationRule = new BlockHeaderCompositeRule(
1242 getProofOfWorkRule(),
1243 blockTimeStampValidationRule
1244 );
1245
1246 blockHeaderValidator = new BlockHeaderValidatorImpl(blockHeaderValidationRule);
1247 }
1248
1249 return blockHeaderValidator;
1250 }
1251
1252 private EthereumChannelInitializerFactory getEthereumChannelInitializerFactory() {
1253 if (ethereumChannelInitializerFactory == null) {
1254 ethereumChannelInitializerFactory = remoteId -> new EthereumChannelInitializer(
1255 remoteId,
1256 getRskSystemProperties(),
1257 getChannelManager(),
1258 getCompositeEthereumListener(),
1259 getConfigCapabilities(),
1260 getNodeManager(),
1261 getRskWireProtocolFactory(),
1262 getEth62MessageFactory(),
1263 getStaticMessages(),
1264 getPeerScoringManager()
1265 );
1266 }
1267
1268 return ethereumChannelInitializerFactory;
1269 }
1270
1271 private Eth62MessageFactory getEth62MessageFactory() {
1272 if (eth62MessageFactory == null) {
1273 eth62MessageFactory = new Eth62MessageFactory(getBlockFactory());
1274 }
1275
1276 return eth62MessageFactory;
1277 }
1278
1279 public BlockValidationRule getBlockValidationRule() {
1280 if (blockValidationRule == null) {
1281 final RskSystemProperties rskSystemProperties = getRskSystemProperties();
1282 final Constants commonConstants = rskSystemProperties.getNetworkConstants();
1283 final BlockTimeStampValidationRule blockTimeStampValidationRule = new BlockTimeStampValidationRule(
1284 commonConstants.getNewBlockMaxSecondsInTheFuture(),
1285 rskSystemProperties.getActivationConfig()
1286 );
1287 blockValidationRule = new BlockValidatorRule(
1288 new TxsMinGasPriceRule(),
1289 new BlockUnclesValidationRule(
1290 getBlockStore(),
1291 commonConstants.getUncleListLimit(),
1292 commonConstants.getUncleGenerationLimit(),
1293 new BlockHeaderCompositeRule(
1294 getProofOfWorkRule(),
1295 getForkDetectionDataRule(),
1296 blockTimeStampValidationRule,
1297 new ValidGasUsedRule()
1298 ),
1299 new BlockHeaderParentCompositeRule(
1300 new PrevMinGasPriceRule(),
1301 new BlockParentNumberRule(),
1302 blockTimeStampValidationRule,
1303 new BlockDifficultyRule(getDifficultyCalculator()),
1304 new BlockParentGasLimitRule(commonConstants.getGasLimitBoundDivisor())
1305 )
1306 ),
1307 new BlockRootValidationRule(rskSystemProperties.getActivationConfig()),
1308 getProofOfWorkRule(),
1309 new RemascValidationRule(),
1310 blockTimeStampValidationRule,
1311 new GasLimitRule(commonConstants.getMinGasLimit()),
1312 new ExtraDataRule(commonConstants.getMaximumExtraDataSize()),
1313 getForkDetectionDataRule()
1314 );
1315 }
1316
1317 return blockValidationRule;
1318 }
1319
1320 private BlockValidationRule getMinerServerBlockValidationRule() {
1321 if (minerServerBlockValidationRule == null) {
1322 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1323 Constants commonConstants = rskSystemProperties.getNetworkConstants();
1324 minerServerBlockValidationRule = new BlockUnclesValidationRule(
1325 getBlockStore(),
1326 commonConstants.getUncleListLimit(),
1327 commonConstants.getUncleGenerationLimit(),
1328 new BlockHeaderCompositeRule(
1329 getProofOfWorkRule(),
1330 new BlockTimeStampValidationRule(commonConstants.getNewBlockMaxSecondsInTheFuture(), rskSystemProperties.getActivationConfig()),
1331 new ValidGasUsedRule()
1332 ),
1333 new BlockHeaderParentCompositeRule(
1334 new PrevMinGasPriceRule(),
1335 new BlockParentNumberRule(),
1336 new BlockDifficultyRule(getDifficultyCalculator()),
1337 new BlockParentGasLimitRule(commonConstants.getGasLimitBoundDivisor())
1338 )
1339 );
1340 }
1341
1342 return minerServerBlockValidationRule;
1343 }
1344
1345 public BlockParentDependantValidationRule getBlockParentDependantValidationRule() {
1346 if (blockParentDependantValidationRule == null) {
1347 Constants commonConstants = getRskSystemProperties().getNetworkConstants();
1348 blockParentDependantValidationRule = new BlockParentCompositeRule(
1349 new BlockTxsFieldsValidationRule(),
1350 new BlockTxsValidationRule(getRepositoryLocator()),
1351 new PrevMinGasPriceRule(),
1352 new BlockParentNumberRule(),
1353 new BlockDifficultyRule(getDifficultyCalculator()),
1354 new BlockParentGasLimitRule(commonConstants.getGasLimitBoundDivisor())
1355 );
1356 }
1357
1358 return blockParentDependantValidationRule;
1359 }
1360
1361 private ForkDetectionDataCalculator getForkDetectionDataCalculator() {
1362 if (forkDetectionDataCalculator == null) {
1363 forkDetectionDataCalculator = new ForkDetectionDataCalculator();
1364 }
1365
1366 return forkDetectionDataCalculator;
1367 }
1368
1369 private ProofOfWorkRule getProofOfWorkRule() {
1370 if (proofOfWorkRule == null) {
1371 proofOfWorkRule = new ProofOfWorkRule(getRskSystemProperties());
1372 }
1373
1374 return proofOfWorkRule;
1375 }
1376
1377 private ForkDetectionDataRule getForkDetectionDataRule() {
1378 if (forkDetectionDataRule == null) {
1379 forkDetectionDataRule = new ForkDetectionDataRule(
1380 getRskSystemProperties().getActivationConfig(),
1381 getConsensusValidationMainchainView(),
1382 getForkDetectionDataCalculator(),
1383 MiningConfig.REQUIRED_NUMBER_OF_BLOCKS_FOR_FORK_DETECTION_CALCULATION
1384 );
1385 }
1386
1387 return forkDetectionDataRule;
1388 }
1389
1390 private DifficultyCalculator getDifficultyCalculator() {
1391 if (difficultyCalculator == null) {
1392 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1393 difficultyCalculator = new DifficultyCalculator(
1394 rskSystemProperties.getActivationConfig(),
1395 rskSystemProperties.getNetworkConstants()
1396 );
1397 }
1398
1399 return difficultyCalculator;
1400 }
1401
1402 private BlockToMineBuilder getBlockToMineBuilder() {
1403 if (blockToMineBuilder == null) {
1404 blockToMineBuilder = new BlockToMineBuilder(
1405 getRskSystemProperties().getActivationConfig(),
1406 getMiningConfig(),
1407 getRepositoryLocator(),
1408 getBlockStore(),
1409 getTransactionPool(),
1410 getDifficultyCalculator(),
1411 getGasLimitCalculator(),
1412 getForkDetectionDataCalculator(),
1413 getMinerServerBlockValidationRule(),
1414 getMinerClock(),
1415 getBlockFactory(),
1416 getBlockExecutor(),
1417 new MinimumGasPriceCalculator(Coin.valueOf(getMiningConfig().getMinGasPriceTarget())),
1418 new MinerUtils()
1419 );
1420 }
1421
1422 return blockToMineBuilder;
1423 }
1424
1425 private BlockNodeInformation getBlockNodeInformation() {
1426 if (blockNodeInformation == null) {
1427 blockNodeInformation = new BlockNodeInformation();
1428 }
1429
1430 return blockNodeInformation;
1431 }
1432
1433 private MessageRecorder getMessageRecorder() {
1434 if (writerMessageRecorder == null) {
1435 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1436 if (!rskSystemProperties.hasMessageRecorderEnabled()) {
1437 return null;
1438 }
1439
1440 Path filePath = FileUtil.getDatabaseDirectoryPath(rskSystemProperties.databaseDir(), "messages");
1441
1442 String fullFilename = filePath.toString();
1443 MessageFilter filter = new MessageFilter(rskSystemProperties.getMessageRecorderCommands());
1444
1445 try {
1446 writerMessageRecorder = new WriterMessageRecorder(
1447 new BufferedWriter(
1448 new OutputStreamWriter(new FileOutputStream(fullFilename), StandardCharsets.UTF_8)
1449 ),
1450 filter
1451 );
1452 } catch (IOException ex) {
1453 throw new IllegalArgumentException("Can't use this path to record messages", ex);
1454 }
1455 }
1456
1457 return writerMessageRecorder;
1458 }
1459
1460 private EthModuleWallet getEthModuleWallet() {
1461 if (ethModuleWallet == null) {
1462 Wallet wallet = getWallet();
1463 if (wallet == null) {
1464 ethModuleWallet = new EthModuleWalletDisabled();
1465 } else {
1466 ethModuleWallet = new EthModuleWalletEnabled(wallet);
1467 }
1468 }
1469
1470 return ethModuleWallet;
1471 }
1472
1473 private EthModuleTransaction getEthModuleTransaction() {
1474 if (ethModuleTransaction == null) {
1475 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1476 Constants constants = rskSystemProperties.getNetworkConstants();
1477 Wallet wallet = getWallet();
1478 TransactionPool transactionPool = getTransactionPool();
1479 if (wallet == null) {
1480 ethModuleTransaction = new EthModuleTransactionDisabled(constants, transactionPool, getTransactionGateway());
1481 } else if (rskSystemProperties.minerClientAutoMine()) {
1482 ethModuleTransaction = new EthModuleTransactionInstant(
1483 constants,
1484 wallet,
1485 transactionPool,
1486 getMinerServer(),
1487 getMinerClient(),
1488 getBlockchain(),
1489 getTransactionGateway(),
1490 getBlockExecutor()
1491 );
1492 } else {
1493 ethModuleTransaction = new EthModuleTransactionBase(constants, wallet, transactionPool, getTransactionGateway());
1494 }
1495 }
1496
1497 return ethModuleTransaction;
1498 }
1499
1500 private SyncProcessor getSyncProcessor() {
1501 if (syncProcessor == null) {
1502 syncProcessor = new SyncProcessor(
1503 getBlockchain(),
1504 getBlockStore(),
1505 getConsensusValidationMainchainView(),
1506 getBlockSyncService(),
1507 getSyncConfiguration(),
1508 getBlockFactory(),
1509 getProofOfWorkRule(),
1510 new SyncBlockValidatorRule(
1511 new BlockUnclesHashValidationRule(),
1512 new BlockRootValidationRule(getRskSystemProperties().getActivationConfig())
1513 ),
1514 getDifficultyCalculator(),
1515 getPeersInformation(),
1516 getGenesis());
1517 }
1518
1519 return syncProcessor;
1520 }
1521
1522 private PeersInformation getPeersInformation() {
1523 if (peersInformation == null) {
1524 peersInformation = new PeersInformation(
1525 getChannelManager(),
1526 getSyncConfiguration(),
1527 getBlockchain(),
1528 getPeerScoringManager());
1529 }
1530 return peersInformation;
1531 }
1532
1533 private SyncPool getSyncPool() {
1534 if (syncPool == null) {
1535 syncPool = new SyncPool(
1536 getCompositeEthereumListener(),
1537 getBlockchain(),
1538 getRskSystemProperties(),
1539 getNodeManager(),
1540 getNodeBlockProcessor(),
1541 () -> new PeerClient(
1542 getRskSystemProperties(),
1543 getCompositeEthereumListener(),
1544 getEthereumChannelInitializerFactory()
1545 )
1546 );
1547 }
1548
1549 return syncPool;
1550 }
1551
1552 private Web3 getWeb3() {
1553 if (web3 == null) {
1554 web3 = buildWeb3();
1555 }
1556
1557 return web3;
1558 }
1559
1560 private JsonRpcWeb3FilterHandler getJsonRpcWeb3FilterHandler() {
1561 if (jsonRpcWeb3FilterHandler == null) {
1562 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1563 jsonRpcWeb3FilterHandler = new JsonRpcWeb3FilterHandler(
1564 rskSystemProperties.corsDomains(),
1565 rskSystemProperties.rpcHttpBindAddress(),
1566 rskSystemProperties.rpcHttpHost()
1567 );
1568 }
1569
1570 return jsonRpcWeb3FilterHandler;
1571 }
1572
1573 private JsonRpcWeb3ServerHandler getJsonRpcWeb3ServerHandler() {
1574 if (jsonRpcWeb3ServerHandler == null) {
1575 jsonRpcWeb3ServerHandler = new JsonRpcWeb3ServerHandler(
1576 getWeb3(),
1577 getRskSystemProperties().getRpcModules()
1578 );
1579 }
1580
1581 return jsonRpcWeb3ServerHandler;
1582 }
1583
1584 private Web3WebSocketServer getWeb3WebSocketServer() {
1585 if (web3WebSocketServer == null) {
1586 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1587 JsonRpcSerializer jsonRpcSerializer = getJsonRpcSerializer();
1588 Ethereum rsk = getRsk();
1589 EthSubscriptionNotificationEmitter emitter = new EthSubscriptionNotificationEmitter(
1590 new BlockHeaderNotificationEmitter(rsk, jsonRpcSerializer),
1591 new LogsNotificationEmitter(
1592 rsk,
1593 jsonRpcSerializer,
1594 getReceiptStore(),
1595 new BlockchainBranchComparator(getBlockStore())
1596 )
1597 );
1598 RskJsonRpcHandler jsonRpcHandler = new RskJsonRpcHandler(emitter, jsonRpcSerializer);
1599 web3WebSocketServer = new Web3WebSocketServer(
1600 rskSystemProperties.rpcWebSocketBindAddress(),
1601 rskSystemProperties.rpcWebSocketPort(),
1602 jsonRpcHandler,
1603 getJsonRpcWeb3ServerHandler()
1604 );
1605 }
1606
1607 return web3WebSocketServer;
1608 }
1609
1610 private Web3HttpServer getWeb3HttpServer() {
1611 if (web3HttpServer == null) {
1612 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1613 web3HttpServer = new Web3HttpServer(
1614 rskSystemProperties.rpcHttpBindAddress(),
1615 rskSystemProperties.rpcHttpPort(),
1616 rskSystemProperties.soLingerTime(),
1617 true,
1618 new CorsConfiguration(rskSystemProperties.corsDomains()),
1619 getJsonRpcWeb3FilterHandler(),
1620 getJsonRpcWeb3ServerHandler()
1621 );
1622 }
1623
1624 return web3HttpServer;
1625 }
1626
1627 private JsonRpcSerializer getJsonRpcSerializer() {
1628 if (jacksonBasedRpcSerializer == null) {
1629 jacksonBasedRpcSerializer = new JacksonBasedRpcSerializer();
1630 }
1631
1632 return jacksonBasedRpcSerializer;
1633 }
1634
1635 private NetBlockStore getNetBlockStore() {
1636 if (netBlockStore == null) {
1637 netBlockStore = new NetBlockStore();
1638 }
1639
1640 return netBlockStore;
1641 }
1642
1643 private TransactionGateway getTransactionGateway() {
1644 if (transactionGateway == null) {
1645 transactionGateway = new TransactionGateway(
1646 getChannelManager(),
1647 getTransactionPool()
1648 );
1649 }
1650
1651 return transactionGateway;
1652 }
1653
1654 private NodeMessageHandler getNodeMessageHandler() {
1655 if (nodeMessageHandler == null) {
1656 nodeMessageHandler = new NodeMessageHandler(
1657 getRskSystemProperties(),
1658 getNodeBlockProcessor(),
1659 getSyncProcessor(),
1660 getChannelManager(),
1661 getTransactionGateway(),
1662 getPeerScoringManager(),
1663 getStatusResolver());
1664 }
1665
1666 return nodeMessageHandler;
1667 }
1668
1669 private StatusResolver getStatusResolver() {
1670 if (statusResolver == null) {
1671 statusResolver = new StatusResolver(getBlockStore(), getGenesis());
1672 }
1673 return statusResolver;
1674 }
1675
1676 private RskWireProtocol.Factory getRskWireProtocolFactory() {
1677 if (rskWireProtocolFactory == null) {
1678 rskWireProtocolFactory = (messageQueue, channel) -> new RskWireProtocol(
1679 getRskSystemProperties(),
1680 getPeerScoringManager(),
1681 getNodeMessageHandler(),
1682 getCompositeEthereumListener(),
1683 getGenesis(),
1684 getMessageRecorder(),
1685 getStatusResolver(),
1686 messageQueue,
1687 channel);
1688 }
1689
1690 return rskWireProtocolFactory;
1691 }
1692
1693 private MiningConfig getMiningConfig() {
1694 if (miningConfig == null) {
1695 RskSystemProperties rskSystemProperties = getRskSystemProperties();
1696 miningConfig = new MiningConfig(
1697 rskSystemProperties.coinbaseAddress(),
1698 rskSystemProperties.minerMinFeesNotifyInDollars(),
1699 rskSystemProperties.minerGasUnitInDollars(),
1700 rskSystemProperties.minerMinGasPrice(),
1701 rskSystemProperties.getNetworkConstants().getUncleListLimit(),
1702 rskSystemProperties.getNetworkConstants().getUncleGenerationLimit(),
1703 new GasLimitConfig(
1704 rskSystemProperties.getNetworkConstants().getMinGasLimit(),
1705 rskSystemProperties.getTargetGasLimit(),
1706 rskSystemProperties.getForceTargetGasLimit()
1707 ),
1708 rskSystemProperties.isMinerServerFixedClock()
1709 );
1710 }
1711
1712 return miningConfig;
1713 }
1714
1715 private GasLimitCalculator getGasLimitCalculator() {
1716 if (gasLimitCalculator == null) {
1717 gasLimitCalculator = new GasLimitCalculator(getRskSystemProperties().getNetworkConstants());
1718 }
1719
1720 return gasLimitCalculator;
1721 }
1722
1723 private ExecutionBlockRetriever getExecutionBlockRetriever() {
1724 if (executionBlockRetriever == null) {
1725 executionBlockRetriever = new ExecutionBlockRetriever(
1726 getMiningMainchainView(),
1727 getBlockchain(),
1728 getMinerServer(),
1729 getBlockToMineBuilder()
1730 );
1731 }
1732
1733 return executionBlockRetriever;
1734 }
1735
1736 private NodeManager getNodeManager() {
1737 if (nodeManager == null) {
1738 nodeManager = new NodeManager(getPeerExplorer(), getRskSystemProperties());
1739 }
1740
1741 return nodeManager;
1742 }
1743
1744 private StaticMessages getStaticMessages() {
1745 if (staticMessages == null) {
1746 staticMessages = new StaticMessages(getRskSystemProperties(), getConfigCapabilities());
1747 }
1748
1749 return staticMessages;
1750 }
1751
1752 private MinerClock getMinerClock() {
1753 if (minerClock == null) {
1754 minerClock = new MinerClock(getMiningConfig().isFixedClock(), Clock.systemUTC());
1755 }
1756
1757 return minerClock;
1758 }
1759
1760 public org.ethereum.db.BlockStore buildBlockStore(String databaseDir) {
1761 File blockIndexDirectory = new File(databaseDir + "/blocks/");
1762 File dbFile = new File(blockIndexDirectory, "index");
1763 if (!blockIndexDirectory.exists()) {
1764 if (!blockIndexDirectory.mkdirs()) {
1765 throw new IllegalArgumentException(String.format(
1766 "Unable to create blocks directory: %s", blockIndexDirectory
1767 ));
1768 }
1769 }
1770
1771 DB indexDB = DBMaker.fileDB(dbFile)
1772 .make();
1773
1774 KeyValueDataSource blocksDB = LevelDbDataSource.makeDataSource(Paths.get(databaseDir, "blocks"));
1775
1776 return new IndexedBlockStore(getBlockFactory(), blocksDB, new MapDBBlocksIndex(indexDB));
1777 }
1778
1779 public PeerScoringReporterService getPeerScoringReporterService() {
1780 if(peerScoringReporterService == null) {
1781 this.peerScoringReporterService = PeerScoringReporterService.withScheduler(getRskSystemProperties().getPeerScoringSummaryTime(), getPeerScoringManager());
1782 }
1783
1784 return peerScoringReporterService;
1785 }
1786 }