Example #1
0
        public void Setup_chain()
        {
            // Import blocks
            BlockTree blockTree    = Build.A.BlockTree().TestObject;
            Block     block1       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block1Rlp)));
            Block     block2       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block2Rlp)));
            Block     block3       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block3Rlp)));
            Block     block4       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block4Rlp)));
            Block     block5       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block5Rlp)));
            Block     genesisBlock = GetRinkebyGenesis();

            // Add blocks
            MineBlock(blockTree, genesisBlock);
            MineBlock(blockTree, block1);
            MineBlock(blockTree, block2);
            MineBlock(blockTree, block3);
            MineBlock(blockTree, block4);
            MineBlock(blockTree, block5);
            // Get a test private key
            PrivateKey key = Build.A.PrivateKey.TestObject;
            // Init snapshot db
            IDb          db     = new MemDb();
            CliqueConfig config = GetRinkebyConfig();

            _clique = new CliqueSealEngine(config, NullEthereumSigner.Instance, key, db, blockTree, NullLogManager.Instance);
        }
Example #2
0
        public void Setup_chain()
        {
            // Import blocks
            _blockTree = Build.A.BlockTree().TestObject;
            Block genesisBlock = GetRinkebyGenesis();
            Block block1       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block1Rlp)));
            Block block2       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block2Rlp)));
            Block block3       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block3Rlp)));
            Block block4       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block4Rlp)));
            Block block5       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block5Rlp)));

            _lastBlock = block5;
            // Add blocks
            MineBlock(_blockTree, genesisBlock);
            MineBlock(_blockTree, block1);
            MineBlock(_blockTree, block2);
            MineBlock(_blockTree, block3);
            MineBlock(_blockTree, block4);
            MineBlock(_blockTree, block5);
            IEthereumSigner signer = new EthereumSigner(RinkebySpecProvider.Instance, NullLogManager.Instance);
            // Init snapshot db
            IDb          db     = new MemDb();
            CliqueConfig config = new CliqueConfig();
            // Select in-turn signer
            int currentBlock       = 6;
            int currentSignerIndex = (currentBlock % _signers.Count);

            _currentSigner = _signers[currentSignerIndex];
            _clique        = new CliqueSealEngine(config, signer, _currentSigner, db, _blockTree, NullLogManager.Instance);
        }
