コード例 #1
0
        public DevLibplanetNodeService(
            LibplanetNodeServiceProperties <T> properties,
            IBlockPolicy <T> easyPolicy,
            IBlockPolicy <T> hardPolicy,
            IStagePolicy <T> stagePolicy,
            IEnumerable <IRenderer <T> > renderers,
            Func <Swarm <T>, Swarm <T>, PrivateKey, CancellationToken, Task> minerLoopAction,
            Progress <PreloadState> preloadProgress,
            Action <RPCException, string> exceptionHandlerAction,
            Action <bool> preloadStatusHandlerAction,
            bool ignoreBootstrapFailure = false
            ) : base(properties, easyPolicy, stagePolicy, renderers, null, preloadProgress, exceptionHandlerAction, preloadStatusHandlerAction, ignoreBootstrapFailure)
        {
            if (easyPolicy is null)
            {
                throw new ArgumentNullException(nameof(easyPolicy));
            }

            if (hardPolicy is null)
            {
                throw new ArgumentNullException(nameof(hardPolicy));
            }

            Log.Debug("Initializing node service.");

            var genesisBlock = LoadGenesisBlock(properties);

            var iceServers = properties.IceServers;

            (SubStore, SubStateStore) = LoadStore(
                properties.StorePath is null ? null : Path.Combine(properties.StorePath, "sub"),
                properties.StoreType,
                properties.StoreStatesCacheSize);

            SubChain = new BlockChain <T>(
                policy: hardPolicy,
                stagePolicy: stagePolicy,
                store: SubStore,
                stateStore: SubStateStore,
                genesisBlock: genesisBlock
                );

            _minerLoopAction = minerLoopAction;
            var subSwarmPrivateKey = new PrivateKey();

            Log.Debug(
                "Address of sub-swarm is: {address}",
                subSwarmPrivateKey.ToAddress());
            SubSwarm = new Swarm <T>(
                SubChain,
                subSwarmPrivateKey,
                properties.AppProtocolVersion,
                trustedAppProtocolVersionSigners: properties.TrustedAppProtocolVersionSigners,
                host: "localhost",
                listenPort: properties.Port + 1,
                iceServers: iceServers,
                workers: properties.Workers
                );
        }
コード例 #2
0
ファイル: SwarmBenchmark.cs プロジェクト: tor0405/libplanet
 public SwarmBenchmark()
 {
     _policy      = new NullPolicy <DumbAction>();
     _stagePolicy = new VolatileStagePolicy <DumbAction>();
     _blocks      = new List <Block <DumbAction> >
     {
         TestUtils.MineGenesis <DumbAction>(),
     };
     _appProtocolVersion = AppProtocolVersion.Sign(new PrivateKey(), 1);
     _blocks.Add(TestUtils.MineNext(_blocks[0]));
     _blocks.Add(TestUtils.MineNext(_blocks[1]));
     _blocks.Add(TestUtils.MineNext(_blocks[2]));
     _blocks.Add(TestUtils.MineNext(_blocks[3]));
 }
コード例 #3
0
 public BlockPolicyTest(ITestOutputHelper output)
 {
     _fx     = new MemoryStoreFixture();
     _output = output;
     _policy = new BlockPolicy <DumbAction>(
         blockAction: null,
         blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000));
     _stagePolicy = new VolatileStagePolicy <DumbAction>();
     _chain       = new BlockChain <DumbAction>(
         _policy,
         _stagePolicy,
         _fx.Store,
         _fx.StateStore,
         _fx.GenesisBlock);
 }
コード例 #4
0
 public SwarmBenchmark()
 {
     _policy      = new NullPolicy <DumbAction>();
     _stagePolicy = new VolatileStagePolicy <DumbAction>();
     _miner       = TestUtils.ChainPrivateKey;
     _blocks      = new List <Block <DumbAction> >
     {
         TestUtils.MineGenesisBlock <DumbAction>(_policy.GetHashAlgorithm, _miner),
     };
     _appProtocolVersion = AppProtocolVersion.Sign(new PrivateKey(), 1);
     _blocks.Add(TestUtils.MineNextBlock(_blocks[0], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[1], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[2], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[3], _policy.GetHashAlgorithm, _miner));
 }
