Exemple #1
0
 public MainchainNodeService(IStateStore stateStore, ITxHub hub, IChainCreationService chainCreationService,
                             IBlockSynchronizer blockSynchronizer, IChainService chainService, IMiner miner, ILogger logger)
 {
     _stateStore           = stateStore;
     _chainCreationService = chainCreationService;
     _chainService         = chainService;
     _txHub             = hub;
     _logger            = logger;
     _miner             = miner;
     _blockSynchronizer = blockSynchronizer;
 }
Exemple #2
0
 public NodeService(
     IBlockSynchronizer blockSynchronizer,
     IBlockchainEventFilter blockchainEventFilter,
     INetworkManager networkManager,
     IBlockManager blockManager
     )
 {
     _blockchainEventFilter = blockchainEventFilter;
     _blockSynchronizer     = blockSynchronizer;
     _blockManager          = blockManager;
     _startTs = TimeUtils.CurrentTimeMillis();
 }
Exemple #3
0
 public BlockchainService(
     ITransactionManager transactionManager,
     IBlockManager blockManager,
     ITransactionPool transactionPool,
     IStateManager stateManager,
     IBlockSynchronizer blockSynchronizer,
     ISystemContractReader systemContractReader
     )
 {
     _transactionPool      = transactionPool;
     _transactionManager   = transactionManager;
     _blockManager         = blockManager;
     _stateManager         = stateManager;
     _blockSynchronizer    = blockSynchronizer;
     _systemContractReader = systemContractReader;
 }
Exemple #4
0
        private const int BatchSize = 1000; // TODO: calculate batch size

        public BlockProducer(
            ITransactionPool transactionPool,
            IValidatorManager validatorManager,
            IBlockSynchronizer blockSynchronizer,
            IBlockManager blockManager,
            IStateManager stateManager,
            ITransactionBuilder transactionBuilder
            )
        {
            _transactionPool    = transactionPool;
            _validatorManager   = validatorManager;
            _blockSynchronizer  = blockSynchronizer;
            _blockManager       = blockManager;
            _stateManager       = stateManager;
            _transactionBuilder = transactionBuilder;
        }
Exemple #5
0
 public RpcManager(
     ITransactionManager transactionManager,
     IBlockManager blockManager,
     IConfigManager configManager,
     IStateManager stateManager,
     ISnapshotIndexRepository snapshotIndexer,
     ITransactionPool transactionPool,
     IVirtualMachine virtualMachine,
     IContractRegisterer contractRegisterer,
     IValidatorStatusManager validatorStatusManager,
     ISystemContractReader systemContractReader,
     IBlockSynchronizer blockSynchronizer,
     ILocalTransactionRepository localTransactionRepository,
     ITransactionSigner transactionSigner,
     IPrivateWallet privateWallet,
     ITransactionBuilder transactionBuilder,
     IBlockchainEventFilter blockchainEventFilter,
     INetworkManager networkManager,
     INodeRetrieval nodeRetrieval,
     IConsensusManager consensusManager
     )
 {
     _transactionManager         = transactionManager;
     _blockManager               = blockManager;
     _configManager              = configManager;
     _stateManager               = stateManager;
     _snapshotIndexer            = snapshotIndexer;
     _transactionPool            = transactionPool;
     _contractRegisterer         = contractRegisterer;
     _validatorStatusManager     = validatorStatusManager;
     _systemContractReader       = systemContractReader;
     _blockSynchronizer          = blockSynchronizer;
     _localTransactionRepository = localTransactionRepository;
     _transactionSigner          = transactionSigner;
     _transactionBuilder         = transactionBuilder;
     _privateWallet              = privateWallet;
     _blockchainEventFilter      = blockchainEventFilter;
     _networkManager             = networkManager;
     _nodeRetrieval              = nodeRetrieval;
     _consensusManager           = consensusManager;
 }
Exemple #6
0
 public MessageHandler(
     IBlockSynchronizer blockSynchronizer,
     ITransactionPool transactionPool,
     IStateManager stateManager,
     IConsensusManager consensusManager,
     IBlockManager blockManager,
     INetworkManager networkManager
     )
 {
     _blockSynchronizer                   = blockSynchronizer;
     _transactionPool                     = transactionPool;
     _stateManager                        = stateManager;
     _consensusManager                    = consensusManager;
     _networkManager                      = networkManager;
     blockManager.OnBlockPersisted       += BlockManagerOnBlockPersisted;
     transactionPool.TransactionAdded    += TransactionPoolOnTransactionAdded;
     _networkManager.OnPingReply         += OnPingReply;
     _networkManager.OnSyncBlocksRequest += OnSyncBlocksRequest;
     _networkManager.OnSyncBlocksReply   += OnSyncBlocksReply;
     _networkManager.OnSyncPoolRequest   += OnSyncPoolRequest;
     _networkManager.OnSyncPoolReply     += OnSyncPoolReply;
     _networkManager.OnConsensusMessage  += OnConsensusMessage;
 }