Example #3
0
        public void Setup_chain()
        {
            // Import blocks
            _blockTree = Build.A.BlockTree().TestObject;
            Block block1       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block1Rlp)));
            Block block2       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block2Rlp)));
            Block block3       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block3Rlp)));
            Block block4       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block4Rlp)));
            Block block5       = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(Block5Rlp)));
            Block genesisBlock = GetRinkebyGenesis();

            // Add blocks
            MineBlock(_blockTree, genesisBlock);
            MineBlock(_blockTree, block1);
            MineBlock(_blockTree, block2);
            MineBlock(_blockTree, block3);
            MineBlock(_blockTree, block4);
            MineBlock(_blockTree, block5);
            // Get a test private key
            PrivateKey key = Build.A.PrivateKey.TestObject;
            // Init snapshot db
            MemDb        db     = new MemDb();
            CliqueConfig config = new CliqueConfig(15, 30000);

            _signer = new EthereumSigner(RinkebySpecProvider.Instance, LimboLogs.Instance);
            _clique = new CliqueSealEngine(config, _signer, key, db, _blockTree, LimboLogs.Instance);
        }
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb blockInfoDb = new MemDb();

                TransactionPool transactionPool = new TransactionPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), _timestamp, _ethereumSigner, GoerliSpecProvider.Instance, NullLogManager.Instance);

                _pools[privateKey] = transactionPool;

                BlockTree blockTree = new BlockTree(blocksDb, blockInfoDb, GoerliSpecProvider.Instance, transactionPool, NullLogManager.Instance);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree);

                _blockTrees.Add(privateKey, blockTree);

                EthereumSigner   ethereumSigner   = new EthereumSigner(GoerliSpecProvider.Instance, NullLogManager.Instance);
                CliqueSealEngine cliqueSealEngine = new CliqueSealEngine(_cliqueConfig, ethereumSigner, privateKey, new MemDb(), blockTree, NullLogManager.Instance);

                cliqueSealEngine.CanSeal = true;

                ISnapshotableDb stateDb = new StateDb();
                ISnapshotableDb codeDb  = new StateDb();
                IDb             traceDb = new MemDb();

                StateProvider stateProvider = new StateProvider(new StateTree(stateDb), codeDb, NullLogManager.Instance);

                stateProvider.CreateAccount(TestObject.PrivateKeyD.Address, 100.Ether());
                stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec);

                _genesis.StateRoot       = _genesis3Validators.StateRoot = stateProvider.StateRoot;
                _genesis.Hash            = BlockHeader.CalculateHash(_genesis.Header);
                _genesis3Validators.Hash = BlockHeader.CalculateHash(_genesis3Validators.Header);

                StorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, NullLogManager.Instance);
                TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, NullLogManager.Instance), NullLogManager.Instance);
                BlockProcessor       blockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, new NoBlockRewards(), transactionProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, transactionPool, NullReceiptStorage.Instance, NullLogManager.Instance);
                BlockchainProcessor  processor            = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(cliqueSealEngine), NullLogManager.Instance, false, false);

                processor.Start();

                StateProvider        minerStateProvider        = new StateProvider(new StateTree(stateDb), codeDb, NullLogManager.Instance);
                StorageProvider      minerStorageProvider      = new StorageProvider(stateDb, minerStateProvider, NullLogManager.Instance);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, NullLogManager.Instance);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, NullLogManager.Instance);
                BlockProcessor       minerBlockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, new NoBlockRewards(), minerTransactionProcessor, stateDb, codeDb, traceDb, minerStateProvider, minerStorageProvider, transactionPool, NullReceiptStorage.Instance, NullLogManager.Instance);
                BlockchainProcessor  minerProcessor            = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(cliqueSealEngine), NullLogManager.Instance, false, false);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                CliqueBlockProducer blockProducer = new CliqueBlockProducer(transactionPool, minerProcessor, blockTree, minerStateProvider, _timestamp, new CryptoRandom(), cliqueSealEngine, _cliqueConfig, privateKey.Address, NullLogManager.Instance);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
