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 ); }
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])); }
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); }
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)); }
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)); }
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); } }
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 })
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; }
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; }