Exemple #7
0
 public KeyGenManager(
     IBlockManager blockManager,
     ITransactionManager transactionManager,
     ITransactionBuilder transactionBuilder,
     IPrivateWallet privateWallet,
     ITransactionPool transactionPool,
     ITransactionSigner transactionSigner,
     IKeyGenRepository keyGenRepository,
     IBlockSynchronizer blockSynchronizer,
     ISystemContractReader systemContractReader
     )
 {
     _blockManager         = blockManager;
     _transactionManager   = transactionManager;
     _transactionBuilder   = transactionBuilder;
     _privateWallet        = privateWallet;
     _transactionPool      = transactionPool;
     _transactionSigner    = transactionSigner;
     _keyGenRepository     = keyGenRepository;
     _blockSynchronizer    = blockSynchronizer;
     _systemContractReader = systemContractReader;
     _blockManager.OnSystemContractInvoked += BlockManagerOnSystemContractInvoked;
 }
Exemple #8
0
        public NetworkManager(IPeerManager peerManager, IBlockSynchronizer blockSynchronizer, INodeService nodeService, ILogger logger)
        {
            _incomingJobs = new BlockingPriorityQueue <PeerMessageReceivedArgs>();
            _peers        = new List <IPeer>();

            _peerManager       = peerManager;
            _logger            = logger;
            _blockSynchronizer = blockSynchronizer;
            _nodeService       = nodeService;

            peerManager.PeerEvent += OnPeerAdded;

            MessageHub.Instance.Subscribe <TransactionAddedToPool>(inTx =>
            {
                if (inTx?.Transaction == null)
                {
                    _logger?.Warn("[event] Transaction null.");
                    return;
                }

                var txHash = inTx.Transaction.GetHashBytes();

                if (txHash != null)
                {
                    _lastTxReceived.Enqueue(txHash);
                }

                if (_peers == null || !_peers.Any())
                {
                    return;
                }

                BroadcastMessage(AElfProtocolMsgType.NewTransaction, inTx.Transaction.Serialize());
            });

            MessageHub.Instance.Subscribe <BlockMined>(inBlock =>
            {
                if (inBlock?.Block == null)
                {
                    _logger?.Warn("[event] Block null.");
                    return;
                }

                byte[] blockHash = inBlock.Block.GetHash().DumpByteArray();

                if (blockHash != null)
                {
                    _lastBlocksReceived.Enqueue(blockHash);
                }

                AnnounceBlock((Block)inBlock.Block);

                _logger?.Info($"Block produced, announcing {blockHash.ToHex()} to peers ({string.Join("|", _peers)}) with " +
                              $"{inBlock.Block.Body.TransactionsCount} txs, block height {inBlock.Block.Header.Index}.");

                LocalHeight++;
            });

            MessageHub.Instance.Subscribe <BlockAccepted>(inBlock =>
            {
                if (inBlock?.Block == null)
                {
                    _logger?.Warn("[event] Block null.");
                    return;
                }

                // Note - This should not happen during header this
                if (UnlinkableHeaderIndex != 0)
                {
                    return;
                }

                IBlock acceptedBlock = inBlock.Block;

                LocalHeight++;

                var blockHash   = acceptedBlock.GetHash().DumpByteArray();
                var blockHeight = acceptedBlock.Header.Index;

                // todo TEMP
                if (_temp.Contains(blockHash))
                {
                    return;
                }

                _temp.Enqueue(blockHash);

                if (blockHash != null)
                {
                    _lastBlocksReceived.Enqueue(blockHash);
                }

                _logger?.Trace($"Block accepted, announcing {blockHash.ToHex()} to peers ({string.Join("|", _peers)}), " +
                               $"block height {acceptedBlock.Header.Index}.");

                lock (_syncLock)
                {
                    if (CurrentSyncSource == null || !CurrentSyncSource.IsSyncingHistory)
                    {
                        AnnounceBlock(acceptedBlock);
                    }

                    if (CurrentSyncSource == null)
                    {
                        _logger?.Warn("Unexpected situation, executed a block but no peer is currently syncing.");
                    }
                    else if (!CurrentSyncSource.IsSyncing)
                    {
                        _logger?.Warn($"{CurrentSyncSource} is sync source but not in sync state.");
                    }
                    else if (CurrentSyncSource.IsSyncingHistory)
                    {
                        if ((int)blockHeight != CurrentSyncSource.CurrentlyRequestedHeight)
                        {
                            _logger?.Warn($"{CurrentSyncSource} unexpected situation, the block executed was not the exepected height.");
                        }

                        bool hasReqNext = CurrentSyncSource.SyncNextHistory();

                        if (hasReqNext)
                        {
                            return;
                        }

                        _logger?.Trace($"{CurrentSyncSource} history blocks synced, local height {LocalHeight}.");

                        // If this peer still has announcements and the next one is the next block we need.
                        if (CurrentSyncSource.AnyStashed)
                        {
                            if (CurrentSyncSource.SyncNextAnnouncement())
                            {
                                _logger?.Trace($"{CurrentSyncSource} has the next block - started sync.");
                                return;
                            }

                            _logger?.Warn($"{CurrentSyncSource} Failed to start announcement sync.");
                        }
                    }
                    else if (CurrentSyncSource.IsSyncingAnnounced)
                    {
                        // we check if the hash of the accepted block is the one the sync source fetched
                        if (!CurrentSyncSource.SyncedAnnouncement.Id.ToByteArray().BytesEqual(blockHash))
                        {
                            _logger?.Warn($"Block {blockHash.ToHex()} accepted by the chain but not currently synced.");
                        }

                        foreach (var peer in _peers)
                        {
                            // Clear the announcement or any previous announcement to not request
                            // again.
                            peer.CleanAnnouncements((int)blockHeight);
                        }

                        bool hasReqNext = CurrentSyncSource.SyncNextAnnouncement();

                        if (hasReqNext)
                        {
                            return;
                        }

                        _logger?.Trace($"Catched up to announcements with {CurrentSyncSource}.");
                    }

                    var oldSyncSource = CurrentSyncSource;

                    // At this point the current sync source either doesn't have the next announcement
                    // or has none at all.
                    CurrentSyncSource = null;

                    // Try and find a peer with an anouncement that corresponds to the next block we need.
                    foreach (var p in _peers.Where(p => p.AnyStashed && p != oldSyncSource))
                    {
                        if (p.SyncNextAnnouncement())
                        {
                            CurrentSyncSource = p;

                            FireSyncStateChanged(true);
                            _logger?.Debug($"Catching up with {p}.");

                            return;
                        }
                    }

                    if (CurrentSyncSource != null)
                    {
                        _logger?.Error($"The current sync source {CurrentSyncSource} is not null even though sync should be finished.");
                    }

                    FireSyncStateChanged(false);

                    _logger?.Debug("Catched up all peers.");
                }
            });

            MessageHub.Instance.Subscribe <UnlinkableHeader>(unlinkableHeaderMsg =>
            {
                if (unlinkableHeaderMsg?.Header == null)
                {
                    _logger?.Warn("[event] message or header null.");
                    return;
                }

                // The reception of this event means that the chain has discovered
                // that the current block it is trying to execute (height H) is
                // not linkable to the block we have at H-1.

                // At this point we stop all current syncing activities and repetedly
                // download previous headers to the block we couldn't link (in other
                // word "his branch") until we find a linkable block (at wich point
                // the HeaderAccepted event should be launched.

                // note that when this event is called, our knowledge of the local
                // height doesn't mean much.

                lock (_syncLock)
                {
                    // If this is already != 0, it means that the previous batch of
                    // headers was not linked and that more need to be requested.
                    if (UnlinkableHeaderIndex != 0)
                    {
                        // Set state with the first occurence of the unlinkable block
                        UnlinkableHeaderIndex = (int)unlinkableHeaderMsg.Header.Index;
                    }
                    else
                    {
                        CurrentSyncSource = null;

                        // Reset all syncing operations
                        foreach (var peer in _peers)
                        {
                            peer.ResetSync();
                        }

                        LocalHeight = 0;
                    }
                }

                _logger?.Trace($"Header unlinkable, height {unlinkableHeaderMsg.Header.Index}.");

                // Use the peer with the highest target to request headers.
                IPeer target = _peers
                               .Where(p => p.KnownHeight >= (int)unlinkableHeaderMsg.Header.Index)
                               .OrderByDescending(p => p.KnownHeight)
                               .FirstOrDefault();

                if (target == null)
                {
                    _logger?.Warn("[event] no peers to sync from.");
                    return;
                }

                target.RequestHeaders((int)unlinkableHeaderMsg.Header.Index, DefaultHeaderRequestCount);
            });

            MessageHub.Instance.Subscribe <HeaderAccepted>(header =>
            {
                if (header?.Header == null)
                {
                    _logger?.Warn("[event] message or header null.");
                    return;
                }

                if (UnlinkableHeaderIndex != 0)
                {
                    _logger?.Warn("[event] HeaderAccepted but network module not in recovery mode.");
                    return;
                }

                if (CurrentSyncSource != null)
                {
                    // todo possible sync reset
                    _logger?.Warn("[event] current sync source is not null");
                    return;
                }

                lock (_syncLock)
                {
                    // Local height reset
                    LocalHeight = (int)header.Header.Index - 1;

                    // Reset Unlinkable header state
                    UnlinkableHeaderIndex = 0;

                    _logger?.Trace($"[event] header accepted, height {header.Header.Index}, local height reset to {header.Header.Index - 1}.");

                    // Use the peer with the highest target that is higher than our height.
                    IPeer target = _peers
                                   .Where(p => p.KnownHeight > LocalHeight)
                                   .OrderByDescending(p => p.KnownHeight)
                                   .FirstOrDefault();

                    if (target == null)
                    {
                        _logger?.Warn("[event] no peers to sync from.");
                        return;
                    }

                    CurrentSyncSource = target;
                    CurrentSyncSource.SyncToHeight(LocalHeight + 1, target.KnownHeight);

                    FireSyncStateChanged(true);
                }
            });

            MessageHub.Instance.Subscribe <ChainInitialized>(inBlock =>
            {
                _peerManager.Start();
                Task.Run(StartProcessingIncoming).ConfigureAwait(false);
            });
        }