Example #5
0
        private async Task InitBlockchain()
        {
            /* spec */
            if (_chainSpec.ChainId == RopstenSpecProvider.Instance.ChainId)
            {
                _specProvider = RopstenSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == MainNetSpecProvider.Instance.ChainId)
            {
                _specProvider = MainNetSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == RinkebySpecProvider.Instance.ChainId)
            {
                _specProvider = RinkebySpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == GoerliSpecProvider.Instance.ChainId)
            {
                _specProvider = GoerliSpecProvider.Instance;
            }
            else if (_chainSpec.ChainId == SturebySpecProvider.Instance.ChainId)
            {
                _specProvider = SturebySpecProvider.Instance;
            }
            else
            {
                _specProvider = new SingleReleaseSpecProvider(LatestRelease.Instance, _chainSpec.ChainId);
            }

            /* sync */
            IDbConfig dbConfig = _configProvider.GetConfig<IDbConfig>();
            foreach (PropertyInfo propertyInfo in typeof(IDbConfig).GetProperties())
            {
                _logger.Info($"DB {propertyInfo.Name}: {propertyInfo.GetValue(dbConfig)}");
            }

            _dbProvider = HiveEnabled
                ? (IDbProvider) new MemDbProvider()
                : new RocksDbProvider(_initConfig.BaseDbPath, dbConfig, _logManager, _initConfig.StoreTraces, _initConfig.StoreReceipts);

            _ethereumSigner = new EthereumSigner(_specProvider, _logManager);
            _transactionPool = new TransactionPool(
                new PersistentTransactionStorage(_dbProvider.PendingTxsDb, _specProvider),
                new PendingTransactionThresholdValidator(_initConfig.ObsoletePendingTransactionInterval,
                    _initConfig.RemovePendingTransactionInterval), new Timestamp(),
                _ethereumSigner, _specProvider, _logManager, _initConfig.RemovePendingTransactionInterval,
                _initConfig.PeerNotificationThreshold);
            _receiptStorage = new PersistentReceiptStorage(_dbProvider.ReceiptsDb, _specProvider);

//            IDbProvider debugRecorder = new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig);
//            _dbProvider = new RpcDbProvider(_jsonSerializer, new BasicJsonRpcClient(KnownRpcUris.NethVm1, _jsonSerializer, _logManager), _logManager, debugRecorder);

//            IDbProvider debugReader = new ReadOnlyDbProvider(new RocksDbProvider(Path.Combine(_dbBasePath, "debug"), dbConfig));
//            _dbProvider = debugReader;

            _blockTree = new BlockTree(
                _dbProvider.BlocksDb,
                _dbProvider.BlockInfosDb,
                _specProvider,
                _transactionPool,
                _logManager);

            CliqueConfig cliqueConfig = null;
            CliqueSealEngine clique = null;            
            switch (_chainSpec.SealEngineType)
            {
                case SealEngineType.None:
                    _sealEngine = NullSealEngine.Instance;
                    _rewardCalculator = new NoBlockRewards();
                    break;
                case SealEngineType.Clique:
                    _rewardCalculator = new NoBlockRewards();
                    cliqueConfig = new CliqueConfig();
                    cliqueConfig.BlockPeriod = _chainSpec.CliquePeriod;
                    cliqueConfig.Epoch = _chainSpec.CliqueEpoch;
                    _sealEngine = clique = new CliqueSealEngine(cliqueConfig, _ethereumSigner, _nodeKey, _dbProvider.BlocksDb, _blockTree, _logManager);
                    _sealEngine.CanSeal = _initConfig.IsMining;
                    break;
                case SealEngineType.NethDev:
                    _rewardCalculator = new NoBlockRewards();
                    _sealEngine = NullSealEngine.Instance;
                    break;
                case SealEngineType.Ethash:
                    _rewardCalculator = new RewardCalculator(_specProvider);
                    var difficultyCalculator = new DifficultyCalculator(_specProvider);
                    _sealEngine = new EthashSealEngine(new Ethash(_logManager), difficultyCalculator, _logManager);
                    break;
                default:
                    throw new NotSupportedException($"Seal engine type {_chainSpec.SealEngineType} is not supported in Nethermind");
            }

            _rewardCalculator = (_sealEngine is CliqueSealEngine)
                ? (IRewardCalculator) new NoBlockRewards()
                : new RewardCalculator(_specProvider);

            /* validation */
            var headerValidator = new HeaderValidator(
                _blockTree,
                _sealEngine,
                _specProvider,
                _logManager);

            var ommersValidator = new OmmersValidator(
                _blockTree,
                headerValidator,
                _logManager);

            var txValidator = new TransactionValidator(
                new SignatureValidator(_specProvider.ChainId));

            _blockValidator = new BlockValidator(
                txValidator,
                headerValidator,
                ommersValidator,
                _specProvider,
                _logManager);

            var stateTree = new StateTree(_dbProvider.StateDb);

            var stateProvider = new StateProvider(
                stateTree,
                _dbProvider.CodeDb,
                _logManager);

            _stateProvider = stateProvider;

            var storageProvider = new StorageProvider(
                _dbProvider.StateDb,
                stateProvider,
                _logManager);

            _transactionPoolInfoProvider = new TransactionPoolInfoProvider(stateProvider);

            /* blockchain processing */
            var blockhashProvider = new BlockhashProvider(
                _blockTree);

            var virtualMachine = new VirtualMachine(
                stateProvider,
                storageProvider,
                blockhashProvider,
                _logManager);

            var transactionProcessor = new TransactionProcessor(
                _specProvider,
                stateProvider,
                storageProvider,
                virtualMachine,
                _logManager);

            var txRecoveryStep = new TxSignaturesRecoveryStep(_ethereumSigner, _transactionPool);
            _recoveryStep = _sealEngine is CliqueSealEngine
                ? new CompositeDataRecoveryStep(txRecoveryStep, new AuthorRecoveryStep(clique))
                : (IBlockDataRecoveryStep) txRecoveryStep;

            _blockProcessor = new BlockProcessor(
                _specProvider,
                _blockValidator,
                _rewardCalculator,
                transactionProcessor,
                _dbProvider.StateDb,
                _dbProvider.CodeDb,
                _dbProvider.TraceDb,
                stateProvider,
                storageProvider,
                _transactionPool,
                _receiptStorage,
                _logManager);

            _blockchainProcessor = new BlockchainProcessor(
                _blockTree,
                _blockProcessor,
                _recoveryStep,
                _logManager,
                _initConfig.StoreReceipts,
                _initConfig.StoreTraces);

            // create shared objects between discovery and peer manager
            _nodeFactory = new NodeFactory(_logManager);
            IStatsConfig statsConfig = _configProvider.GetConfig<IStatsConfig>();
            _nodeStatsProvider = new NodeStatsProvider(statsConfig, _nodeFactory, _logManager, !statsConfig.CaptureNodeStatsEventHistory);

            var encrypter = new AesEncrypter(
                _configProvider.GetConfig<IKeyStoreConfig>(),
                _logManager);

            _keyStore = new FileKeyStore(
                _configProvider.GetConfig<IKeyStoreConfig>(),
                _ethereumJsonSerializer,
                encrypter,
                _cryptoRandom,
                _logManager);

            if (_initConfig.IsMining)
            {
                IReadOnlyDbProvider minerDbProvider = new ReadOnlyDbProvider(_dbProvider, false);
                AlternativeChain producerChain = new AlternativeChain(_blockTree, _blockValidator, _rewardCalculator,
                    _specProvider, minerDbProvider, _recoveryStep, _logManager, _transactionPool, _receiptStorage);

                switch (_chainSpec.SealEngineType)
                {
                    case SealEngineType.Clique:
                    {
                        // TODO: need to introduce snapshot provider for clique and pass it here instead of CliqueSealEngine
                        if (_logger.IsWarn) _logger.Warn("Starting Clique block producer & sealer");
                        _blockProducer = new CliqueBlockProducer(_transactionPool, producerChain.Processor, _blockTree,
                            producerChain.StateProvider, _timestamp, _cryptoRandom, (CliqueSealEngine)_sealEngine, cliqueConfig, _nodeKey.Address,
                            _logManager);
                        break;
                    }
                    case SealEngineType.NethDev:
                    {
                        if (_logger.IsWarn) _logger.Warn("Starting Dev block producer & sealer");
                        _blockProducer = new DevBlockProducer(_transactionPool, producerChain.Processor, _blockTree,
                            _timestamp, _logManager);
                        break;
                    }
                    default:
                        throw new NotSupportedException($"Mining in {_chainSpec.SealEngineType} mode is not supported");
                }

                _blockProducer.Start();
            }

            if (!HiveEnabled)
            {
                _blockchainProcessor.Start();
                LoadGenesisBlock(_chainSpec,string.IsNullOrWhiteSpace(_initConfig.GenesisHash) ?
                        null : new Keccak(_initConfig.GenesisHash), _blockTree, stateProvider, _specProvider);
                if (_initConfig.ProcessingEnabled)
                {
#pragma warning disable 4014
                    LoadBlocksFromDb();
#pragma warning restore 4014
                }
                else
                {
                    if (_logger.IsWarn) _logger.Warn( $"Shutting down processor due to {nameof(InitConfig)}.{nameof(InitConfig.ProcessingEnabled)} set to false");
                    await _blockchainProcessor.StopAsync();
                }
            }

            await InitializeNetwork(
                _receiptStorage,
                headerValidator,
                txValidator);
        }