private async Task <LyraRestClient> FindValidSeedForSyncAsync() { do { var rand = new Random(); int ndx; do { ndx = rand.Next(0, ProtocolSettings.Default.SeedList.Length); } while (NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[ndx]); var addr = ProtocolSettings.Default.SeedList[ndx].Split(':')[0]; var apiUrl = $"https://{addr}:4505/api/LyraNode/"; _log.LogInformation("Platform {1} Use seed node of {0}", apiUrl, Environment.OSVersion.Platform); var client = await LyraRestClient.CreateAsync(NetworkID, Environment.OSVersion.Platform.ToString(), "LyraNode2", "1.0", apiUrl); var mode = await client.GetSyncState(); if (mode.ResultCode == APIResultCodes.Success) { return(client); } await Task.Delay(10000); // incase of hammer } while (true); }
public async Task <LyraRestClient> GetClientForSeed0() { if (_seed0Client == null) { var addr = ProtocolSettings.Default.SeedList[0].Split(':')[0]; var apiUrl = $"https://{addr}:4505/api/LyraNode/"; _seed0Client = await LyraRestClient.CreateAsync(BlockChain.Singleton.NetworkID, Environment.OSVersion.Platform.ToString(), "LyraNode2", "1.0", apiUrl); } return(_seed0Client); }
public async Task <LyraRestClient> GetClientForSeed0() { if (_seed0Client == null) { var addr = ProtocolSettings.Default.SeedList[0].Split(':')[0]; var apiUrl = $"https://{addr}:4505/api/LyraNode/"; _log.LogInformation("Platform {1} Use seed node of {0}", apiUrl, Environment.OSVersion.Platform); _seed0Client = await LyraRestClient.CreateAsync(NetworkID, Environment.OSVersion.Platform.ToString(), "LyraNode2", "1.0", apiUrl); } return(_seed0Client); }
private async Task<Wallet> RefreshBalanceAsync(string masterKey) { // create wallet and update balance var memStor = new AccountInMemoryStorage(); var acctWallet = new ExchangeAccountWallet(memStor, _network); acctWallet.AccountName = "tmpAcct"; await acctWallet.RestoreAccountAsync("", masterKey); acctWallet.OpenAccount("", acctWallet.AccountName); Console.WriteLine("Sync wallet for " + acctWallet.AccountId); var rpcClient = await LyraRestClient.CreateAsync(_network, "Windows", "Lyra Client Cli", "1.0a"); await acctWallet.Sync(rpcClient); return acctWallet; }
public async Task <Dictionary <string, Decimal> > RefreshBalance(string networkId) { var rpcClient = await LyraRestClient.CreateAsync(networkId, "Windows", "AutoSender", "0.1"); var result = await wallet.Sync(rpcClient); if (result == Lyra.Core.Blocks.APIResultCodes.Success) { return(wallet.GetLatestBlock()?.Balances); } else { throw new Exception(result.ToString()); } }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) { _waitOrder = new AutoResetEvent(false); try { _log.LogInformation($"NodeService: ExecuteAsync Called."); // something must be initialized first new AuthorizersFactory().Init(); var walletStore = new LiteAccountDatabase(); var tmpWallet = new Wallet(walletStore, Neo.Settings.Default.LyraNode.Lyra.NetworkId); string lyra_folder = BaseAccount.GetFullFolderName("Lyra-CLI-" + Neo.Settings.Default.LyraNode.Lyra.NetworkId); string full_path = BaseAccount.GetFullPath(lyra_folder); tmpWallet.OpenAccount(full_path, Neo.Settings.Default.LyraNode.Lyra.Wallet.Name); if (ProtocolSettings.Default.StandbyValidators.Any(a => a == tmpWallet.AccountId)) { // not update balance for seed nodes. PosWallet = tmpWallet; } else { // create wallet and update balance var memStor = new AccountInMemoryStorage(); var acctWallet = new ExchangeAccountWallet(memStor, Neo.Settings.Default.LyraNode.Lyra.NetworkId); acctWallet.AccountName = "tmpAcct"; await acctWallet.RestoreAccountAsync("", tmpWallet.PrivateKey); acctWallet.OpenAccount("", acctWallet.AccountName); Console.WriteLine("Sync wallet for " + acctWallet.AccountId); var rpcClient = await LyraRestClient.CreateAsync(Neo.Settings.Default.LyraNode.Lyra.NetworkId, Environment.OSVersion.Platform.ToString(), "Lyra Client Cli", "1.0a"); await acctWallet.Sync(rpcClient); PosWallet = acctWallet; } var sys = new LyraSystem(); sys.Start(); if (_db == null) { //BsonSerializer.RegisterSerializer(typeof(decimal), new DecimalSerializer(BsonType.Decimal128)); //BsonSerializer.RegisterSerializer(typeof(decimal?), new NullableSerializer<decimal>(new DecimalSerializer(BsonType.Decimal128))); client = new MongoClient(Neo.Settings.Default.LyraNode.Lyra.Database.DexDBConnect); _db = client.GetDatabase("Dex"); var exchangeAccounts = _db.GetCollection <ExchangeAccount>("exchangeAccounts"); var queue = _db.GetCollection <ExchangeOrder>("queuedDexOrders"); var finished = _db.GetCollection <ExchangeOrder>("finishedDexOrders"); // TODO: make it DI Dealer = new DealEngine(exchangeAccounts, queue, finished); Dealer.OnNewOrder += (s, a) => _waitOrder.Set(); } //_watcher = new ZooKeeperWatcher(_log); //await UsingZookeeper(_zkClusterOptions.ConnectionString, async (zk) => { // // get Lyra network configurations from /lyra // // {"mode":"permissioned","seeds":["node1","node2"]} // var cfg = await zk.getDataAsync("/lyra"); // var runtimeConfig = JsonConvert.DeserializeObject<ConsensusRuntimeConfig>(Encoding.ASCII.GetString(cfg.Data)); // // do copy because the object is global // _consensus.Mode = runtimeConfig.Mode; // _consensus.Seeds = runtimeConfig.Seeds; // _consensus.CurrentSeed = runtimeConfig.CurrentSeed; // _consensus.PrimaryAuthorizerNodes = runtimeConfig.PrimaryAuthorizerNodes; // _consensus.BackupAuthorizerNodes = runtimeConfig.BackupAuthorizerNodes; // _consensus.VotingNodes = runtimeConfig.VotingNodes; // _log.LogInformation($"NodeService: Got runtimeconfig success."); //}); // all seeds do node election //if (_consensus.Seeds.Contains(Neo.Settings.Default.LyraNode.Orleans.EndPoint.AdvertisedIPAddress)) //{ //while(true) // we do nothing without zk //{ // try // { // var electRoot = "/lyra/seedelect"; // var zk = new ZooKeeper(_zkClusterOptions.ConnectionString, ZOOKEEPER_CONNECTION_TIMEOUT, _watcher); // var stat = await zk.existsAsync(electRoot); // if (stat == null) // await zk.createAsync(electRoot, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); // _leader = new LeaderElectionSupport(zk, electRoot, Neo.Settings.Default.LyraNode.Orleans.EndPoint.AdvertisedIPAddress); // _leader.addListener(this); // await _leader.start(); // break; // } // catch(Exception ex) // { // _log.Fail(Orleans.ErrorCode.MembershipShutDownFailure, ex.Message); // await Task.Delay(1000); // } //} //} } catch (Exception ex) { throw new Exception("Error Initialize Node Service", ex); } while (!stoppingToken.IsCancellationRequested) { // do work if (_waitOrder.WaitOne(1000)) { _waitOrder.Reset(); await Dealer.MakeDealAsync(); } else { // no new order. do house keeping. } } }
public async Task <int> RunWallet(Options options) { Console.WriteLine("Personal and Business Banking, Payments, and Digital Asset Management"); Console.WriteLine(""); Console.WriteLine("Banking: Store, transfer, and receive interest on multiple digital assets"); Console.WriteLine("Payments: Make or accept instant payments using various currencies, online and in store"); Console.WriteLine("Digital Asset Management: Issue your own tokens within seconds"); Console.WriteLine(""); string network_id = options.NetworkId; bool INMEMORY = options.Database == Options.INMEMORY_DATABASE; bool WEB = options.Protocol == Options.WEBAPI_PROTOCOL; Wallet wallet; if (INMEMORY) { var inmemory_storage = new AccountInMemoryStorage(); wallet = new Wallet(inmemory_storage, network_id); } else { wallet = new Wallet(new LiteAccountDatabase(), network_id); } string lyra_folder = BaseAccount.GetFullFolderName(network_id, "wallets"); if (!Directory.Exists(lyra_folder)) { Directory.CreateDirectory(lyra_folder); } Console.WriteLine("Storage Location: " + lyra_folder); if (options.GenWalletName != null) { wallet.AccountName = options.GenWalletName; wallet.CreateAccount(lyra_folder, wallet.AccountName, AccountTypes.Standard); var ep = Neo.Cryptography.ECC.ECPoint.FromBytes(Base58Encoding.DecodeAccountId(wallet.AccountId), Neo.Cryptography.ECC.ECCurve.Secp256r1); Console.WriteLine($"The new wallet {wallet.AccountName} for {network_id}: "); Console.WriteLine(ep.ToString()); Console.WriteLine(wallet.AccountId); return(0); } CommandProcessor command = new CommandProcessor(wallet); string input = null; try { while (!wallet.AccountExistsLocally(lyra_folder, input)) { Console.WriteLine("Press Enter for default account, or enter account name: "); input = Console.ReadLine(); if (string.IsNullOrEmpty(input)) { input = "My Account"; } wallet.AccountName = input; string fileName = ""; if (INMEMORY) { fileName = lyra_folder + wallet.AccountName + ".key"; if (System.IO.File.Exists(fileName)) { string private_key = System.IO.File.ReadAllText(fileName); if (wallet.ValidatePrivateKey(private_key)) { var result = await wallet.RestoreAccountAsync(lyra_folder, private_key); if (!result.Successful()) { Console.WriteLine("Could not restore account from file: " + result.ResultMessage); continue; } } } } if (!wallet.AccountExistsLocally(lyra_folder, wallet.AccountName)) { Console.WriteLine("Local account data not found. Would you like to create a new account? (Y/n): "); if (command.ReadYesNoAnswer()) { wallet.CreateAccount(lyra_folder, wallet.AccountName, AccountTypes.Standard); } else { Console.WriteLine("Please enter private key to restore account: "); string privatekey = Console.ReadLine(); if (!wallet.ValidatePrivateKey(privatekey)) { continue; } var result = await wallet.RestoreAccountAsync(lyra_folder, privatekey); if (!result.Successful()) { Console.WriteLine("Could not restore account from file: " + result.ResultMessage); continue; } } if (INMEMORY) { System.IO.File.WriteAllText(fileName, wallet.PrivateKey); } } else { wallet.OpenAccount(lyra_folder, wallet.AccountName); } } LyraRestClient rpcClient; if (!string.IsNullOrWhiteSpace(options.Node)) { var apiUrl = $"https://{options.Node}:4505/api/Node/"; rpcClient = await LyraRestClient.CreateAsync(network_id, "Windows", "WizDAG Client Cli", "1.0a", apiUrl); } else { rpcClient = await LyraRestClient.CreateAsync(network_id, "Windows", "WizDAG Client Cli", "1.0a");//await LyraRpcClient.CreateAsync(network_id, "Lyra Client Cli", "1.0"); } Console.WriteLine("Type 'help' to see the list of available commands"); Console.WriteLine(""); await wallet.Sync(rpcClient); //timer1 = new Timer(async _ => //{ // if (timer_busy1) // return; // try // { // timer_busy1 = true; // var sync_result = await wallet.Sync(rpcClient); // } // finally // { // timer_busy1 = false; // } //}, //null, 2000, 30000); input = CommandProcessor.COMMAND_STATUS; while (input != CommandProcessor.COMMAND_STOP) { var result = await command.Execute(input); Console.Write(string.Format("{0}> ", wallet.AccountName)); //Console.Write input = Console.ReadLine(); } Console.WriteLine("WizDAG Client is shutting down"); } catch (Exception ex) { Console.WriteLine(string.Format("Exception: {0}", ex.Message)); Console.WriteLine("WizDAG Client is shutting down"); } finally { if (wallet != null) { wallet.Dispose(); } } return(0); }
// args: [number] the tps to simulate // static async System.Threading.Tasks.Task Main(string[] args) { var workingFolder = @"C:\working\Friday"; var lyraFolder = BaseAccount.GetFullFolderName("Lyra-CLI-" + network_id); Console.WriteLine("Press enter to begin."); Console.ReadLine(); // create and save wallets //var tt = new TransactionTester(); //var wlts = tt.CreateWallet(1000); //var json = JsonConvert.SerializeObject(wlts); //File.WriteAllText(workingFolder + @"\wallets.json", json); // key is account id var wallets = JsonConvert.DeserializeObject <Dictionary <string, string> >(File.ReadAllText(workingFolder + @"\\wallets.json")); //var rpcClient = await LyraRestClient.CreateAsync(network_id, "Windows", "Lyra Client Cli", "1.0a", "https://192.168.3.62:4505/api/LyraNode/"); var rpcClient = await LyraRestClient.CreateAsync(network_id, "Windows", "Lyra Client Cli", "1.0a"); var tt = new TransactionTester(rpcClient); var masterWallet = new Wallet(new LiteAccountDatabase(), network_id); masterWallet.AccountName = "My Account"; masterWallet.OpenAccount(lyraFolder, masterWallet.AccountName); await masterWallet.Sync(rpcClient); _ = Task.Run(async() => { while (true) { var state = await rpcClient.GetSyncState(); await Task.Delay(10000); var state2 = await rpcClient.GetSyncState(); var tps = state2.Status.totalBlockCount - state.Status.totalBlockCount; Console.WriteLine($"\n============> TPS: {tps} / 10\n"); } }); //var all = await tt.RefreshBalancesAsync(wallets.Select(a => new KeyPair(Base58Encoding.DecodePrivateKey(a.Value))).ToArray()); //File.WriteAllText(workingFolder + @"\balances.json", JsonConvert.SerializeObject(all)); var rich10 = JsonConvert.DeserializeObject <List <WalletBalance> >(File.ReadAllText(workingFolder + @"\balances.json")); var realRich10 = rich10.Where(a => a.balance.ContainsKey(lyraCoin) && a.balance.ContainsKey(testCoin)) .Where(a => a.balance[testCoin] >= 10000).ToDictionary(a => a.privateKey, a => a.balance); //var rich90 = wallets.Where(a => !realRich10.ContainsKey(a.Value)).Take(90); var rich90 = JsonConvert.DeserializeObject <List <KeyValuePair <string, string> > >(File.ReadAllText(workingFolder + @"\\rich90.json")); //File.WriteAllText(workingFolder + @"\rich90.json", JsonConvert.SerializeObject(rich90)); var poors = wallets.Where(a => !rich90.Any(x => x.Key == a.Key)); var testGroup1 = rich90.Take(350); await tt.MultiThreadedSendAsync(new [] { masterWallet.PrivateKey }, testGroup1.Select(a => a.Key).ToArray(), new Dictionary <string, decimal> { { lyraCoin, 5000 } }, true); Console.WriteLine("Coin distribute OK. Press Enter to continue..."); Console.ReadLine(); await tt.MultiThreadedSendAsync(testGroup1.Select(a => a.Value).ToArray(), poors.Select(a => a.Key).ToArray(), new Dictionary <string, decimal> { { lyraCoin, 1 } }); Console.ReadLine(); //foreach(var b in masterWallet.GetLatestBlock().Balances) //{ // Console.WriteLine($"{b.Key}: {b.Value}"); //} //Console.WriteLine("Hello Lyra!"); //var top10 = wallets.Take(10).ToDictionary(a => a.Key, a => a.Value); //await tt.SingleThreadedSendAsync(10, masterWallet, top10.Keys.ToArray(), new Dictionary<string, decimal> { // { lyraCoin, 10000 }, {testCoin, 1000000} //}); //var top100 = wallets.Skip(10).Take(100).ToDictionary(a => a.Key, a => a.Value); //await tt.MultiThreadedSendAsync(10, top10.Select(a => new KeyPair(Base58Encoding.DecodePrivateKey(a.Value))).ToArray(), // top100.Values.ToArray(), new Dictionary<string, decimal> { // { lyraCoin, 100 }, {testCoin, 10000} } // ); }
/// <summary> /// if this node is seed0 then sync with seeds others (random choice the one that is in normal state) /// if this node is seed1+ then sync with seed0 /// otherwise sync with any seed node /// </summary> private void SyncBlocksFromSeeds(long ToUIndex) { InSyncing = true; Task.Run(async() => { while (true) { _log.LogInformation("BlockChain Doing Sync..."); string syncWithUrl = null; LyraRestClient client = null; long syncToUIndex = ToUIndex; for (int i = 0; i < ProtocolSettings.Default.SeedList.Length; i++) { if (NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[i]) // self { continue; } try { var addr = ProtocolSettings.Default.SeedList[i].Split(':')[0]; var apiUrl = $"https://{addr}:4505/api/LyraNode/"; _log.LogInformation("Platform {1} Use seed node of {0}", apiUrl, Environment.OSVersion.Platform); client = await LyraRestClient.CreateAsync(NetworkID, Environment.OSVersion.Platform.ToString(), "LyraNode2", "1.0", apiUrl); var mode = await client.GetSyncState(); if (mode.ResultCode == APIResultCodes.Success && mode.Mode == ConsensusWorkingMode.Normal) { syncWithUrl = apiUrl; if (syncToUIndex == 0) { syncToUIndex = mode.NewestBlockUIndex; } break; } } catch (Exception ex) { _log.LogWarning($"Trying to sync.. {ex.Message}"); } } if (syncWithUrl == null) { // no node to sync. if (NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[0]) { // seed0. no seed to sync. this seed must have the NORMAL blockchain var board = new BillBoard(); board.Add(NodeService.Instance.PosWallet.AccountId); // add me! LyraSystem.Singleton.Consensus.Tell(board); break; } else { _log.LogError("No seed node in normal state. Wait..."); await Task.Delay(300 * 1000); } } else { // update latest billboard var board = await client.GetBillBoardAsync(); LyraSystem.Singleton.Consensus.Tell(board); // do sync with node long startUIndex = _store.GetNewestBlockUIndex() + 1; _log.LogInformation($"BlockChain Doing sync from {startUIndex} to {syncToUIndex} from node {syncWithUrl}"); async Task <bool> DoCopyBlock() { for (long j = startUIndex; j <= syncToUIndex; j++) { var blockResult = await client.GetBlockByUIndex(j).ConfigureAwait(false); if (blockResult.ResultCode == APIResultCodes.Success) { AddBlock(blockResult.GetBlock() as TransactionBlock); startUIndex = j + 1; _log.LogInformation($"BlockChain Synced Block Number: {j}"); } else if (blockResult.ResultCode == APIResultCodes.BlockNotFound) { return(true); } else { // error _log.LogError($"Error syncing block: {blockResult.ResultCode}"); return(false); } } return(true); } var copyOK = await DoCopyBlock().ConfigureAwait(false); if (copyOK) { break; } else { await Task.Delay(5000).ConfigureAwait(false); } } } InSyncing = false; LyraSystem.Singleton.Consensus.Tell(new ConsensusService.BlockChainSynced()); _log.LogInformation("BlockChain Sync Completed."); }); }
/// <summary> /// if this node is seed0 then sync with seeds others (random choice the one that is in normal state) /// if this node is seed1+ then sync with seed0 /// otherwise sync with any seed node /// </summary> private void SyncBlocksFromSeeds(long ToUIndex) { InSyncing = true; Task.Run(async() => { while (true) { _log.LogInformation("BlockChain Doing Sync..."); string syncWithUrl = null; LyraRestClient client = null; long syncToUIndex = ToUIndex; #if DEBUG for (int i = 0; i < 2; i++) // save time #else for (int i = 0; i < ProtocolSettings.Default.SeedList.Length; i++) #endif { if (NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[i]) // self { continue; } try { var addr = ProtocolSettings.Default.SeedList[i].Split(':')[0]; var apiUrl = $"https://{addr}:4505/api/LyraNode/"; _log.LogInformation("Platform {1} Use seed node of {0}", apiUrl, Environment.OSVersion.Platform); client = await LyraRestClient.CreateAsync(NetworkID, Environment.OSVersion.Platform.ToString(), "LyraNode2", "1.0", apiUrl); var mode = await client.GetSyncState(); if (mode.ResultCode == APIResultCodes.Success && mode.Mode == ConsensusWorkingMode.Normal) { syncWithUrl = apiUrl; if (syncToUIndex == 0) { syncToUIndex = mode.NewestBlockUIndex; } break; } } catch (Exception ex) { _log.LogWarning($"Trying to sync.. {ex.Message}"); } } if (syncWithUrl == null) { // no node to sync. if (NodeService.Instance.PosWallet.AccountId == ProtocolSettings.Default.StandbyValidators[0]) { // seed0. no seed to sync. this seed must have the NORMAL blockchain break; } else { _log.LogError("No seed node in normal state. Wait..."); await Task.Delay(300 * 1000); } } else { // update latest billboard var board = await client.GetBillBoardAsync(); LyraSystem.Singleton.Consensus.Tell(board); // do sync with node long startUIndex = await _store.GetNewestBlockUIndexAsync() + 1; _log.LogInformation($"BlockChain Doing sync from {startUIndex} to {syncToUIndex} from node {syncWithUrl}"); async Task <bool> DoCopyBlock(long fromUIndex, long toUIndex) { var authorizers = new AuthorizersFactory(); for (long j = fromUIndex; j <= toUIndex; j++) { var blockResult = await client.GetBlockByUIndex(j).ConfigureAwait(false); if (blockResult.ResultCode == APIResultCodes.Success) { var blockX = blockResult.GetBlock() as TransactionBlock; if (blockX.UIndex <= 2) // the two genesis service block { await AddBlockAsync(blockX); continue; } var stopwatch = Stopwatch.StartNew(); var authorizer = authorizers.Create(blockX.BlockType); var localAuthResult = await authorizer.AuthorizeAsync(blockX, false); stopwatch.Stop(); _log.LogInformation($"Authorize takes {stopwatch.ElapsedMilliseconds} ms"); if (localAuthResult.Item1 == APIResultCodes.Success) { await AddBlockAsync(blockX); fromUIndex = j + 1; _log.LogInformation($"BlockChain Synced Block Number: {j}"); } else { _log.LogInformation($"BlockChain Block Number: {j} verify failed for {localAuthResult.Item1}"); return(false); } } else { // error _log.LogInformation($"Error syncing block: {blockResult.ResultCode}"); continue; } } return(true); } var copyOK = await DoCopyBlock(startUIndex, syncToUIndex).ConfigureAwait(false); if (copyOK) { //// check missing block //for(long k = 1; k <= startUIndex; k++) //{ // if(await BlockChain.Singleton.GetBlockByUIndex(k) == null) // { // _log.LogInformation($"syncing one missing block: {k}"); // await DoCopyBlock(k, k).ConfigureAwait(false); // } //} break; } else { await Task.Delay(5000).ConfigureAwait(false); } } } InSyncing = false; LyraSystem.Singleton.Consensus.Tell(new ConsensusService.BlockChainSynced()); _log.LogInformation("BlockChain Sync Completed."); }); }