コード例 #5
0
        public static BlockChain <NCAction> MakeBlockChain(
            BlockRenderer[] blockRenderers,
            IBlockPolicy <NCAction> policy      = null,
            IStagePolicy <NCAction> stagePolicy = null,
            IStore store           = null,
            IStateStore stateStore = null)
        {
            PrivateKey adminPrivateKey = new PrivateKey();

            policy ??= new BlockPolicy <NCAction>();
            stagePolicy ??= new VolatileStagePolicy <NCAction>();
            store ??= new DefaultStore(null);
            stateStore ??= new TrieStateStore(new DefaultKeyValueStore(null));
            Block <NCAction> genesis = MakeGenesisBlock(adminPrivateKey.ToAddress(), ImmutableHashSet <Address> .Empty);

            return(new BlockChain <NCAction>(policy, stagePolicy, store, stateStore, genesis, renderers: blockRenderers));
        }
コード例 #6
0
        private void ProcessTxIds(TxIds message)
        {
            if (!(message.Remote is BoundPeer peer))
            {
                _logger.Information(
                    $"Ignores a {nameof(TxIds)} message because it was sent by an invalid peer: " +
                    "{PeerAddress}.",
                    message.Remote?.Address.ToHex()
                    );
                return;
            }

            _logger.Debug(
                $"Received a {nameof(TxIds)} message: {{@TxIds}}.",
                message.Ids.Select(txid => txid.ToString())
                );

            IStagePolicy <T>        stagePolicy = BlockChain.StagePolicy;
            ImmutableHashSet <TxId> newTxIds    = message.Ids
                                                  .Where(id => !_demandTxIds.ContainsKey(id))
                                                  .Where(id => !stagePolicy.HasStaged(BlockChain, id, true))
                                                  .ToImmutableHashSet();

            if (!newTxIds.Any())
            {
                _logger.Debug("No unaware transactions to receive.");
                return;
            }

            _logger.Debug(
                "Unaware transactions to receive: {@TxIds}.",
                newTxIds.Select(txid => txid.ToString())
                );
            foreach (TxId txid in newTxIds)
            {
                _demandTxIds.TryAdd(txid, peer);
            }
        }
