当前位置: 首页 > news >正文

专业简历制作网站有哪些提高wordpress打开速度

专业简历制作网站有哪些,提高wordpress打开速度,音乐网站界面,国家免费24小时律师咨询2019独角兽企业重金招聘Python工程师标准 0x00 概论 不同于比特币使用的工作量证明#xff08;PoW#xff09;来实现共识#xff0c;NEO提出了DBFT共识算法。DBFT改良自股权证明算法#xff08;PoS#xff09;#xff0c;我没有具体分析过PoS的源码#x… 2019独角兽企业重金招聘Python工程师标准 0x00 概论 不同于比特币使用的工作量证明PoW来实现共识NEO提出了DBFT共识算法。DBFT改良自股权证明算法PoS我没有具体分析过PoS的源码所以暂时还不是很懂具体哪里做了改动有兴趣的同学可以看下NEO的官方文档。本文主要内容集中在对共识协议源码的分析此外还会有对于一些理论的讲解。关于NEO网络通信部分源码分析我还另外写了一篇博客所以本文中所有涉及到通信的内容我就不再赘述有兴趣的同学可以去看我的另一篇博客。 0x01 获取议员名单 NEO的共识协议类似于西方国家的议会每次区块的生成都在议长主持下由议会成员共同协商生成新的区块。NEO网络节点分为两种一种为共识节点另一种为普通节点。普通节点是不参与NEO新区快生成的对应于普通人共识节点参与共识的过程并且都有机会成为议长主持新区块的生成对应于议员。 看官方文档似乎所有的共识节点都可以到NEO的服务器注册为议员但是貌似成为议员还是有条件的据社区大佬说你账户里至少也要由个把亿才能成为议员所以像我这样的穷逼是没希望了。但是在分析源码的时候我发现似乎并不是这样。源码中在每轮共识开始的时候调用ConsensusContext.cs中的Reset方法在 重置共识的时候会调用Blockchain.Default.GetValidators()来获取议员列表跟进去这个GetValidators()源码 源码位置neo/Core/BlockChain.cs /// summary/// 获取下一个区块的记账人列表/// /summary/// returns返回一组公钥表示下一个区块的记账人列表/returnspublic ECPoint[] GetValidators(){lock (_validators){if (_validators.Count 0){_validators.AddRange(GetValidators(Enumerable.EmptyTransaction()));}return _validators.ToArray();}}发现这里是调用了内部的GetValidators(IEnumerableTransaction others)方法但是这里有点意思这里传过去的参数居然是个空的。再看这个内部的GetValidators方法 源码位置neo/Core/BlockChain.cs public virtual IEnumerableECPoint GetValidators(IEnumerableTransaction others){DataCacheUInt160, AccountState accounts GetStatesUInt160, AccountState();DataCacheECPoint, ValidatorState validators GetStatesECPoint, ValidatorState();MetaDataCacheValidatorsCountState validators_count GetMetaDataValidatorsCountState();foreach (Transaction tx in others){}int count (int)validators_count.Get().Votes.Select((p, i) new{Count i,Votes p}).Where(p p.Votes Fixed8.Zero).ToArray().WeightedFilter(0.25, 0.75, p p.Votes.GetData(), (p, w) new{p.Count,Weight w}).WeightedAverage(p p.Count, p p.Weight);count Math.Max(count, StandbyValidators.Length);HashSetECPoint sv new HashSetECPoint(StandbyValidators);ECPoint[] pubkeys validators.Find().Select(p p.Value).Where(p (p.Registered p.Votes Fixed8.Zero) || sv.Contains(p.PublicKey)).OrderByDescending(p p.Votes).ThenBy(p p.PublicKey).Select(p p.PublicKey).Take(count).ToArray();IEnumerableECPoint result;if (pubkeys.Length count){result pubkeys;}else{HashSetECPoint hashSet new HashSetECPoint(pubkeys);for (int i 0; i StandbyValidators.Length hashSet.Count count; i)hashSet.Add(StandbyValidators[i]);result hashSet;}return result.OrderBy(p p);}我把第一个foreach循环中的代码都删掉了因为明显传进来的others参数为0所以循环体里的代码根本不会有执行的机会。这个方法的返回值是result它值的数据有两个来源。第一个是pubkeyspubkeys来自于本地缓存中的议员信息这个信息是在区块链同步的时候保存的也就是说只要共识节点开始接入区块链网络进行区块同步就会获取到议员信息。而如果没有缓存议员信息或者缓存的议员信息丢失就会使用内置的默认议员列表进行共识之后再在共识的过程中缓存议员信息。 上面说到获取议员信息有两种途径第二种的使用内置默认议员列表是直接将配置文件protocol.json中的数据读取到StandbyValidators字段中。接下来主要介绍第一种途径。 GetValidators方法的第二行调用了GetStates并且传入类的类型是ValidatorState这个方法位于LevelDBBlockChain.cs文件中完整代码如下 源码位置neo/Implementations/BlockChains/LevelDB/LevelDBBlockChain.cs public override DataCacheTKey, TValue GetStatesTKey, TValue(){Type t typeof(TValue);if (t typeof(AccountState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Account);if (t typeof(UnspentCoinState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Coin);if (t typeof(SpentCoinState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_SpentCoin);if (t typeof(ValidatorState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Validator);if (t typeof(AssetState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Asset);if (t typeof(ContractState)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Contract);if (t typeof(StorageItem)) return new DbCacheTKey, TValue(db, DataEntryPrefix.ST_Storage);throw new NotSupportedException();}可以看到这里是直接从leveldb的数据库中读取的议员数据。也就是说在读取数据之前应该要创建/打开数据库才行这部分的操作可以参考neo-cli项目这个项目就在MainService类的OnStart方法中传入了数据库地址。 当然这只是从数据库中获取议员信息向数据库中存入议员信息的工作主要由LevelDBBlockChain.cs文件中的Persist(Block block) 方法负责这个方法接收一个区块类型作为参数主要工作是将同步到的区块信息解析保存。涉及到议员信息的关键代码如下 源码位置:neo/Implementations/BlockChains/LevelDB/LevelDBBlockChain.cs/Persist foreach (ECPoint pubkey in account.Votes){ValidatorState validator validators.GetAndChange(pubkey);validator.Votes - out_prev.Value;if (!validator.Registered validator.Votes.Equals(Fixed8.Zero))validators.Delete(pubkey);}通过调用GetAndChange方法将获取到的议员账户添加到数据库缓存中。 0x02 确定议长 共识节点通过调用ConsensusService类中的Start方法来开始参与共识。在Start方法中首先是注册了消息接收、数据保存等的事件通知之后调用InitializeConsensus开启共识InitializeConsensus方法接收一个整形参数这个参数被称为为视图编号具体视图的定义可以去查看官方文档这里不做解释。当传入的视图编号为0时就意味是着一轮新的共识需要重置共识状态。重置共识状态的代码如下 源码位置neo/Consenus/ConsensusContext.cs /// summary/// 共识状态重置准备发起新一轮共识/// /summary/// param namewallet钱包/parampublic void Reset(Wallet wallet){State ConsensusState.Initial; //设置共识状态为 InitialPrevHash Blockchain.Default.CurrentBlockHash; //获取上一个区块的哈希BlockIndex Blockchain.Default.Height 1; //新区块下标ViewNumber 0; //初始状态 视图编号为0Validators Blockchain.Default.GetValidators(); //获取议员信息MyIndex -1; //当前议员下标初始化PrimaryIndex BlockIndex % (uint)Validators.Length; //确定议长 p (h-v)mod n 此处v 0 TransactionHashes null;Signatures new byte[Validators.Length][];ExpectedView new byte[Validators.Length]; //用于保存众议员当前视图编号KeyPair null;for (int i 0; i Validators.Length; i){//获取自己的议员编号以及密钥WalletAccount account wallet.GetAccount(Validators[i]);if (account?.HasKey true){MyIndex i;KeyPair account.GetKey();break;}}_header null;}}在代码中我添加了详尽的注释确定议长的算法是当前区块高度1 再减去当前的视图编号结果mod上当前的议员人数结果就是议长的下标。议员自己的编号则是自己在议员列表中的位置因为这个位置的排序是根据每个议员的权重所以理论上只要节点的议员成员是一致的那么最终获得的序列也是一致也就是说每个议员的编号在所有的共识节点都是一致的。 在共识节点中除了在共识重置的时候会确定议长之外在每次更新本地视图的时候也会重新确定议长 源码位置neo/Consensus/ConsensusContex.cs /// summary/// 更新共识视图/// /summary/// param nameview_number新的视图编号/parampublic void ChangeView(byte view_number){int p ((int)BlockIndex - view_number) % Validators.Length;//设置共识状态为已发送签名State ConsensusState.SignatureSent;ViewNumber view_number;//议长编号PrimaryIndex p 0 ? (uint)p : (uint)(p Validators.Length);if (State ConsensusState.Initial){TransactionHashes null;Signatures new byte[Validators.Length][];}_header null;}0x03 议长发起共识 议长在更新完视图编号后如果当前时间距离上次写入新区块的时间超过了预定的每轮共识的间隔时间15s则立即开始新一轮的共识否则等到间隔时间后再发起共识时间控制代码如下 源码位置neo/Consensus/ConsencusService.cs/InitializeConsensus //议长发起共识时间控制TimeSpan span DateTime.Now - block_received_time;if (span Blockchain.TimePerBlock)timer.Change(0, Timeout.Infinite); //间隔时间大于预定时间则立即发起共识elsetimer.Change(Blockchain.TimePerBlock - span, Timeout.InfiniteTimeSpan); //定时执行议长进行共识的函数是OnTimeout由定时器定时执行。下面是议长发起共识的核心代码: 源码位置neo/Consencus/ConsensusService.cs/OnTimeOut context.Timestamp Math.Max(DateTime.Now.ToTimestamp(), Blockchain.Default.GetHeader(context.PrevHash).Timestamp 1);context.Nonce GetNonce();//生成区块随机数//获取本地内存中的交易列表ListTransaction transactions LocalNode.GetMemoryPool().Where(p CheckPolicy(p)).ToList();//如果内存中缓存的交易信息数量大于区块最大交易数则对内存中的交易信息进行排序 每字节手续费 越高越先确认交易if (transactions.Count Settings.Default.MaxTransactionsPerBlock)transactions transactions.OrderByDescending(p p.NetworkFee / p.Size).Take(Settings.Default.MaxTransactionsPerBlock - 1).ToList();//添加手续费交易transactions.Insert(0, CreateMinerTransaction(transactions, context.BlockIndex, context.Nonce));context.TransactionHashes transactions.Select(p p.Hash).ToArray();context.Transactions transactions.ToDictionary(p p.Hash);//获取新区块记账人合约地址context.NextConsensus Blockchain.GetConsensusAddress(Blockchain.Default.GetValidators(transactions).ToArray());//生成新区块并签名context.Signatures[context.MyIndex] context.MakeHeader().Sign(context.KeyPair);议长将本地的交易生成新的Header并签名然后将这个Header发送PrepareRequest广播给网络中的议员。 0x04 议员参与共识 议员在收到PrepareRequest广播之后会触发OnPrepareReceived方法 源码位置neo/Consensus/ConsensusService.cs /// summary/// 收到议长共识请求/// /summary/// param namepayload议长的共识参数/param/// param namemessage/paramprivate void OnPrepareRequestReceived(ConsensusPayload payload, PrepareRequest message){Log(${nameof(OnPrepareRequestReceived)}: height{payload.BlockIndex} view{message.ViewNumber} index{payload.ValidatorIndex} tx{message.TransactionHashes.Length});if (!context.State.HasFlag(ConsensusState.Backup) || context.State.HasFlag(ConsensusState.RequestReceived))//当前不处于回退状态或者已经收到了重置请求return;if (payload.ValidatorIndex ! context.PrimaryIndex) return;//只接受议长发起的共识请求if (payload.Timestamp Blockchain.Default.GetHeader(context.PrevHash).Timestamp || payload.Timestamp DateTime.Now.AddMinutes(10).ToTimestamp()){Log($Timestamp incorrect: {payload.Timestamp});return;}context.State | ConsensusState.RequestReceived;//设置状态为收到议长共识请求context.Timestamp payload.Timestamp; //时间戳同步context.Nonce message.Nonce; //区块随机数同步context.NextConsensus message.NextConsensus; context.TransactionHashes message.TransactionHashes; //交易哈希context.Transactions new DictionaryUInt256, Transaction();//议长公钥验证if (!Crypto.Default.VerifySignature(context.MakeHeader().GetHashData(), message.Signature, context.Validators[payload.ValidatorIndex].EncodePoint(false))) return;//添加议长签名到议员签名列表context.Signatures new byte[context.Validators.Length][];context.Signatures[payload.ValidatorIndex] message.Signature;//将内存中缓存的交易添加到共识的context中DictionaryUInt256, Transaction mempool LocalNode.GetMemoryPool().ToDictionary(p p.Hash);foreach (UInt256 hash in context.TransactionHashes.Skip(1)){if (mempool.TryGetValue(hash, out Transaction tx))if (!AddTransaction(tx, false))//从缓存队列中读取添加到contex中return;}if (!AddTransaction(message.MinerTransaction, true)) return; //添加分配字节费的交易 矿工手续费交易LocalNode.AllowHashes(context.TransactionHashes.Except(context.Transactions.Keys));if (context.Transactions.Count context.TransactionHashes.Length)localNode.SynchronizeMemoryPool();}议员在收到议长共识请求之后首先使用议长的公钥对收到的共识信息进行验证在验证通过后将议长的签名添加到签名列表中。然后将内存中缓存并在议长Header的交易哈希列表中的交易添加到context里。 这里需要讲一下这个从内存中添加交易信息到context中的方法 AddTransaction。这个方法在每次添加交易之后都会比较当前context中的交易笔数是否和从议长那里获取的交易哈希数相同如果相同而且记账人合约地址验证通过则广播自己的签名到网络中这部分核心代码如下 源码位置neo/Consensus/ConsensusService.cs/AddTransaction //设置共识状态为已发送签名context.State | ConsensusState.SignatureSent;//添加本地签名到签名列表context.Signatures[context.MyIndex] context.MakeHeader().Sign(context.KeyPair);//广播共识响应SignAndRelay(context.MakePrepareResponse(context.Signatures[context.MyIndex]));//检查签名状态是否符合共识要求CheckSignatures();因为所有的议员都需要同步各个共识节点的签名所以议员节点也需要监听网络中别的节点对议长共识信息的响应并记录签名信息。在每次监听到共识响应并记录了收到的签名信息之后节点需要调用CheckSignatures方法对当前收到的签名信息是否合法进行判断CheckSignatures代码如下 源码位置neo/Consensus/ConsensusService.cs /// summary/// 验证共识协商结果/// /summaryprivate void CheckSignatures(){//验证当前已进行的协商的共识节点数是否合法if (context.Signatures.Count(p p ! null) context.M context.TransactionHashes.All(p context.Transactions.ContainsKey(p))){//建立合约Contract contract Contract.CreateMultiSigContract(context.M, context.Validators);//创建新区块Block block context.MakeHeader();//设置区块参数ContractParametersContext sc new ContractParametersContext(block);for (int i 0, j 0; i context.Validators.Length j context.M; i)if (context.Signatures[i] ! null){sc.AddSignature(contract, context.Validators[i], context.Signatures[i]);j;}//获取用于验证区块的脚本sc.Verifiable.Scripts sc.GetScripts();block.Transactions context.TransactionHashes.Select(p context.Transactions[p]).ToArray();Log($relay block: {block.Hash});//广播新区块if (!localNode.Relay(block))Log($reject block: {block.Hash});//设置当前共识状态为新区块已广播context.State | ConsensusState.BlockSent;}}CheckSignatures方法里首先是对当前签名数的合法性判断。也就是以获取的合法签名数量需要不小于M。M这个值的获取在ConsensusContext类中 public int M Validators.Length - (Validators.Length - 1) / 3;这个值的获取涉及到NEO共识算法的容错能力公式是? ⌊ (?−1) / 3 ⌋理解的话就是只要有超过网络2/3的共识节点是一致的那么这个结果就是可信的。这个理解起来不是很难想看分析的话可以参考官方白皮书。也就是说只要获取到的签名数量合法了当前节点就可以根据已有的信息生成新的区块并向网络中进行广播。 0x05 视图更新 我个人感觉NEO的共识协议里最鸡贼的就是这个视图的概念了。因为NEO网络的共识间隔是用定时任务来做的而不是根据全网算力在数学意义上保证每个区块生成的大概时间。每轮的共识都是由当前选定的议长来发起这就有个很大的问题如果当前选定的议长刚好是个大坏蛋怎么办如果这个议长一直不发起共识或者故意发起错误的共识信息导致本轮共识无法最终完成怎么办为了解决这个问题视图概念被引入在一个视图生存周期完成的时候如果共识还没有被达成则议员会发送广播请求进入下一个视图周期并重新选择议长当请求更新视图的请求大于议员数量的2/3的时候全网达成共识进入下一个视图周期重新开始共识过程。议长的选定算法和视图的编号有关系这保证了每轮视图选定的议长不会是同一个。 视图的生存时间是t*2^(view_number1)其中t是默认的区块生成时间间隔view_number是当前视图编号。议员在每次共识开始的时候进入编号为0的视图周期如果当前周期完成的时候共识没有达成则视图编号1并进入下一个视图周期。定义视图生存时间的代码在ConsensusServer类的InitializeConsensus方法中 源码位置neo/Consensus/ConsensusService.cs/InitializeConsensus context.State ConsensusState.Backup;timer_height context.BlockIndex;timer_view view_number;//议员超时控制 t*2^(view_number1)timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock (view_number 1)), Timeout.InfiniteTimeSpan);当一轮视图周期完成的时候如果共识没有达成则发出更新视图请求 源码位置neo/Consensus/ConsensusService.cs /// summary/// 发送更新视图请求/// /summaryprivate void RequestChangeView(){context.State | ConsensusState.ViewChanging;context.ExpectedView[context.MyIndex];Log($request change view: height{context.BlockIndex} view{context.ViewNumber} nv{context.ExpectedView[context.MyIndex]} state{context.State});//重置视图周期timer.Change(TimeSpan.FromSeconds(Blockchain.SecondsPerBlock (context.ExpectedView[context.MyIndex] 1)), Timeout.InfiniteTimeSpan);//签名并广播更新视图消息SignAndRelay(context.MakeChangeView());//检查是否可以更新视图CheckExpectedView(context.ExpectedView[context.MyIndex]);}更新视图会把当前期望视图1并且广播更新视图的请求给所有的议员。这里需要注意的是在当前节点发送了更新视图的请求之后节点的当前视图编号并没有改变而只是改变了期望视图编号。 其他议员在收到更新视图的广播后会触发OnChangeViewReceived方法来更新自己的议员期望视图列表。 源码位置neo/Consensus/ConsensusService.cs /// summary/// 议员收到更新视图的请求/// /summary/// param namepayload/param/// param namemessage/paramprivate void OnChangeViewReceived(ConsensusPayload payload, ChangeView message){Log(${nameof(OnChangeViewReceived)}: height{payload.BlockIndex} view{message.ViewNumber} index{payload.ValidatorIndex} nv{message.NewViewNumber});//消息中新视图编号比当前所记录的视图编号还小则为过时消息if (message.NewViewNumber context.ExpectedView[payload.ValidatorIndex])return;//更新目标议员期望视图编号context.ExpectedView[payload.ValidatorIndex] message.NewViewNumber;//检查是否符合更新视图要求CheckExpectedView(message.NewViewNumber);}在每次收到更新视图请求之后都需要检查一下当前收到的请求数量是不是大于2/3的全体议员数如果满足条件则在新视图周期里重新开始共识过程。 捐赠地址NEOASCjW4xpfr8kyVHY1J2PgvcgFbPYa1qX7F 转载于:https://my.oschina.net/u/2276921/blog/1621870
http://www.zqtcl.cn/news/317590/

