public AuthState CreateAuthringState(AuthorizingMsg msg, bool sourceValid) { _log.LogInformation($"Consensus: CreateAuthringState Called: BlockIndex: {msg.Block.Height}"); AuthState state; if (msg.Block is ServiceBlock sb) { _log.LogInformation($"AllVoters: {Board.AllVoters.Count}"); state = new ServiceBlockAuthState(Worker_OnConsensusSuccessAsync, Board.AllVoters); msg.IsServiceBlock = true; state.SetView(Board.AllVoters); } else { state = new AuthState(Worker_OnConsensusSuccessAsync); msg.IsServiceBlock = false; state.SetView(Board.PrimaryAuthorizers); } state.InputMsg = msg; state.IsSourceValid = sourceValid; return(state); }
public async Task LeaderSendBlockToConsensusAndForgetAsync(Block block) { if (block == null) { throw new ArgumentNullException(); } if (Settings.Default.LyraNode.Lyra.NetworkId == "xtest") { _ = Task.Run(async() => { await OnNewBlock(block); }).ConfigureAwait(false); } else { await Task.Delay(1000); AuthorizingMsg msg = new AuthorizingMsg { From = _sys.PosWallet.AccountId, Block = block, BlockHash = block.Hash, MsgType = ChatMessageType.AuthorizerPrePrepare }; var state = CreateAuthringState(msg, true); await SubmitToConsensusAsync(state); } }
private async Task <(ConsensusResult?, APIResultCodes errorCode)> SendBlockToConsensusAndWaitResultAsync(Block block, List <string> voters = null) // default is genesus, 4 default { if (block == null) { throw new ArgumentNullException(); } AuthorizingMsg msg = new AuthorizingMsg { From = _sys.PosWallet.AccountId, Block = block, BlockHash = block.Hash, MsgType = ChatMessageType.AuthorizerPrePrepare }; var state = CreateAuthringState(msg, true); var sent = await SubmitToConsensusAsync(state); if (sent) { await state.WaitForCloseAsync(); return(state.CommitConsensus, state.GetMajorErrorCode()); } else { return(null, APIResultCodes.DoubleSpentDetected); } }
private AuthorizedMsg LocalAuthorizingAsync(AuthorizingMsg item) { var authorizer = _authorizers[item.Block.BlockType]; var localAuthResult = authorizer.Authorize(item.Block); var result = new AuthorizedMsg { From = NodeService.Instance.PosWallet.AccountId, MsgType = ChatMessageType.AuthorizerPrepare, BlockHash = item.Block.Hash, Result = localAuthResult.Item1, AuthSign = localAuthResult.Item2 }; if (item.Block.BlockType == BlockTypes.Consolidation) { // do nothing. the UIndex has already take cared of. } else { result.BlockUIndex = Mode == ConsensusWorkingMode.Normal ? _UIndexSeed++ : 0; // if seed out of sync, then others know } return(result); }
private async Task <AuthState> PostToConsensusAsync(TransactionBlock block) { _log.LogInformation($"ApiService: PostToConsensusAsync Called: {block.BlockType}"); //AuthorizingMsg msg = new AuthorizingMsg //{ // From = NodeService.Instance.PosWallet.AccountId, // Block = block, // MsgType = ChatMessageType.AuthorizerPrePrepare //}; AuthorizingMsg msg = new AuthorizingMsg { From = NodeService.Instance.PosWallet.AccountId, Block = block, MsgType = ChatMessageType.AuthorizerPrePrepare }; var state = new AuthState(true); state.SetView(await BlockChain.Singleton.GetLastServiceBlockAsync()); state.InputMsg = msg; DagSystem.Singleton.Consensus.Tell(state); await state.Done.AsTask(); state.Done.Close(); state.Done = null; var ts1 = state.T1 == null ? "" : ((int)(DateTime.Now - state.T1).TotalMilliseconds).ToString(); var ts2 = state.T2 == null ? "" : ((int)(DateTime.Now - state.T2).TotalMilliseconds).ToString(); var ts3 = state.T3 == null ? "" : ((int)(DateTime.Now - state.T3).TotalMilliseconds).ToString(); var ts4 = state.T4 == null ? "" : ((int)(DateTime.Now - state.T4).TotalMilliseconds).ToString(); var ts5 = state.T5 == null ? "" : ((int)(DateTime.Now - state.T5).TotalMilliseconds).ToString(); _log.LogInformation($"ApiService Timing:\n{ts1}\n{ts2}\n{ts3}\n{ts4}\n{ts5}\n"); var resultMsg = state.OutputMsgs.Count > 0 ? state.OutputMsgs.First().Result.ToString() : "Unknown"; _log.LogInformation($"ApiService: PostToConsensusAsync Exited: IsAuthoringSuccess: {state?.CommitConsensus == ConsensusResult.Yay} with {resultMsg}"); if (state.CommitConsensus == ConsensusResult.Yay) { return(state); } else { return(null); } }
private void OnPrePrepare(AuthorizingMsg item) { _log.LogInformation($"Consensus: OnPrePrepare Called: BlockUIndex: {item.Block.UIndex}"); var state = CreateAuthringState(item); _ = Task.Run(() => { var result = LocalAuthorizingAsync(item); Send2P2pNetwork(result); state.AddAuthResult(result); CheckAuthorizedAllOk(state); _log.LogInformation($"Consensus: OnPrePrepare LocalAuthorized: {item.Block.UIndex}: {result.IsSuccess}"); }); }
private async Task <AuthState> PostToConsensusAsync(TransactionBlock block) { _log.LogInformation($"ApiService: PostToConsensusAsync Called: {block.BlockType}"); AuthorizingMsg msg = new AuthorizingMsg { From = NodeService.Instance.PosWallet.AccountId, Block = block, MsgType = ChatMessageType.AuthorizerPrePrepare }; var result = await ConsensusSvc.Ask <AuthState>(msg).ConfigureAwait(false); var resultMsg = result.OutputMsgs.Count > 0 ? result.OutputMsgs.First().Result.ToString() : "Unknown"; _log.LogInformation($"ApiService: PostToConsensusAsync Exited: IsAuthoringSuccess: {result?.IsConsensusSuccess == true} with {resultMsg}"); return(result); }
private AuthState CreateAuthringState(AuthorizingMsg item) { _log.LogInformation($"Consensus: CreateAuthringState Called: BlockUIndex: {item.Block.UIndex}"); var ukey = item.Block.Hash; if (_activeConsensus.ContainsKey(ukey)) { return(_activeConsensus[ukey]); } var state = new AuthState { HashOfFirstBlock = ukey, InputMsg = item, }; // add possible out of ordered messages belong to the block if (_outOfOrderedMessages.ContainsKey(item.Block.Hash)) { var msgs = _outOfOrderedMessages[item.Block.Hash]; _outOfOrderedMessages.Remove(item.Block.Hash); foreach (var msg in msgs) { switch (msg) { case AuthorizedMsg authorized: state.AddAuthResult(authorized); break; case AuthorizerCommitMsg committed: state.AddCommitedResult(committed); break; } } } _activeConsensus.Add(ukey, state); return(state); }
private void GenerateConsolidateBlock() { var authGenesis = BlockChain.Singleton.GetLastServiceBlock(); var lastCons = BlockChain.Singleton.GetSyncBlock(); var consBlock = new ConsolidationBlock { UIndex = _UIndexSeed++, NetworkId = authGenesis.NetworkId, ShardId = authGenesis.ShardId, ServiceHash = authGenesis.Hash, SvcAccountID = NodeService.Instance.PosWallet.AccountId }; // use merkle tree to consolidate all previous blocks, from lastCons.UIndex to consBlock.UIndex -1 var mt = new MerkleTree(); for (var ndx = lastCons.UIndex; ndx < consBlock.UIndex; ndx++) // TODO: handling "losing" block here { var block = BlockChain.Singleton.GetBlockByUIndex(ndx); if (block == null) { // block lost _log.LogError($"Block lost for No. {ndx}. Try to resync with other seeds..."); // triggering a resync Mode = ConsensusWorkingMode.OutofSyncWaiting; LyraSystem.Singleton.TheBlockchain.Tell(new BlockChain.NeedSync { ToUIndex = ndx }); return; } var mhash = MerkleHash.Create(block.UHash); mt.AppendLeaf(mhash); } consBlock.MerkelTreeHash = mt.BuildTree().ToString(); consBlock.InitializeBlock(lastCons, NodeService.Instance.PosWallet.PrivateKey, authGenesis.NetworkId, authGenesis.ShardId, NodeService.Instance.PosWallet.AccountId); //consBlock.UHash = SignableObject.CalculateHash($"{consBlock.UIndex}|{consBlock.Index}|{consBlock.Hash}"); //consBlock.Authorizations = new List<AuthorizationSignature>(); //consBlock.Authorizations.Add(new AuthorizationSignature //{ // Key = NodeService.Instance.PosWallet.AccountId, // Signature = Signatures.GetSignature(NodeService.Instance.PosWallet.PrivateKey, consBlock.Hash + consBlock.ServiceHash, NodeService.Instance.PosWallet.AccountId) //}); //BlockChain.Singleton.AddBlock(consBlock); //// broadcast to whole network //var msg = new ChatMsg(NodeService.Instance.PosWallet.AccountId, JsonConvert.SerializeObject(consBlock)); //msg.MsgType = ChatMessageType.BlockConsolidation; //Send2P2pNetwork(msg); // no, we do consensus AuthorizingMsg msg = new AuthorizingMsg { From = NodeService.Instance.PosWallet.AccountId, Block = consBlock, MsgType = ChatMessageType.AuthorizerPrePrepare }; var state = CreateAuthringState(msg); var localAuthResult = LocalAuthorizingAsync(msg); state.AddAuthResult(localAuthResult); if (!localAuthResult.IsSuccess) { _log.LogError("Fatal Error: Consolidate block local authorization failed."); } else { Send2P2pNetwork(msg); Send2P2pNetwork(localAuthResult); } }