コード例 #7
0
        public NineChroniclesNodeService(
            PrivateKey?minerPrivateKey,
            LibplanetNodeServiceProperties <NCAction> properties,
            Progress <PreloadState>?preloadProgress = null,
            bool ignoreBootstrapFailure             = false,
            bool ignorePreloadFailure = false,
            bool strictRendering      = false,
            bool authorizedMiner      = false,
            bool isDev          = false,
            int blockInterval   = 10000,
            int reorgInterval   = 0,
            TimeSpan txLifeTime = default,
            int minerCount      = 1
            )
        {
            MinerPrivateKey = minerPrivateKey;
            Properties      = properties;

            LogEventLevel logLevel          = LogEventLevel.Debug;
            var           blockPolicySource = new BlockPolicySource(Log.Logger, logLevel);
            // BlockPolicy shared through Lib9c.
            IBlockPolicy <NCAction>?blockPolicy = null;
            // Policies for dev mode.
            IBlockPolicy <NCAction>?easyPolicy  = null;
            IBlockPolicy <NCAction>?hardPolicy  = null;
            IStagePolicy <NCAction> stagePolicy =
                txLifeTime == default
                    ? new VolatileStagePolicy <NCAction>()
                    : new VolatileStagePolicy <NCAction>(txLifeTime);

            if (isDev)
            {
                easyPolicy = new ReorgPolicy(new RewardGold(), 1);
                hardPolicy = new ReorgPolicy(new RewardGold(), 2);
            }
            else
            {
                blockPolicy = blockPolicySource.GetPolicy(properties.MinimumDifficulty, properties.MaximumTransactions);
            }

            BlockRenderer      = blockPolicySource.BlockRenderer;
            ActionRenderer     = blockPolicySource.ActionRenderer;
            ExceptionRenderer  = new ExceptionRenderer();
            NodeStatusRenderer = new NodeStatusRenderer();
            var renderers      = new List <IRenderer <NCAction> >();
            var strictRenderer = new StrictRenderer(onError: exc =>
                                                    ExceptionRenderer.RenderException(
                                                        RPCException.InvalidRenderException,
                                                        exc.Message.Split("\n")[0]
                                                        )
                                                    );

            if (Properties.Render)
            {
                renderers.Add(blockPolicySource.BlockRenderer);
                renderers.Add(blockPolicySource.LoggedActionRenderer);
            }
            else if (Properties.LogActionRenders)
            {
                renderers.Add(blockPolicySource.BlockRenderer);
                // The following "nullRenderer" does nothing.  It's just for filling
                // the LoggedActionRenderer<T>() constructor's parameter:
                IActionRenderer <NCAction> nullRenderer =
                    new AnonymousActionRenderer <NCAction>();
                renderers.Add(
                    new LoggedActionRenderer <NCAction>(
                        nullRenderer,
                        Log.Logger,
                        logLevel
                        )
                    );
            }
            else
            {
                renderers.Add(blockPolicySource.LoggedBlockRenderer);
            }

            if (strictRendering)
            {
                Log.Debug(
                    $"Strict rendering is on. Add {nameof(StrictRenderer)}.");
                renderers.Add(strictRenderer);
            }

            async Task minerLoopAction(
                BlockChain <NCAction> chain,
                Swarm <NCAction> swarm,
                PrivateKey privateKey,
                CancellationToken cancellationToken)
            {
                var miner = new Miner(chain, swarm, privateKey, authorizedMiner);

                Log.Debug("Miner called.");
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        long nextBlockIndex = chain.Tip.Index + 1;
                        bool authBlock      = blockPolicy is BlockPolicy bp
                                              // Copied from https://git.io/JLxNd
                                              && nextBlockIndex > 0 &&
                                              nextBlockIndex <= bp.AuthorizedMinersState?.ValidUntil &&
                                              nextBlockIndex % bp.AuthorizedMinersState?.Interval == 0;
                        if (swarm.Running && ((authorizedMiner && authBlock) || (!authorizedMiner && !authBlock)))
                        {
                            Log.Debug("Start mining.");

                            IEnumerable <Task <Block <NCAction> > > miners = Enumerable
                                                                             .Range(0, minerCount)
                                                                             .Select(_ => miner.MineBlockAsync(properties.MaximumTransactions, cancellationToken));
                            await Task.WhenAll(miners);
                        }
                        else
                        {
                            await Task.Delay(1000, cancellationToken);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Exception occurred.");
                    }
                }
            }

            async Task devMinerLoopAction(
                Swarm <NCAction> mainSwarm,
                Swarm <NCAction> subSwarm,
                PrivateKey privateKey,
                CancellationToken cancellationToken)
            {
                var miner = new ReorgMiner(mainSwarm, subSwarm, privateKey, reorgInterval);

                Log.Debug("Miner called.");
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        if (mainSwarm.Running)
                        {
                            Log.Debug("Start mining.");
                            await miner.MineBlockAsync(properties.MaximumTransactions, cancellationToken);

                            await Task.Delay(blockInterval, cancellationToken);
                        }
                        else
                        {
                            await Task.Delay(1000, cancellationToken);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Exception occurred.");
                    }
                }
            }

            if (isDev)
            {
                NodeService = new DevLibplanetNodeService <NCAction>(
                    Properties,
                    easyPolicy,
                    hardPolicy,
                    stagePolicy,
                    renderers,
                    devMinerLoopAction,
                    preloadProgress,
                    (code, msg) =>
                {
                    ExceptionRenderer.RenderException(code, msg);
                    Log.Error(msg);
                },
                    isPreloadStarted => { NodeStatusRenderer.PreloadStatus(isPreloadStarted); },
                    ignoreBootstrapFailure
                    );
            }
            else
            {
                NodeService = new LibplanetNodeService <NCAction>(
                    Properties,
                    blockPolicy,
                    stagePolicy,
                    renderers,
                    minerLoopAction,
                    preloadProgress,
                    (code, msg) =>
                {
                    ExceptionRenderer.RenderException(code, msg);
                    Log.Error(msg);
                },
                    isPreloadStarted =>
                {
                    NodeStatusRenderer.PreloadStatus(isPreloadStarted);
                },
                    ignoreBootstrapFailure,
                    ignorePreloadFailure
                    );
            }

            strictRenderer.BlockChain = NodeService.BlockChain ?? throw new Exception("BlockChain is null.");
            if (NodeService.BlockChain?.GetState(AuthorizedMinersState.Address) is Dictionary ams &&
                blockPolicy is BlockPolicy bp)
            {
                bp.AuthorizedMinersState = new AuthorizedMinersState(ams);
            }

            if (authorizedMiner && blockPolicy is BlockPolicy {
                AuthorizedMinersState : null
            })