相关文章:

  • 门户网站建设项目书页面设计一般用什么软件
  • 安徽城乡建设 厅网站电子商务网站建设需要哪些步骤
  • 网站建设应该懂什么知识青岛模板网站建设
  • 免费cms建站系统有哪些网站设计项目总结
  • 做网站湖州网站后台管理系统如何使用
  • 网站建设报价单-中英文版长春省妇幼网站做四维
  • 注册网站免费网站上传小马后怎么做
  • 我省推行制度推动山西品牌建设整站优化网站
  • 临海手机网站设计网站设计 深圳
  • 网站推广做哪个比较好百度怎么优化排名
  • 做jsp网站时怎么预览wordpress安装不上
  • 网站建设深圳官网怎么制作网站镜像
  • 弹幕网站开发难么招生网站建设的意义
  • 网站空间多大合适软件开发培训机构网课
  • 13个实用平面设计网站网络推广一个月的收入
  • 淮安企业网站制作校园网网络规划与设计方案
  • html完整网站开发自媒体平台账号注册
  • 厦门seo网站网站空间 群集
  • 青岛网站推广方案营销自动化平台
  • 管理信息系统与网站建设有什么区别python版wordpress
  • 济南市建设行政主管部门网站公众号登录入口官网
  • 深圳苏州企业网站建设服务企业做网站需要什么条件
  • 电脑什么网站可以做长图攻略公众号 微网站开发
  • 网站核检单怎么用小皮创建网站
  • 企业网站托管平台有哪些烟台高新区建设局网站
  • 石家庄网站做网站和县网页定制
  • 网站个人备案和企业备案潍坊公司注册网站
  • 建个网站的流程互联网裁员
  • 设置网站模板汉口网站建设公司
  • 网站对一个关键词做排名怎么做网站建设 图纸网