public void Init() { if (_authorizerInstances != null) { throw new InvalidOperationException("Already initialized."); } _authorizers = new Dictionary <BlockTypes, string>(); _authorizers.Add(BlockTypes.SendTransfer, "SendTransferAuthorizer"); _authorizers.Add(BlockTypes.LyraTokenGenesis, "GenesisAuthorizer"); _authorizers.Add(BlockTypes.ReceiveFee, "ReceiveTransferAuthorizer"); _authorizers.Add(BlockTypes.OpenAccountWithReceiveFee, "NewAccountAuthorizer"); _authorizers.Add(BlockTypes.OpenAccountWithReceiveTransfer, "NewAccountAuthorizer"); _authorizers.Add(BlockTypes.OpenAccountWithImport, "NewAccountWithImportAuthorizer"); _authorizers.Add(BlockTypes.ReceiveTransfer, "ReceiveTransferAuthorizer"); _authorizers.Add(BlockTypes.ImportAccount, "ImportAccountAuthorizer"); _authorizers.Add(BlockTypes.TokenGenesis, "NewTokenAuthorizer"); _authorizers.Add(BlockTypes.Consolidation, "ConsolidationBlockAuthorizer"); _authorizers.Add(BlockTypes.NullTransaction, "NullTransactionAuthorizer"); _authorizers.Add(BlockTypes.Service, "ServiceAuthorizer"); _authorizerInstances = new Dictionary <BlockTypes, IAuthorizer>(); foreach (var kvp in _authorizers) { var authorizer = (IAuthorizer)Activator.CreateInstance(Type.GetType("Lyra.Core.Authorizers." + kvp.Value)); _authorizerInstances.Add(kvp.Key, authorizer); } Singleton = this; }
private async Task <bool> SyncDatabaseAsync(ILyraAPI client) { var consensusClient = client; BlockAPIResult seedSvcGen = null; for (int i = 0; i < 10; i++) { seedSvcGen = await consensusClient.GetServiceGenesisBlockAsync(); if (seedSvcGen.ResultCode == APIResultCodes.Success) { break; } await Task.Delay(10 * 1000); _log.LogInformation("Recreate aggregated client..."); //await client.InitAsync(); } var localDbState = await GetNodeStatusAsync(); if (localDbState.totalBlockCount == 0) { LocalDbSyncState.Remove(); } else { var oldState = LocalDbSyncState.Load(); if (oldState.svcGenHash != seedSvcGen.GetBlock().Hash) { LocalDbSyncState.Remove(); } //if(oldState.databaseVersion > 0 && oldState.databaseVersion < LyraGlobal.DatabaseVersion) //{ // // should upgrade database or resync completely // _sys.Storage.Delete(true); // LocalDbSyncState.Remove(); // localDbState = await GetNodeStatusAsync(); //} } var localState = LocalDbSyncState.Load(); if (localState.svcGenHash == null) { localState.svcGenHash = seedSvcGen.GetBlock().Hash; localState.databaseVersion = LyraGlobal.DatabaseVersion; } var lastCons = (await consensusClient.GetLastConsolidationBlockAsync()).GetBlock() as ConsolidationBlock; if (lastCons == null) { return(false); } bool IsSuccess = true; var _authorizers = new AuthorizersFactory(); while (true) { try { var remoteConsQuery = await consensusClient.GetConsolidationBlocksAsync(_sys.PosWallet.AccountId, null, localState.lastVerifiedConsHeight + 1, 1); if (remoteConsQuery.ResultCode == APIResultCodes.Success) { var remoteConsBlocks = remoteConsQuery.GetBlocks(); if (remoteConsBlocks.Any()) { foreach (var block in remoteConsBlocks) { var consTarget = block as ConsolidationBlock; _log.LogInformation($"SyncDatabase: Sync consolidation block {consTarget.Height} of total {lastCons.Height}."); if (await SyncAndVerifyConsolidationBlockAsync(consensusClient, consTarget)) { _log.LogInformation($"Consolidation block {consTarget.Height} is OK."); localState.lastVerifiedConsHeight = consTarget.Height; LocalDbSyncState.Save(localState); } else { throw new Exception($"Consolidation block {consTarget.Height} is failure."); } } } else { IsSuccess = true; break; } } else if (remoteConsQuery.ResultCode == APIResultCodes.APIRouteFailed) { _log.LogWarning("Got inconsistant result from network. retry later."); throw new Exception("Failed to sync. reason: " + remoteConsQuery.ResultCode); } else { _log.LogWarning($"Unexpected error {remoteConsQuery.ResultCode}: {remoteConsQuery.ResultMessage}. retry later."); throw new Exception($"Failed to sync. reason: {remoteConsQuery.ResultCode}: {remoteConsQuery.ResultMessage}"); } } catch (Exception ex) { _log.LogWarning("SyncDatabase Exception: " + ex.Message); await Task.Delay(30000); IsSuccess = false; break; } } return(IsSuccess); }
public void Init() { if (_authorizerInstances != null) { return; } //throw new InvalidOperationException("Already initialized."); _authorizers = new Dictionary <BlockTypes, Type>(); _authorizerInstances = new Dictionary <BlockTypes, IAuthorizer>(); var exporters = typeof(BaseAuthorizer) .Assembly.GetTypes() .Where(t => t.IsSubclassOf(typeof(BaseAuthorizer)) && !t.IsAbstract) .Select(t => new { b = (IAuthorizer)Activator.CreateInstance(t), t }); foreach (var entry in exporters) { BlockTypes bt; try { bt = entry.b.GetBlockType(); //Console.WriteLine($"{bt}: {entry.t.Name}"); if (bt != BlockTypes.Null) { Register(bt, entry.t); } } catch (Exception ex) { Console.WriteLine($"Error register authorizer: {entry.t}"); } } var depreteds = new[] { BlockTypes.Null, BlockTypes.Sync, BlockTypes.OpenAccountWithReceiveFee, BlockTypes.OpenAccountWithImport, BlockTypes.ReceiveFee, BlockTypes.ImportAccount, BlockTypes.ReceiveMultipleFee, BlockTypes.ReceiveAuthorizerFee, BlockTypes.TradeOrder, BlockTypes.Trade, BlockTypes.ExecuteTradeOrder, BlockTypes.CancelTradeOrder, }; // make sure every blocktype has an authrorizer foreach (var t in Enum.GetValues(typeof(BlockTypes))) { if (depreteds.Any(a => a == (BlockTypes)t)) { continue; } if (!_authorizers.ContainsKey((BlockTypes)t)) { Console.WriteLine($"Authorizers Missing {t}"); } } /* * _authorizers.Add(BlockTypes.SendTransfer, typeof(SendTransferAuthorizer)); * * _authorizers.Add(BlockTypes.ReceiveFee, typeof(ReceiveTransferAuthorizer)); * //_authorizers.Add(BlockTypes.ReceiveNodeProfit, "ReceiveNodeProfitAuthorizer"); * _authorizers.Add(BlockTypes.OpenAccountWithReceiveFee, typeof(NewAccountAuthorizer)); * _authorizers.Add(BlockTypes.OpenAccountWithReceiveTransfer, typeof(NewAccountAuthorizer)); * //_authorizers.Add(BlockTypes.OpenAccountWithImport, "NewAccountWithImportAuthorizer"); * _authorizers.Add(BlockTypes.ReceiveTransfer, typeof(ReceiveTransferAuthorizer)); * //_authorizers.Add(BlockTypes.ImportAccount, "ImportAccountAuthorizer"); * _authorizers.Add(BlockTypes.Consolidation, typeof(ConsolidationBlockAuthorizer)); * _authorizers.Add(BlockTypes.Service, typeof(ServiceAuthorizer)); * _authorizers.Add(BlockTypes.TradeOrder, typeof(TradeOrderAuthorizer)); * _authorizers.Add(BlockTypes.Trade, typeof(TradeAuthorizer)); * _authorizers.Add(BlockTypes.CancelTradeOrder, typeof(CancelTradeOrderAuthorizer)); //HACK: wait for code check in * _authorizers.Add(BlockTypes.ExecuteTradeOrder, typeof(ExecuteTradeOrderAuthorizer)); * _authorizers.Add(BlockTypes.PoolFactory, typeof(PoolFactoryAuthorizer)); * * // pool, not needed * //_authorizers.Add(BlockTypes.PoolGenesis, "PoolGenesisAuthorizer"); * //_authorizers.Add(BlockTypes.PoolDeposit, "PoolDepositAuthorizer"); * //_authorizers.Add(BlockTypes.PoolWithdraw, "PoolWithdrawAuthorizer"); * //_authorizers.Add(BlockTypes.PoolSwapIn, "PoolSwapInAuthorizer"); * //_authorizers.Add(BlockTypes.PoolSwapOut, "PoolSwapOutAuthorizer"); * * //_authorizers.Add(BlockTypes.ProfitingGenesis, "ProfitingGenesisAuthorizer"); * //_authorizers.Add(BlockTypes.Profiting, "ProfitingAuthorizer"); * //_authorizers.Add(BlockTypes.Benefiting, "BenefitingAuthorizer"); * * //_authorizers.Add(BlockTypes.StakingGenesis, "StakingGenesisAuthorizer"); * //_authorizers.Add(BlockTypes.Staking, "StakingAuthorizer"); * //_authorizers.Add(BlockTypes.UnStaking, "UnStakingAuthorizer"); * * * _authorizers.Add(BlockTypes.ReceiveAsFee, typeof(ReceiveAsFeeAuthorizer)); * _authorizers.Add(BlockTypes.LyraTokenGenesis, typeof(LyraGenesisAuthorizer)); * _authorizers.Add(BlockTypes.TokenGenesis, typeof(TokenGenesisAuthorizer)); * * // DEX * //_authorizers.Add(BlockTypes.DexWalletGenesis, "DexWalletGenesisAuthorizer"); * //_authorizers.Add(BlockTypes.DexTokenMint, "DexTokenMintAuthorizer"); * //_authorizers.Add(BlockTypes.DexTokenBurn, "DexTokenBurnAuthorizer"); * //_authorizers.Add(BlockTypes.DexWithdrawToken, "DexWithdrawAuthorizer"); * //_authorizers.Add(BlockTypes.DexSendToken, "DexSendAuthorizer"); * //_authorizers.Add(BlockTypes.DexRecvToken, "DexReceiveAuthorizer"); * * // DAO Note: not needed. dynamic work flow did this. * //_authorizers.Add(BlockTypes.Orgnization, "DaoAuthorizer"); * //_authorizers.Add(BlockTypes.OrgnizationGenesis, "DaoGenesisAuthorizer"); * * _authorizerInstances = new Dictionary<BlockTypes, IAuthorizer>(); * foreach(var kvp in _authorizers) * { * var authorizer = (IAuthorizer)Activator.CreateInstance(kvp.Value); * _authorizerInstances.Add(kvp.Key, authorizer); * } * * //_wfAuthorizer = new TransactionAuthorizer(); */ Singleton = this; }
public ConsensusService(IActorRef localNode) { _localNode = localNode; _log = new SimpleLogger("ConsensusService").Logger; _outOfOrderedMessages = new Dictionary <string, List <SourceSignedMessage> >(); _activeConsensus = new Dictionary <string, AuthState>(); _authorizers = new AuthorizersFactory(); while (BlockChain.Singleton == null) { Task.Delay(100).Wait(); } _UIndexSeed = BlockChain.Singleton.GetBlockCount() + 1; Mode = ConsensusWorkingMode.OutofSyncWaiting; Receive <Consolidate>((_) => { _log.LogInformation("Doing Consolidate"); OnNodeActive(NodeService.Instance.PosWallet.AccountId); // update billboard if (Mode == ConsensusWorkingMode.Normal) { BroadCastBillBoard(); GenerateConsolidateBlock(); } }); Receive <BillBoard>((bb) => { _board = bb; }); Receive <AskForBillboard>((_) => Sender.Tell(_board)); Receive <AuthorizingMsg>(async msg => { if (msg.Version != LyraGlobal.ProtocolVersion) { Sender.Tell(null); } OnNodeActive(NodeService.Instance.PosWallet.AccountId); // update billboard // first try auth locally var state = CreateAuthringState(msg); var localAuthResult = LocalAuthorizingAsync(msg); state.AddAuthResult(localAuthResult); if (!localAuthResult.IsSuccess) { state.Done.Set(); Sender.Tell(state); } else { Send2P2pNetwork(msg); Send2P2pNetwork(localAuthResult); var sender = Context.Sender; await Task.Run(() => { _ = state.Done.WaitOne(); }).ConfigureAwait(false); sender.Tell(state); } }); Receive <SignedMessageRelay>(relayMsg => { if (relayMsg.signedMessage.Version == LyraGlobal.ProtocolVersion) { OnNextConsensusMessage(relayMsg.signedMessage); } else { _log.LogWarning("Protocol Version Mismatch. Do nothing."); } }); Receive <BlockChainSynced>(_ => { Mode = ConsensusWorkingMode.Normal; _UIndexSeed = BlockChain.Singleton.GetBlockCount() + 1; // declare to the network var msg = new ChatMsg { From = NodeService.Instance.PosWallet.AccountId, MsgType = ChatMessageType.NodeUp, Text = "Staking with () Lyra" }; Send2P2pNetwork(msg); }); Task.Run(async() => { while (true) { StateClean(); await Task.Delay(1000).ConfigureAwait(false); } }); }