コード例 #8
0
        public LibplanetNodeService(
            LibplanetNodeServiceProperties <T> properties,
            IBlockPolicy <T> blockPolicy,
            IStagePolicy <T> stagePolicy,
            IEnumerable <IRenderer <T> > renderers,
            Func <BlockChain <T>, Swarm <T>, PrivateKey, CancellationToken, Task> minerLoopAction,
            Progress <PreloadState> preloadProgress,
            Action <RPCException, string> exceptionHandlerAction,
            Action <bool> preloadStatusHandlerAction,
            bool ignoreBootstrapFailure = false,
            bool ignorePreloadFailure   = false
            )
        {
            if (blockPolicy is null)
            {
                throw new ArgumentNullException(nameof(blockPolicy));
            }

            Properties = properties;

            var genesisBlock = LoadGenesisBlock(properties);

            var iceServers = Properties.IceServers;

            (Store, StateStore) = LoadStore(
                Properties.StorePath,
                Properties.StoreType,
                Properties.StoreStatesCacheSize);

            var pendingTxs = Store.IterateStagedTransactionIds()
                             .ToImmutableHashSet();

            Store.UnstageTransactionIds(pendingTxs);
            Log.Debug("Pending txs unstaged. [{PendingCount}]", pendingTxs.Count);

            var chainIds = Store.ListChainIds().ToList();

            Log.Debug($"Number of chain ids: {chainIds.Count()}");

            if (Properties.Confirmations > 0)
            {
                IComparer <BlockPerception> comparer = blockPolicy.CanonicalChainComparer;
                renderers = renderers.Select(r => r is IActionRenderer <T> ar
                    ? new DelayedActionRenderer <T>(ar, comparer, Store, Properties.Confirmations, 50)
                    : new DelayedRenderer <T>(r, comparer, Store, Properties.Confirmations)
                                             );

                // Log the outmost (before delayed) events as well as
                // the innermost (after delayed) events:
                ILogger logger = Log.ForContext("SubLevel", " RAW-RENDER-EVENT");
                renderers = renderers.Select(r => r is IActionRenderer <T> ar
                    ? new LoggedActionRenderer <T>(ar, logger, LogEventLevel.Debug)
                    : new LoggedRenderer <T>(r, logger, LogEventLevel.Debug)
                                             );
            }

            BlockChain = new BlockChain <T>(
                policy: blockPolicy,
                store: Store,
                stagePolicy: stagePolicy,
                stateStore: StateStore,
                genesisBlock: genesisBlock,
                renderers: renderers
                );

            _obsoletedChainIds = chainIds.Where(chainId => chainId != BlockChain.Id).ToList();

            _minerLoopAction            = minerLoopAction;
            _exceptionHandlerAction     = exceptionHandlerAction;
            _preloadStatusHandlerAction = preloadStatusHandlerAction;
            IEnumerable <IceServer> shuffledIceServers = null;

            if (!(iceServers is null))
            {
                var rand = new Random();
                shuffledIceServers = iceServers.OrderBy(x => rand.Next());
            }

            Swarm = new Swarm <T>(
                BlockChain,
                Properties.SwarmPrivateKey,
                Properties.AppProtocolVersion,
                trustedAppProtocolVersionSigners: Properties.TrustedAppProtocolVersionSigners,
                host: Properties.Host,
                listenPort: Properties.Port,
                iceServers: shuffledIceServers,
                workers: Properties.Workers,
                differentAppProtocolVersionEncountered: Properties.DifferentAppProtocolVersionEncountered,
                options: new SwarmOptions
            {
                MaxTimeout           = TimeSpan.FromSeconds(10),
                BlockHashRecvTimeout = TimeSpan.FromSeconds(10),
            }
                );

            PreloadEnded   = new AsyncManualResetEvent();
            BootstrapEnded = new AsyncManualResetEvent();

            PreloadProgress        = preloadProgress;
            IgnoreBootstrapFailure = ignoreBootstrapFailure;
            _ignorePreloadFailure  = ignorePreloadFailure;
        }
コード例 #9
0
        public LibplanetNodeService(
            LibplanetNodeServiceProperties <T> properties,
            IBlockPolicy <T> blockPolicy,
            IStagePolicy <T> stagePolicy,
            IEnumerable <IRenderer <T> > renderers,
            Func <BlockChain <T>, Swarm <T>, PrivateKey, CancellationToken, Task> minerLoopAction,
            Progress <PreloadState> preloadProgress,
            Action <RPCException, string> exceptionHandlerAction,
            Action <bool> preloadStatusHandlerAction,
            bool ignoreBootstrapFailure = false,
            bool ignorePreloadFailure   = false
            )
        {
            if (blockPolicy is null)
            {
                throw new ArgumentNullException(nameof(blockPolicy));
            }

            Properties = properties;

            var genesisBlock = LoadGenesisBlock(properties, blockPolicy.GetHashAlgorithm);

            var iceServers = Properties.IceServers;

            (Store, StateStore) = LoadStore(
                Properties.StorePath,
                Properties.StoreType,
                Properties.StoreStatesCacheSize);

            var chainIds = Store.ListChainIds().ToList();

            Log.Debug($"Number of chain ids: {chainIds.Count()}");
            Log.Debug($"Canonical chain id: {Store.GetCanonicalChainId().ToString()}");

            if (Properties.Confirmations > 0)
            {
                HashAlgorithmGetter       getHashAlgo = blockPolicy.GetHashAlgorithm;
                IComparer <IBlockExcerpt> comparer    = blockPolicy.CanonicalChainComparer;
                int confirms = Properties.Confirmations;
                renderers = renderers.Select(r => r is IActionRenderer <T> ar
                    ? new DelayedActionRenderer <T>(ar, comparer, Store, getHashAlgo, confirms, 50)
                    : new DelayedRenderer <T>(r, comparer, Store, getHashAlgo, confirms)
                                             );

                // Log the outmost (before delayed) events as well as
                // the innermost (after delayed) events:
                ILogger logger = Log.ForContext("SubLevel", " RAW-RENDER-EVENT");
                renderers = renderers.Select(r => r is IActionRenderer <T> ar
                    ? new LoggedActionRenderer <T>(ar, logger, LogEventLevel.Debug)
                    : new LoggedRenderer <T>(r, logger, LogEventLevel.Debug)
                                             );
            }

            if (Properties.NonblockRenderer)
            {
                renderers = renderers.Select(r =>
                {
                    if (r is IActionRenderer <T> ar)
                    {
                        return(new NonblockActionRenderer <T>(
                                   ar,
                                   Properties.NonblockRendererQueue,
                                   NonblockActionRenderer <T> .FullMode.DropOldest
                                   ));
                    }
                    else
                    {
                        return(new NonblockRenderer <T>(
                                   r,
                                   Properties.NonblockRendererQueue,
                                   NonblockActionRenderer <T> .FullMode.DropOldest
                                   ));
                    }
                });
            }

            BlockChain = new BlockChain <T>(
                policy: blockPolicy,
                store: Store,
                stagePolicy: stagePolicy,
                stateStore: StateStore,
                genesisBlock: genesisBlock,
                renderers: renderers
                );

            _obsoletedChainIds = chainIds.Where(chainId => chainId != BlockChain.Id).ToList();

            _minerLoopAction            = minerLoopAction;
            _exceptionHandlerAction     = exceptionHandlerAction;
            _preloadStatusHandlerAction = preloadStatusHandlerAction;
            IEnumerable <IceServer> shuffledIceServers = null;

            if (!(iceServers is null))
            {
                var rand = new Random();
                shuffledIceServers = iceServers.OrderBy(x => rand.Next());
            }

            Swarm = new Swarm <T>(
                BlockChain,
                Properties.SwarmPrivateKey,
                Properties.AppProtocolVersion,
                trustedAppProtocolVersionSigners: Properties.TrustedAppProtocolVersionSigners,
                host: Properties.Host,
                listenPort: Properties.Port,
                iceServers: shuffledIceServers,
                workers: Properties.Workers,
                differentAppProtocolVersionEncountered: Properties.DifferentAppProtocolVersionEncountered,
                options: new SwarmOptions
            {
                MaxTimeout             = TimeSpan.FromSeconds(50),
                BlockHashRecvTimeout   = TimeSpan.FromSeconds(50),
                BlockRecvTimeout       = TimeSpan.FromSeconds(5),
                BranchpointThreshold   = 50,
                StaticPeers            = Properties.StaticPeers,
                MinimumBroadcastTarget = Properties.MinimumBroadcastTarget,
                BucketSize             = Properties.BucketSize,
                PollInterval           = Properties.PollInterval,
                MaximumPollPeers       = Properties.MaximumPollPeers
            }
                );

            PreloadEnded   = new AsyncManualResetEvent();
            BootstrapEnded = new AsyncManualResetEvent();

            PreloadProgress        = preloadProgress;
            IgnoreBootstrapFailure = ignoreBootstrapFailure;
            _ignorePreloadFailure  = ignorePreloadFailure;
        }