public void ShouldThrowIfDisposed() { HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.NotFound); var mockHttpMessageHandler = new MockHttpMessageHandler(response); var mockHttpClient = new HttpClient(mockHttpMessageHandler); var rpcClient = new RpcClient("127.0.0.1:8545", mockHttpClient, new JsonSerializer()); rpcClient.Dispose(); try { var rpcResponse = rpcClient.PostRpcRequestAsync<string>(new RpcRequest { ID = 0, JsonRpc = "2.0", MethodName = "eth_getWork", Parameters = null }).Result; } catch (AggregateException ex) { throw ex.InnerException; } }
static void Main(string[] args) { Log.Texte("", "---------------------------------------------------------------", ConsoleColor.DarkBlue); Log.Texte("", " _______ _________ _______ _________ _______ _______ ", ConsoleColor.Cyan); Log.Texte("", "( ____ )\\__ __/( ____ \\__ __/( ____ \\( )|\\ /|", ConsoleColor.Cyan); Log.Texte("", "| ( )| ) ( | ( \\/ ) ( | ( \\/| () () || ) ( |", ConsoleColor.Cyan); Log.Texte("", "| (____)| | | | (__ | | | (__ | || || || | | |", ConsoleColor.Cyan); Log.Texte("", "| __) | | | __) | | | __) | |(_)| || | | |", ConsoleColor.Cyan); Log.Texte("", "| (\\ ( | | | ( | | | ( | | | || | | |", ConsoleColor.Cyan); Log.Texte("", "| ) \\ \\_____) (___| ) | | | (____/\\| ) ( || (___) |", ConsoleColor.Cyan); Log.Texte("", "|/ \\__/\\_______/|/ )_( (_______/|/ \\|(_______)", ConsoleColor.Cyan); Log.Texte("", "www.Strawberry-Pr0jcts.com", ConsoleColor.DarkCyan); Log.Texte("", "---------------------------------------------------------------", ConsoleColor.DarkBlue); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<RealmConfig>(); Config.RealmInfo.GenerateName(); // Loading log level from file if (!Log.InitLog(Config.LogLevel,"Realm")) ConsoleMgr.WaitAndExit(2000); CharactersMgr.CharactersDB = DBManager.Start(Config.CharactersDB.Total(), ConnectionType.DATABASE_MYSQL, "Characters"); if (CharactersMgr.CharactersDB == null) ConsoleMgr.WaitAndExit(2000); WorldMgr.WorldDB = DBManager.Start(Config.WorldDB.Total(), ConnectionType.DATABASE_MYSQL, "World"); if (WorldMgr.WorldDB == null) ConsoleMgr.WaitAndExit(2000); PacketProcessor.RegisterDefinitions(); // Starting Remote Client Client = new RpcClient("Realm-" + Config.RealmInfo.RealmId, Config.RpcCharacter.RpcLocalIp, 1); if (!Client.Start(Config.RpcCharacter.RpcServerIp, Config.RpcCharacter.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); Server = new RpcServer(Config.RpcMapServer.RpcClientStartingPort, 2); if (!Server.Start(Config.RpcMapServer.RpcIp, Config.RpcMapServer.RpcPort)) ConsoleMgr.WaitAndExit(2000); World = Client.GetLocalObject<WorldMgr>(); Accounts = Client.GetServerObject<AccountMgr>(); Characters = Client.GetLocalObject<CharactersMgr>(); // 1 : Loading WorldMgr World.Load(); // 2 : Loading CharactersMgr CharactersMgr.Client = Client; CharactersMgr.MyRealm = Config.RealmInfo; CharactersMgr.MyRealm.RpcInfo = Client.Info; Characters.Load(); // 3 : Loading AccountsMgr Accounts.RegisterRealm(Config.RealmInfo, Client.Info); ConsoleMgr.Start(); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); Log.Texte("", "-------------------- Lobby Server ---------------------", ConsoleColor.DarkRed); Log.Texte("", " █ █░ ▄▄▄ ██▀███ ▓█████ ███▄ ▄███▓ █ ██ ", ConsoleColor.Red); Log.Texte("", "▓█░ █ ░█░▒████▄ ▓██ ▒ ██▒▓█ ▀ ▓██▒▀█▀ ██▒ ██ ▓██▒", ConsoleColor.Red); Log.Texte("", "▒█░ █ ░█ ▒██ ▀█▄ ▓██ ░▄█ ▒▒███ ▓██ ▓██░▓██ ▒██░", ConsoleColor.Red); Log.Texte("", "░█░ █ ░█ ░██▄▄▄▄██ ▒██▀▀█▄ ▒▓█ ▄ ▒██ ▒██ ▓▓█ ░██░", ConsoleColor.Red); Log.Texte("", "░░██▒██▓ ▓█ ▓██▒░██▓ ▒██▒░▒████▒▒██▒ ░██▒▒▒█████▓ ", ConsoleColor.Red); Log.Texte("", "░ ▓░▒ ▒ ▒▒ ▓▒█░░ ▒▓ ░▒▓░░░ ▒░ ░░ ▒░ ░ ░░▒▓▒ ▒ ▒ ", ConsoleColor.Red); Log.Texte("", " ▒ ░ ░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ░ ░░ ░ ░░░▒░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ▒ ░░ ░ ░ ░ ░ ░░░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ░ ░ ░ ░ ░ ", ConsoleColor.Red); Log.Texte("", "-------------------http://WarEmu.com-------------------", ConsoleColor.DarkRed); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<LobbyConfigs>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "LobbyServer")) ConsoleMgr.WaitAndExit(2000); Client = new RpcClient("LobbyServer", Config.RpcInfo.RpcLocalIp, 1); if (!Client.Start(Config.RpcInfo.RpcServerIp, Config.RpcInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); if (!TCPManager.Listen<TCPServer>(Config.ClientPort, "LobbyServer")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("LobbyServer"); ConsoleMgr.Start(); }
public void ShouldParseCorrectErrorCodeAndMessageInException() { HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); response.Content = new StringContent("{\"id\":0,\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32000,\"message\":\"mining work not ready\"}}"); var mockHttpClient = new HttpClient(new MockHttpMessageHandler(response)); var rpcClient = new RpcClient("127.0.0.1:8545", mockHttpClient, new JsonSerializer()); EthException thrownException = null; try { var rpcResponse = rpcClient.EthGetWorkAsync().Result; } catch (AggregateException ex) { thrownException = ex.InnerException as EthException; } Assert.IsTrue(thrownException != null); int expectedErrorCode = -32000; string expectedErrorMessage = "mining work not ready"; Assert.IsTrue(Equals(expectedErrorCode, thrownException.ErrorCode)); Assert.IsTrue(Equals(expectedErrorMessage, thrownException.Message)); }
public EthCompilerService(RpcClient client) : base(client) { CompileLLL = new EthCompileLLL(client); CompileSerpent = new EthCompileSerpent(client); CompileSolidity = new EthCompileSolidity(client); GetCompilers = new EthGetCompilers(client); }
public Eth(RpcClient client):base(client) { this.Client = client; DeployContract = new DeployContract(client); Accounts = new EthAccounts(client); CoinBase = new EthCoinBase(client); GasPrice = new EthGasPrice(client); GetBalance = new EthGetBalance(client); GetCode = new EthGetCode(client); GetStorageAt = new EthGetStorageAt(client); ProtocolVersion = new EthProtocolVersion(client); Sign = new EthSign(client); Syncing = new EthSyncing(client); Transactions = new EthTransactionsService(client); Filters = new EthFilterService(client); Blocks = new EthBlockService(client); Uncles = new EthUncleService(client); Mining = new EthMiningService(client); Compile = new EthCompilerService(client); this.DefaultBlock = BlockParameter.CreateLatest(); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); Console.CancelKeyPress += new ConsoleCancelEventHandler(OnClose); Log.Texte("", "-------------------- World Server ---------------------", ConsoleColor.DarkRed); Log.Texte("", " █ █░ ▄▄▄ ██▀███ ▓█████ ███▄ ▄███▓ █ ██ ", ConsoleColor.Red); Log.Texte("", "▓█░ █ ░█░▒████▄ ▓██ ▒ ██▒▓█ ▀ ▓██▒▀█▀ ██▒ ██ ▓██▒", ConsoleColor.Red); Log.Texte("", "▒█░ █ ░█ ▒██ ▀█▄ ▓██ ░▄█ ▒▒███ ▓██ ▓██░▓██ ▒██░", ConsoleColor.Red); Log.Texte("", "░█░ █ ░█ ░██▄▄▄▄██ ▒██▀▀█▄ ▒▓█ ▄ ▒██ ▒██ ▓▓█ ░██░", ConsoleColor.Red); Log.Texte("", "░░██▒██▓ ▓█ ▓██▒░██▓ ▒██▒░▒████▒▒██▒ ░██▒▒▒█████▓ ", ConsoleColor.Red); Log.Texte("", "░ ▓░▒ ▒ ▒▒ ▓▒█░░ ▒▓ ░▒▓░░░ ▒░ ░░ ▒░ ░ ░░▒▓▒ ▒ ▒ ", ConsoleColor.Red); Log.Texte("", " ▒ ░ ░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ░ ░░ ░ ░░░▒░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ▒ ░░ ░ ░ ░ ░ ░░░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ░ ░ ░ ░ ░ ", ConsoleColor.Red); Log.Texte("", "-------------------http://WarEmu.com-------------------", ConsoleColor.DarkRed); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<WorldConfigs>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "WorldServer")) ConsoleMgr.WaitAndExit(2000); CharMgr.Database = DBManager.Start(Config.CharacterDatabase.Total(), ConnectionType.DATABASE_MYSQL, "Characters"); if (CharMgr.Database == null) ConsoleMgr.WaitAndExit(2000); WorldMgr.Database = DBManager.Start(Config.WorldDatabase.Total(), ConnectionType.DATABASE_MYSQL, "World"); if (WorldMgr.Database == null) ConsoleMgr.WaitAndExit(2000); AbilityMgr.Database = WorldMgr.Database; Client = new RpcClient("WorldServer-" + Config.RealmId, Config.AccountCacherInfo.RpcLocalIp, 1); if (!Client.Start(Config.AccountCacherInfo.RpcServerIp, Config.AccountCacherInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); Rm = Program.AcctMgr.GetRealm(Config.RealmId); if (Rm == null) { Log.Error("WorldServer", "Realm (" + Config.RealmId + ") not found"); return; } LoaderMgr.Start(); if (!TCPManager.Listen<TCPServer>(Rm.Port, "World")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("World"); AcctMgr.UpdateRealm(Client.Info, Rm.RealmId); AcctMgr.UpdateRealmCharacters(Rm.RealmId, (uint)CharMgr.Database.GetObjectCount<Character>("Realm=1"), (uint)CharMgr.Database.GetObjectCount<Character>("Realm=2")); ConsoleMgr.Start(); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<LauncherConfig>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "LauncherServer")) ConsoleMgr.WaitAndExit(2000); Client = new RpcClient("LauncherServer", Config.RpcInfo.RpcLocalIp, 1); if (!Client.Start(Config.RpcInfo.RpcServerIp, Config.RpcInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); Info = new FileInfo("Configs/mythloginserviceconfig.xml"); if (!Info.Exists) { Log.Error("Configs/mythloginserviceconfig.xml", "Config file missing !"); ConsoleMgr.WaitAndExit(5000); } StrInfo = Info.OpenText().ReadToEnd(); if (!TCPManager.Listen<TCPServer>(Config.LauncherServerPort, "LauncherServer")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("LauncherServer"); ConsoleMgr.Start(); }
public static async Task Run() { AuthenticationHeaderValue authHeaderValue = AuthenticationHeaderValue.Parse("Basic R2VrY3RlazpXZWxjMG1lIQ=="); RpcClient client = new RpcClient(new Uri("http://localhost:62390/RpcApi/"), authHeaderValue); RpcRequest request = new RpcRequest("Id1", "CharacterCount", "Test"); RpcResponse response = await client.SendRequestAsync(request, "Strings"); List<RpcRequest> requests = new List<RpcRequest> { request, new RpcRequest("id2", "CharacterCount", "Test2"), new RpcRequest("id3", "CharacterCount", "Test23") }; List<RpcResponse> bulkResponse = await client.SendBulkRequestAsync(requests, "Strings"); IntegerFromSpace responseValue = response.GetResult<IntegerFromSpace>(); if (responseValue == null) { Console.WriteLine("null"); } else { Console.WriteLine(responseValue.Test); } }
public static void Main(string[] args) { RpcClient client = new RpcClient(new Uri("http://localhost:8545/")); Type testerType = typeof (IRPCRequestTester); var assembly = testerType.GetTypeInfo().Assembly; var types = assembly.GetTypes(); foreach (var type in types) { if (typeof (IRPCRequestTester).IsAssignableFrom(type) && type != typeof (IRPCRequestTester)) { var tester = (IRPCRequestTester) Activator.CreateInstance(type); try { var testerResult = tester.ExecuteTestAsync(client).Result; ConsoleOutputResult(testerResult, tester.GetRequestType()); } catch (Exception ex) { ConsoleOutputResult("Error:" + ex.InnerException.Message, tester.GetRequestType()); } } } Console.ReadLine(); }
public EthMiningService(RpcClient client) : base(client) { SubmitHashrate = new EthSubmitHashrate(client); SubmitWork = new EthSubmitWork(client); GetWork = new EthGetWork(client); Hashrate = new EthHashrate(client); IsMining = new EthMining(client); }
public async Task<dynamic> ExecuteTestAsync(RpcClient client) { //The compiled solidity contract to be deployed //contract test { function multiply(uint a) returns(uint d) { return a * 7; } } var contractByteCode = "0x606060405260728060106000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa1146037576035565b005b604b60048080359060200190919050506061565b6040518082815260200191505060405180910390f35b6000600782029050606d565b91905056"; //Create a new Eth Send Transanction RPC Handler var ethSendTransation = new EthSendTransaction(client); //As the input the compiled contract is the Data, together with our address var transactionInput = new TransactionInput(); transactionInput.Data = contractByteCode; transactionInput.From = "0x12890d2cce102216644c59dae5baed380d84830c"; // retrieve the hash var transactionHash = await ethSendTransation.SendRequestAsync( transactionInput); //the contract should be mining now //get contract address var ethGetTransactionReceipt = new EthGetTransactionReceipt(client); TransactionReceipt receipt = null; //wait for the contract to be mined to the address while (receipt == null) { receipt = await ethGetTransactionReceipt.SendRequestAsync( transactionHash); } //Encode and build function parameters var function = new FunctionCallEncoder(); //Input the function method Sha3Encoded (4 bytes) var sha3Signature = "c6888fa1"; //Define input parameters var inputParameters = new[] { new Parameter("uint", "a") }; //encode the function call (function + parameter input) //using 69 as the input var functionCall = function.EncodeRequest(sha3Signature, inputParameters, 69); //reuse the transaction input, (just the address) //the destination address is the contract address transactionInput.To = receipt.ContractAddress; //use as data the function call transactionInput.Data = functionCall; // rpc method to do the call var ethCall = new EthCall(client); // call and get the result var resultFunction = await ethCall.SendRequestAsync( transactionInput); // decode the output var functionDecoder = new FunctionCallDecoder(); var output = functionDecoder.DecodeOutput<int>(resultFunction, new Parameter("uint", "d")); //visual test return "The result of deploying a contract and calling a function to multiply 7 by 69 is: " + output + " and should be 483"; }
public async void ShouldInterceptParamsRequest() { var client = new RpcClient(new Uri("http://localhost:8545/")); client.OverridingRequestInterceptor = new OverridingInterceptorMock(); var ethGetCode = new EthGetCode(client); var code = await ethGetCode.SendRequestAsync("address"); Assert.Equal(code, "the code"); }
/* curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0x65180b8c813457b21dad6cc6363d195231b4d2e9","data":"0x606060405260728060106000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa1146037576035565b005b604b60048080359060200190919050506061565b6040518082815260200191505060405180910390f35b6000600782029050606d565b91905056"}],"id":1}' http://localhost:8545 */ public async Task<dynamic> ExecuteTestAsync(RpcClient client) { var contractByteCode = "0x606060405260728060106000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa1146037576035565b005b604b60048080359060200190919050506061565b6040518082815260200191505060405180910390f35b6000600782029050606d565b91905056"; var ethSendTransation = new EthSendTransaction(client); var transactionInput = new TransactionInput(); transactionInput.Data = contractByteCode; transactionInput.From = "0x12890d2cce102216644c59dae5baed380d84830c"; return await ethSendTransation.SendRequestAsync( transactionInput); }
public async void ShouldInterceptNoParamsRequest() { var client = new RpcClient(new Uri("http://localhost:8545/")); client.OverridingRequestInterceptor = new OverridingInterceptorMock(); var ethAccounts = new EthAccounts(client); var accounts = await ethAccounts.SendRequestAsync(); Assert.True(accounts.Length == 2); Assert.Equal(accounts[0],"hello"); }
public EthBlockService(RpcClient client) : base(client) { GetBlockNumber = new EthBlockNumber(client); GetBlockTransactionCountByHash = new EthGetBlockTransactionCountByHash(client); GetBlockTransactionCountByNumber = new EthGetBlockTransactionCountByNumber(client); GetBlockWithTransactionsByHash = new EthGetBlockWithTransactionsByHash(client); GetBlockWithTransactionsByNumber = new EthGetBlockWithTransactionsByNumber(client); GetBlockWithTransactionsHashesByHash = new EthGetBlockWithTransactionsHashesByHash(client); GetBlockWithTransactionsHashesByNumber = new EthGetBlockWithTransactionsHashesByNumber(client); }
public void Init() { var controller = new RpcController(); client = new RpcClient(controller); server = new RpcServer(controller); server.RegisterService(new SampleService()); var channel = new LoopbackRpcChannel(controller); channel.Start(); dynProxy = client.GetProxy("ISampleService"); }
public EthTransactionsService(RpcClient client) : base(client) { Call = new EthCall(client); EstimateGas = new EthEstimateGas(client); GetTransactionByBlockHashAndIndex = new EthGetTransactionByBlockHashAndIndex(client); GetTransactionByBlockNumberAndIndex = new EthGetTransactionByBlockNumberAndIndex(client); GetTransactionByHash = new EthGetTransactionByHash(client); GetTransactionCount = new EthGetTransactionCount(client); GetTransactionReceipt = new EthGetTransactionReceipt(client); SendRawTransaction = new EthSendRawTransaction(client); SendTransaction = new EthSendTransaction(client); }
/* curl -X POST --data '{"jsonrpc":"2.0","method":"eth_sendTransaction","params":[{"from":"0x65180b8c813457b21dad6cc6363d195231b4d2e9","data":"0x606060405260728060106000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa1146037576035565b005b604b60048080359060200190919050506061565b6040518082815260200191505060405180910390f35b6000600782029050606d565b91905056"}],"id":1}' http://localhost:8545 */ public async Task<dynamic> ExecuteTestAsync(RpcClient client) { var contractByteCode = "0xc6888fa10000000000000000000000000000000000000000000000000000000000000045"; var to = "0x32eb97b8ad202b072fd9066c03878892426320ed"; var ethSendTransation = new EthSendTransaction(client); var transactionInput = new TransactionInput(); transactionInput.Data = contractByteCode; transactionInput.To = to; transactionInput.From = "0x12890d2cce102216644c59dae5baed380d84830c"; return await ethSendTransation.SendRequestAsync( transactionInput); }
public EthFilterService(RpcClient client) : base(client) { GetFilterChangesForBlockOrTransaction = new EthGetFilterChangesForBlockOrTransaction(client); GetFilterChangesForEthNewFilter = new EthGetFilterChangesForEthNewFilter(client); GetFilterLogsForBlockOrTransaction = new EthGetFilterLogsForBlockOrTransaction(client); GetFilterLogsForEthNewFilter = new EthGetFilterLogsForEthNewFilter(client); GetLogs = new EthGetLogs(client); NewBlockFilter = new EthNewBlockFilter(client); NewFilter = new EthNewFilter(client); NewPendingTransactionFilter = new EthNewPendingTransactionFilter(client); UninstallFilter = new EthUninstallFilter(client); }
public async Task JoinAsync(NetGameServerInfo serverInfo) { var serializer = new DefaultJsonSerializer(typeof(NetGameClient).GetTypeInfo().Assembly, Serialization.JsonSerializationSettings); _rpcClient = await RpcClient.ConnectAsync(serverInfo.RemoteAddress, serverInfo.RemotePort, this, serializer); JoinResult joinResult = await _rpcClient.Server.JoinAsync(PlayerInfo); var serverStub = new ClientSideServerProxy(_rpcClient.Connection); if (joinResult.IsSuccessful) await InitializeAsync(joinResult.SpawnPosition, serverStub); else throw new InvalidOperationException("Failed to join game server"); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); Console.CancelKeyPress += new ConsoleCancelEventHandler(OnClose); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<WorldConfigs>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "WorldServer")) ConsoleMgr.WaitAndExit(2000); CharMgr.Database = DBManager.Start(Config.CharacterDatabase.Total(), ConnectionType.DATABASE_MYSQL, "Characters"); if (CharMgr.Database == null) ConsoleMgr.WaitAndExit(2000); WorldMgr.Database = DBManager.Start(Config.WorldDatabase.Total(), ConnectionType.DATABASE_MYSQL, "World"); if (WorldMgr.Database == null) ConsoleMgr.WaitAndExit(2000); AbilityMgr.Database = WorldMgr.Database; Client = new RpcClient("WorldServer-" + Config.RealmId, Config.AccountCacherInfo.RpcLocalIp, 1); if (!Client.Start(Config.AccountCacherInfo.RpcServerIp, Config.AccountCacherInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); Rm = Program.AcctMgr.GetRealm(Config.RealmId); if (Rm == null) { Log.Error("WorldServer", "Realm (" + Config.RealmId + ") not found"); return; } LoaderMgr.Start(); if (!TCPManager.Listen<TCPServer>(Rm.Port, "World")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("World"); AcctMgr.UpdateRealm(Client.Info, Rm.RealmId); ConsoleMgr.Start(); }
public void Init() { controller = new Mock<RpcController>(); client = new RpcClient(controller.Object); defaultResult = new RpcMessage(); defaultResult.ResultMessage = new RpcMessage.Result(); defaultResult.ResultMessage.CallResult = new RpcMessage.Parameter(); defaultResult.ResultMessage.CallResult.IntParam = 100; controller.Setup(c => c.Send(It.IsAny<RpcMessage>())) .Callback((RpcMessage m) => { defaultResult.Id = m.Id; if (m.CallMessage.ExpectsResult) client.ReceiveResult(defaultResult); }); }
static void Main(string[] args) { Log.Texte("", "-------------------------------", ConsoleColor.DarkBlue); Log.Texte("", " _____ _____ ", ConsoleColor.Cyan); Log.Texte("", " /\\ | __ \\ / ____|", ConsoleColor.Cyan); Log.Texte("", " / \\ | |__) | (___ ", ConsoleColor.Cyan); Log.Texte("", " / /\\ \\ | ___/ \\___ \\ ", ConsoleColor.Cyan); Log.Texte("", " / ____ \\| | ____) |", ConsoleColor.Cyan); Log.Texte("", "/_/ \\_\\_| |_____/ APB-World", ConsoleColor.Cyan); Log.Texte("", "http://AllPrivateServer.com", ConsoleColor.DarkCyan); Log.Texte("", "-------------------------------", ConsoleColor.DarkBlue); Assembly.Load("Common"); Log.Info("WorldServer", "Starting ..."); ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<WorldServerConfig>(); if (!Log.InitLog(Config.LogLevel, "WorldServer")) ConsoleMgr.WaitAndExit(2000); FileServerClient = new RpcClient("WorldServer-File-"+Config.WorldID, Config.FileServerRpc.RpcLocalIp, 0); if (!FileServerClient.Start(Config.FileServerRpc.RpcServerIp, Config.FileServerRpc.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); CharacterServerClient = new RpcClient("WorldServer-Char-" + Config.WorldID, Config.CharacterServerRpc.RpcLocalIp, 0); if (!CharacterServerClient.Start(Config.CharacterServerRpc.RpcServerIp, Config.CharacterServerRpc.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); if (!TCPManager.Listen<TcpServer>(Config.WorldServerPort, "World")) ConsoleMgr.WaitAndExit(2000); CharMgr = CharacterServerClient.GetServerObject<CharacterMgr>(); FileMgr = FileServerClient.GetServerObject<FileManager>(); CharMgr.RegisterWorld(CharacterServerClient.Info.RpcID, Config.WorldID, Config.WorldName, Config.WorldServerPort, Config.WorldServerIp); ConsoleMgr.Start(); }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); Log.Texte("", "------------------- Launcher Server -------------------", ConsoleColor.DarkRed); Log.Texte("", " █ █░ ▄▄▄ ██▀███ ▓█████ ███▄ ▄███▓ █ ██ ", ConsoleColor.Red); Log.Texte("", "▓█░ █ ░█░▒████▄ ▓██ ▒ ██▒▓█ ▀ ▓██▒▀█▀ ██▒ ██ ▓██▒", ConsoleColor.Red); Log.Texte("", "▒█░ █ ░█ ▒██ ▀█▄ ▓██ ░▄█ ▒▒███ ▓██ ▓██░▓██ ▒██░", ConsoleColor.Red); Log.Texte("", "░█░ █ ░█ ░██▄▄▄▄██ ▒██▀▀█▄ ▒▓█ ▄ ▒██ ▒██ ▓▓█ ░██░", ConsoleColor.Red); Log.Texte("", "░░██▒██▓ ▓█ ▓██▒░██▓ ▒██▒░▒████▒▒██▒ ░██▒▒▒█████▓ ", ConsoleColor.Red); Log.Texte("", "░ ▓░▒ ▒ ▒▒ ▓▒█░░ ▒▓ ░▒▓░░░ ▒░ ░░ ▒░ ░ ░░▒▓▒ ▒ ▒ ", ConsoleColor.Red); Log.Texte("", " ▒ ░ ░ ▒ ▒▒ ░ ░▒ ░ ▒░ ░ ░ ░░ ░ ░░░▒░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ▒ ░░ ░ ░ ░ ░ ░░░ ░ ░ ", ConsoleColor.Red); Log.Texte("", " ░ ░ ░ ░ ░ ░ ░ ░ ", ConsoleColor.Red); Log.Texte("", "-------------------http://WarEmu.com-------------------", ConsoleColor.DarkRed); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<LauncherConfig>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "LauncherServer")) ConsoleMgr.WaitAndExit(2000); Client = new RpcClient("LauncherServer", Config.RpcInfo.RpcLocalIp, 1); if (!Client.Start(Config.RpcInfo.RpcServerIp, Config.RpcInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); Info = new FileInfo("Configs/mythloginserviceconfig.xml"); if (!Info.Exists) { Log.Error("Configs/mythloginserviceconfig.xml", "Config file missing !"); ConsoleMgr.WaitAndExit(5000); } StrInfo = Info.OpenText().ReadToEnd(); if (!TCPManager.Listen<TCPServer>(Config.LauncherServerPort, "LauncherServer")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("LauncherServer"); ConsoleMgr.Start(); }
private RpcClient CreateAuthenticatedApiClient() { var requestFactory = new TestRequestFactory(); var throttleScopes = new Dictionary<string, IThrottedRequestQueue> { {"data", new ThrottedRequestQueue(TimeSpan.FromSeconds(5), 30, 10)}, {"trading", new ThrottedRequestQueue(TimeSpan.FromSeconds(3), 1, 10)} }; requestFactory.CreateTestRequest(LoggedIn); _testStreamingConnectionFactory = new TestStreamingConnectionFactory(); var ctx = new RpcClient(new Uri(TestConfig.RpcUrl), new Uri(TestConfig.StreamingUrl), new RequestCache(), requestFactory, _testStreamingConnectionFactory, throttleScopes, 3); ctx.LogIn(TestConfig.ApiUsername, TestConfig.ApiPassword); return ctx; }
public void Request_and_Response_should_be_handled() { _subscriber = new RpcSubscriber(new MessageHandlerProvider(new MessageHandlerTypeCache(), null), ComponentLocator.Current.Get<IRabbitConnection>(), new MessageFormatter(new Utf8MessageSerializer(null), new JsonMessageStringifier(null), null), null); _subscriber.Subscribe(QueuesConfiguration.FromCode(new Queue() { Name = "TestQueue_RPC", IsRcp = true })); var client = new RpcClient( new MessageFormatter(new Utf8MessageSerializer(null), new JsonMessageStringifier(null), null), ComponentLocator.Current.Get<IModel>(), null); var res = client.Request<MyResultMessage3>(new MyMessage3() { A = "Piotrek" }, "TestQueue_RPC"); res.B.Should().Be("Piotrek"); }
static void Main(string[] args) { Int32 port = 13000; TcpClient tcpClient = new TcpClient("127.0.0.1", port); var controller = new RpcController(); var client = new RpcClient(controller); var channel = new NetworkStreamRpcChannel(controller, tcpClient.GetStream()); channel.Start(); ISampleService service = client.GetProxy<ISampleService>(); int counter = 0; while (true) { Console.WriteLine("Enter number to test:"); int x = Int32.Parse(Console.ReadLine()); bool isPrime; if (counter++ % 2 == 0) { Console.WriteLine(" Asking server if " + x + " is prime..."); isPrime = service.TestPrime(x); } else { Console.WriteLine(" Asking server if " + x + " is prime, using an async query..."); IAsyncResult asyncResult = service.BeginTestPrime(x, null, null); Console.WriteLine(" Doing some other stuff while the server is calculating..."); isPrime = service.EndTestPrime(asyncResult); } if (isPrime) Console.WriteLine(" Server says: Prime!"); else Console.WriteLine(" Server says: Not prime!"); } }
static void Main(string[] args) { var topologyLoader = new TopologyLoader("../Topology/topology.txt", Encoding.UTF8, new TopologyParser()); var client = new RpcClient(topologyLoader); var myService = client.GetService<IMyService>(); string line; while ((line = Console.ReadLine()) != "exit") { switch (line) { case "greet": { Console.Write("Enter a name: "); var name = Console.ReadLine(); var greeting = myService.Greet(name); Console.WriteLine(greeting); } break; case "add": { Console.Write("Enter a: "); var a = int.Parse(Console.ReadLine()); Console.Write("Enter b: "); var b = int.Parse(Console.ReadLine()); var sum = myService.Add(a, b); Console.WriteLine(sum); } break; default: { Console.WriteLine("Unkown command"); } break; } } }
static void Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(onError); // Loading all configs files ConfigMgr.LoadConfigs(); Config = ConfigMgr.GetConfig<LobbyConfigs>(); // Loading log level from file if (!Log.InitLog(Config.LogLevel, "LobbyServer")) ConsoleMgr.WaitAndExit(2000); Client = new RpcClient("LobbyServer", Config.RpcInfo.RpcLocalIp, 1); if (!Client.Start(Config.RpcInfo.RpcServerIp, Config.RpcInfo.RpcServerPort)) ConsoleMgr.WaitAndExit(2000); if (!TCPManager.Listen<TCPServer>(Config.ClientPort, "LobbyServer")) ConsoleMgr.WaitAndExit(2000); Server = TCPManager.GetTcp<TCPServer>("LobbyServer"); ConsoleMgr.Start(); }
public async Task <IActionResult> PostInputsAsync([FromBody, Required] InputsRequest4 request) { // Validate request. if (request.RoundId < 0) { return(BadRequest("Invalid request.")); } if (request.Inputs.Count() > 7) { return(BadRequest("Maximum 7 inputs can be registered.")); } using (await InputsLock.LockAsync()) { CoordinatorRound round = Coordinator.TryGetRound(request.RoundId); if (round is null || round.Phase != RoundPhase.InputRegistration) { return(NotFound("No such running round in InputRegistration. Try another round.")); } // Do more checks. try { var blindedOutputs = request.BlindedOutputScripts.ToArray(); int blindedOutputCount = blindedOutputs.Length; int maxBlindedOutputCount = round.MixingLevels.Count(); if (blindedOutputCount > maxBlindedOutputCount) { return(BadRequest($"Too many blinded output was provided: {blindedOutputCount}, maximum: {maxBlindedOutputCount}.")); } if (blindedOutputs.Distinct().Count() < blindedOutputs.Length) { return(BadRequest("Duplicate blinded output found.")); } if (round.ContainsAnyBlindedOutputScript(blindedOutputs.Select(x => x.BlindedOutput))) { return(BadRequest("Blinded output has already been registered.")); } if (request.ChangeOutputAddress.Network != Network) { // RegTest and TestNet address formats are sometimes the same. if (Network == Network.Main) { return(BadRequest($"Invalid ChangeOutputAddress Network.")); } } var uniqueInputs = new HashSet <OutPoint>(); foreach (InputProofModel inputProof in request.Inputs) { var outpoint = inputProof.Input; if (uniqueInputs.Contains(outpoint)) { return(BadRequest("Cannot register an input twice.")); } uniqueInputs.Add(outpoint); } var alicesToRemove = new HashSet <Guid>(); var getTxOutResponses = new List <(InputProofModel inputModel, Task <GetTxOutResponse> getTxOutTask)>(); var batch = RpcClient.PrepareBatch(); foreach (InputProofModel inputProof in request.Inputs) { if (round.ContainsInput(inputProof.Input, out List <Alice> tr)) { alicesToRemove.UnionWith(tr.Select(x => x.UniqueId)); // Input is already registered by this alice, remove it later if all the checks are completed fine. } if (Coordinator.AnyRunningRoundContainsInput(inputProof.Input, out List <Alice> tnr)) { if (tr.Union(tnr).Count() > tr.Count) { return(BadRequest("Input is already registered in another round.")); } } OutPoint outpoint = inputProof.Input; var bannedElem = await Coordinator.UtxoReferee.TryGetBannedAsync(outpoint, notedToo : false); if (bannedElem is { }) { return(BadRequest($"Input is banned from participation for {(int)bannedElem.BannedRemaining.TotalMinutes} minutes: {inputProof.Input.N}:{inputProof.Input.Hash}.")); } var txOutResponseTask = batch.GetTxOutAsync(inputProof.Input.Hash, (int)inputProof.Input.N, includeMempool: true); getTxOutResponses.Add((inputProof, txOutResponseTask)); } // Perform all RPC request at once await batch.SendBatchAsync(); byte[] blindedOutputScriptHashesByte = ByteHelpers.Combine(blindedOutputs.Select(x => x.BlindedOutput.ToBytes())); uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blindedOutputScriptHashesByte)); var inputs = new HashSet <Coin>(); var allInputsConfirmed = true; foreach (var responses in getTxOutResponses) { var(inputProof, getTxOutResponseTask) = responses; var getTxOutResponse = await getTxOutResponseTask; // Check if inputs are unspent. if (getTxOutResponse is null) { return(BadRequest($"Provided input is not unspent: {inputProof.Input.N}:{inputProof.Input.Hash}.")); } // Check if unconfirmed. if (getTxOutResponse.Confirmations <= 0) { // If it spends a CJ then it may be acceptable to register. if (!await Coordinator.ContainsUnconfirmedCoinJoinAsync(inputProof.Input.Hash)) { return(BadRequest("Provided input is neither confirmed, nor is from an unconfirmed coinjoin.")); } allInputsConfirmed = false; } // Check if immature. if (getTxOutResponse.IsCoinBase && getTxOutResponse.Confirmations <= 100) { return(BadRequest("Provided input is immature.")); } // Check if inputs are native segwit. if (getTxOutResponse.ScriptPubKeyType != "witness_v0_keyhash") { return(BadRequest("Provided input must be witness_v0_keyhash.")); } TxOut txOut = getTxOutResponse.TxOut; var address = (BitcoinWitPubKeyAddress)txOut.ScriptPubKey.GetDestinationAddress(Network); // Check if proofs are valid. if (!address.VerifyMessage(blindedOutputScriptsHash, inputProof.Proof)) { return(BadRequest("Provided proof is invalid.")); } inputs.Add(new Coin(inputProof.Input, txOut)); } if (!allInputsConfirmed) { // Check if mempool would accept a fake transaction created with the registered inputs. // Fake outputs: mixlevels + 1 maximum, +1 because there can be a change. var result = await RpcClient.TestMempoolAcceptAsync(inputs, fakeOutputCount : round.MixingLevels.Count() + 1, round.FeePerInputs, round.FeePerOutputs); if (!result.accept) { return(BadRequest($"Provided input is from an unconfirmed coinjoin, but a limit is reached: {result.rejectReason}")); } } var acceptedBlindedOutputScripts = new List <BlindedOutputWithNonceIndex>(); // Calculate expected networkfee to pay after base denomination. int inputCount = inputs.Count; Money networkFeeToPayAfterBaseDenomination = (inputCount * round.FeePerInputs) + (2 * round.FeePerOutputs); // Check if inputs have enough coins. Money inputSum = inputs.Sum(x => x.Amount); Money changeAmount = (inputSum - (round.MixingLevels.GetBaseDenomination() + networkFeeToPayAfterBaseDenomination)); if (changeAmount < Money.Zero) { return(BadRequest($"Not enough inputs are provided. Fee to pay: {networkFeeToPayAfterBaseDenomination.ToString(false, true)} BTC. Round denomination: {round.MixingLevels.GetBaseDenomination().ToString(false, true)} BTC. Only provided: {inputSum.ToString(false, true)} BTC.")); } acceptedBlindedOutputScripts.Add(blindedOutputs.First()); Money networkFeeToPay = networkFeeToPayAfterBaseDenomination; // Make sure we sign the proper number of additional blinded outputs. var moneySoFar = Money.Zero; for (int i = 1; i < blindedOutputCount; i++) { if (!round.MixingLevels.TryGetDenomination(i, out Money denomination)) { break; } Money coordinatorFee = denomination.Percentage(round.CoordinatorFeePercent * round.AnonymitySet); // It should be the number of bobs, but we must make sure they'd have money to pay all. changeAmount -= (denomination + round.FeePerOutputs + coordinatorFee); networkFeeToPay += round.FeePerOutputs; if (changeAmount < Money.Zero) { break; } acceptedBlindedOutputScripts.Add(blindedOutputs[i]); } // Make sure Alice checks work. var alice = new Alice(inputs, networkFeeToPayAfterBaseDenomination, request.ChangeOutputAddress, acceptedBlindedOutputScripts.Select(x => x.BlindedOutput)); foreach (Guid aliceToRemove in alicesToRemove) { round.RemoveAlicesBy(aliceToRemove); } round.AddAlice(alice); // All checks are good. Sign. var blindSignatures = new List <uint256>(); for (int i = 0; i < acceptedBlindedOutputScripts.Count; i++) { var blindedOutput = acceptedBlindedOutputScripts[i]; var signer = round.MixingLevels.GetLevel(i).Signer; uint256 blindSignature = signer.Sign(blindedOutput.BlindedOutput, round.NonceProvider.GetNonceKeyForIndex(blindedOutput.N)); blindSignatures.Add(blindSignature); } alice.BlindedOutputSignatures = blindSignatures.ToArray(); // Check if phase changed since. if (round.Status != CoordinatorRoundStatus.Running || round.Phase != RoundPhase.InputRegistration) { return(StatusCode(StatusCodes.Status503ServiceUnavailable, "The state of the round changed while handling the request. Try again.")); } // Progress round if needed. if (round.CountAlices() >= round.AnonymitySet) { await round.RemoveAlicesIfAnInputRefusedByMempoolAsync(); if (round.CountAlices() >= round.AnonymitySet) { await round.ExecuteNextPhaseAsync(RoundPhase.ConnectionConfirmation); } } var resp = new InputsResponse { UniqueId = alice.UniqueId, RoundId = round.RoundId }; return(Ok(resp)); }
public static GetRegistrantResult GetRegistrantAsync(string name, WalletOptions options = null) { options = options ?? new WalletOptions(); return(RpcClient.GetRegistrant(options.RpcServerAddress, name)); }
public void TestConstructorWithBasicAuth() { var client = new RpcClient("http://www.xxx.yyy", "krain", "123456"); client.Dispose(); }
public GetSubscriptionResult GetSubscriptionAsync(string topic, string subscriber) => RpcClient.GetSubscription(this.Options.RpcServerAddress, topic, subscriber);
public static GetNonceByAddrResult GetNonceAsync(string address, WalletOptions options = null) { options = options ?? new WalletOptions(); return(RpcClient.GetNonceByAddress(options.RpcServerAddress, address)); }
public string SubscribeAsync(string topic, int duration, string identifier, string meta, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.Subscribe(topic, duration, identifier, meta, this, options)); }
public string TransferNameAsync(string name, string recipient, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.TransferName(name, recipient, this, options)); }
public async Task <dynamic> ExecuteTestAsync(RpcClient client) { var ethNewBlockFilter = new EthNewBlockFilter(client); return(await ethNewBlockFilter.SendRequestAsync()); }
public async Task <dynamic> ExecuteTestAsync(RpcClient client) { var ethGetUncleCountByBlockHash = new EthGetUncleCountByBlockHash(client); return(await ethGetUncleCountByBlockHash.SendRequestAsync("0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238")); }
public CcjCoordinator(Network network, string folderPath, RPCClient rpc, CcjRoundConfig roundConfig) { Network = Guard.NotNull(nameof(network), network); FolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(folderPath), folderPath, trim: true); RpcClient = Guard.NotNull(nameof(rpc), rpc); RoundConfig = Guard.NotNull(nameof(roundConfig), roundConfig); Rounds = new List <CcjRound>(); RoundsListLock = new AsyncLock(); CoinJoins = new List <uint256>(); UnconfirmedCoinJoins = new List <uint256>(); CoinJoinsLock = new AsyncLock(); Directory.CreateDirectory(FolderPath); UtxoReferee = new UtxoReferee(Network, FolderPath, RpcClient); // Initialize RsaKey string rsaKeyPath = Path.Combine(FolderPath, "RsaKey.json"); if (File.Exists(rsaKeyPath)) { string rsaKeyJson = File.ReadAllText(rsaKeyPath, encoding: Encoding.UTF8); RsaKey = BlindingRsaKey.CreateFromJson(rsaKeyJson); } else { RsaKey = new BlindingRsaKey(); File.WriteAllText(rsaKeyPath, RsaKey.ToJson(), encoding: Encoding.UTF8); Logger.LogInfo <CcjCoordinator>($"Created RSA key at: {rsaKeyPath}"); } if (File.Exists(CoinJoinsFilePath)) { try { var toRemove = new List <string>(); string[] allLines = File.ReadAllLines(CoinJoinsFilePath); foreach (string line in allLines) { try { uint256 txHash = new uint256(line); RPCResponse getRawTransactionResponse = RpcClient.SendCommand(RPCOperations.getrawtransaction, txHash.ToString(), true); CoinJoins.Add(txHash); if (getRawTransactionResponse.Result.Value <int>("confirmations") <= 0) { UnconfirmedCoinJoins.Add(txHash); } } catch (Exception ex) { toRemove.Add(line); var logEntry = ex is RPCException rpce && rpce.RPCCode == RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY ? $"CoinJoins file contains invalid transaction ID {line}" : $"CoinJoins file got corrupted. Deleting offending line \"{line.Substring(0, 20)}\"."; Logger.LogWarning <CcjCoordinator>($"{logEntry}. {ex.GetType()}: {ex.Message}"); } } if (toRemove.Count != 0) // a little performance boost, it'll be empty almost always { var newAllLines = allLines.Where(x => !toRemove.Contains(x)); File.WriteAllLines(CoinJoinsFilePath, newAllLines); } } catch (Exception ex) { Logger.LogWarning <CcjCoordinator>($"CoinJoins file got corrupted. Deleting {CoinJoinsFilePath}. {ex.GetType()}: {ex.Message}"); File.Delete(CoinJoinsFilePath); } } }
public EthGetWork(RpcClient client) : base(client, ApiMethods.eth_getWork.ToString()) { }
public async Task <IActionResult> GetTransactionsAsync([FromQuery, Required] IEnumerable <string> transactionIds) { if (!ModelState.IsValid) { return(BadRequest("Invalid transaction Ids.")); } var maxTxToRequest = 10; if (transactionIds.Count() > maxTxToRequest) { return(BadRequest($"Maximum {maxTxToRequest} transactions can be requested.")); } var parsedIds = new List <uint256>(); try { // Remove duplicates, do not use Distinct(), order is not guaranteed. foreach (var txid in transactionIds.Select(x => new uint256(x))) { if (!parsedIds.Contains(txid)) { parsedIds.Add(txid); } } } catch { return(BadRequest("Invalid transaction Ids.")); } try { var hexes = new Dictionary <uint256, string>(); var queryRpc = false; IRPCClient batchingRpc = null; List <Task <Transaction> > tasks = null; lock (TransactionHexCacheLock) { foreach (var txid in parsedIds) { if (TransactionHexCache.TryGetValue(txid, out string hex)) { hexes.Add(txid, hex); } else { if (!queryRpc) { queryRpc = true; batchingRpc = RpcClient.PrepareBatch(); tasks = new List <Task <Transaction> >(); } tasks.Add(batchingRpc.GetRawTransactionAsync(txid)); } } } if (queryRpc) { await batchingRpc.SendBatchAsync(); foreach (var tx in await Task.WhenAll(tasks)) { string hex = tx.ToHex(); hexes.Add(tx.GetHash(), hex); lock (TransactionHexCacheLock) { if (TransactionHexCache.TryAdd(tx.GetHash(), hex) && TransactionHexCache.Count >= 1000) { TransactionHexCache.Remove(TransactionHexCache.Keys.First()); } } } } // Order hexes according to the order of the query. var orderedResult = parsedIds.Where(x => hexes.ContainsKey(x)).Select(x => hexes[x]); return(Ok(orderedResult)); } catch (Exception ex) { Logger.LogDebug(ex); return(BadRequest(ex.Message)); } }
public string UnsubscribeAsync(string topic, string identifier, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.Unsubscribe(topic, identifier, this, options)); }
private volatile bool _disposedValue = false; // To detect redundant calls public Coordinator(Network network, BlockNotifier blockNotifier, string folderPath, IRPCClient rpc, CoordinatorRoundConfig roundConfig) { Network = Guard.NotNull(nameof(network), network); BlockNotifier = Guard.NotNull(nameof(blockNotifier), blockNotifier); FolderPath = Guard.NotNullOrEmptyOrWhitespace(nameof(folderPath), folderPath, trim: true); RpcClient = Guard.NotNull(nameof(rpc), rpc); RoundConfig = Guard.NotNull(nameof(roundConfig), roundConfig); Rounds = new List <CoordinatorRound>(); RoundsListLock = new AsyncLock(); CoinJoins = new List <uint256>(); UnconfirmedCoinJoins = new List <uint256>(); CoinJoinsLock = new AsyncLock(); LastSuccessfulCoinJoinTime = DateTimeOffset.UtcNow; Directory.CreateDirectory(FolderPath); UtxoReferee = new UtxoReferee(Network, FolderPath, RpcClient, RoundConfig); if (File.Exists(CoinJoinsFilePath)) { try { var getTxTasks = new List <(Task <Transaction> txTask, string line)>(); var batch = RpcClient.PrepareBatch(); var toRemove = new List <string>(); string[] allLines = File.ReadAllLines(CoinJoinsFilePath); foreach (string line in allLines) { try { getTxTasks.Add((batch.GetRawTransactionAsync(uint256.Parse(line)), line)); } catch (Exception ex) { toRemove.Add(line); var logEntry = ex is RPCException rpce && rpce.RPCCode == RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY ? $"CoinJoins file contains invalid transaction ID {line}" : $"CoinJoins file got corrupted. Deleting offending line \"{line.Substring(0, 20)}\"."; Logger.LogWarning($"{logEntry}. {ex.GetType()}: {ex.Message}"); } } batch.SendBatchAsync().GetAwaiter().GetResult(); foreach (var(txTask, line) in getTxTasks) { try { var tx = txTask.GetAwaiter().GetResult(); CoinJoins.Add(tx.GetHash()); } catch (Exception ex) { toRemove.Add(line); var logEntry = ex is RPCException rpce && rpce.RPCCode == RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY ? $"CoinJoins file contains invalid transaction ID {line}" : $"CoinJoins file got corrupted. Deleting offending line \"{line.Substring(0, 20)}\"."; Logger.LogWarning($"{logEntry}. {ex.GetType()}: {ex.Message}"); } } if (toRemove.Count != 0) // a little performance boost, it'll be empty almost always { var newAllLines = allLines.Where(x => !toRemove.Contains(x)); File.WriteAllLines(CoinJoinsFilePath, newAllLines); } } catch (Exception ex) { Logger.LogWarning($"CoinJoins file got corrupted. Deleting {CoinJoinsFilePath}. {ex.GetType()}: {ex.Message}"); File.Delete(CoinJoinsFilePath); } uint256[] mempoolHashes = RpcClient.GetRawMempoolAsync().GetAwaiter().GetResult(); UnconfirmedCoinJoins.AddRange(CoinJoins.Intersect(mempoolHashes)); } try { string roundCountFilePath = Path.Combine(folderPath, "RoundCount.txt"); if (File.Exists(roundCountFilePath)) { string roundCount = File.ReadAllText(roundCountFilePath); CoordinatorRound.RoundCount = long.Parse(roundCount); } else { // First time initializes (so the first constructor will increment it and we'll start from 1.) CoordinatorRound.RoundCount = 0; } } catch (Exception ex) { CoordinatorRound.RoundCount = 0; Logger.LogInfo($"{nameof(CoordinatorRound.RoundCount)} file was corrupt. Resetting to 0."); Logger.LogDebug(ex); } BlockNotifier.OnBlock += BlockNotifier_OnBlockAsync; }
public string DeleteNameAsync(string name, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.DeleteName(name, this, options)); }
public PolicyAPIDemo(RpcClient rpcClient) { this.rpcClient = rpcClient; this.policyAPI = new PolicyAPI(rpcClient); }
public string TransferToAsync(string toAddress, decimal amount, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.TransferTo(toAddress, new Amount(amount), this, options)); }
public void Synchronize() { Task.Run(async() => { try { if (Interlocked.Read(ref _workerCount) >= 2) { return; } Interlocked.Increment(ref _workerCount); while (Interlocked.Read(ref _workerCount) != 1) { await Task.Delay(100); } if (IsStopping) { return; } try { Interlocked.Exchange(ref _serviceStatus, Running); SyncInfo syncInfo = null; while (IsRunning) { try { // If we did not yet initialized syncInfo, do so. syncInfo ??= await GetSyncInfoAsync().ConfigureAwait(false); uint currentHeight = 0; uint256 currentHash = null; using (await IndexLock.LockAsync()) { if (Index.Count != 0) { var lastIndex = Index[^ 1]; currentHeight = lastIndex.Header.Height; currentHash = lastIndex.Header.BlockHash; } else { currentHash = StartingHeight == 0 ? uint256.Zero : await RpcClient.GetBlockHashAsync((int)StartingHeight - 1); currentHeight = StartingHeight - 1; } } var coreNotSynced = !syncInfo.IsCoreSynchornized; var tipReached = syncInfo.BlockCount == currentHeight; var isTimeToRefresh = DateTimeOffset.UtcNow - syncInfo.BlockchainInfoUpdated > TimeSpan.FromMinutes(5); if (coreNotSynced || tipReached || isTimeToRefresh) { syncInfo = await GetSyncInfoAsync(); } // If wasabi filter height is the same as core we may be done. if (syncInfo.BlockCount == currentHeight) { // Check that core is fully synced if (syncInfo.IsCoreSynchornized && !syncInfo.InitialBlockDownload) { // Mark the process notstarted, so it can be started again // and finally block can mark it as stopped. Interlocked.Exchange(ref _serviceStatus, NotStarted); return; } else { // Knots is catching up give it a 10 seconds await Task.Delay(10000); continue; } } uint nextHeight = currentHeight + 1; uint256 blockHash = await RpcClient.GetBlockHashAsync((int)nextHeight); VerboseBlockInfo block = await RpcClient.GetVerboseBlockAsync(blockHash); // Check if we are still on the best chain, // if not rewind filters till we find the fork. if (currentHash != block.PrevBlockHash) { Logger.LogWarning("Reorg observed on the network."); await ReorgOneAsync(); // Skip the current block. continue; } var scripts = FetchScripts(block); GolombRiceFilter filter; if (scripts.Any()) { filter = new GolombRiceFilterBuilder() .SetKey(block.Hash) .SetP(20) .SetM(1 << 20) .AddEntries(scripts.Select(x => x.ToCompressedBytes())) .Build(); } else { // We cannot have empty filters, because there was a bug in GolombRiceFilterBuilder that evaluates empty filters to true. // And this must be fixed in a backwards compatible way, so we create a fake filter with a random scp instead. filter = CreateDummyEmptyFilter(block.Hash); } var smartHeader = new SmartHeader(block.Hash, block.PrevBlockHash, nextHeight, block.BlockTime); var filterModel = new FilterModel(smartHeader, filter); await File.AppendAllLinesAsync(IndexFilePath, new[] { filterModel.ToLine() }); using (await IndexLock.LockAsync()) { Index.Add(filterModel); } // If not close to the tip, just log debug. if (syncInfo.BlockCount - nextHeight <= 3 || nextHeight % 100 == 0) { Logger.LogInfo($"Created filter for block: {nextHeight}."); } else { Logger.LogDebug($"Created filter for block: {nextHeight}."); } LastFilterBuildTime = DateTimeOffset.UtcNow; }
public static string SendTransactionAsync(Transaction tx, TransactionOptions options = null) { options = options ?? new TransactionOptions(); return(RpcClient.SendRawTransaction(options.RpcServerAddress, tx)); }
private static async Task AssertRpcNodeFullyInitializedAsync() { try { var blockchainInfo = await RpcClient.GetBlockchainInfoAsync(); var blocks = blockchainInfo.Blocks; if (blocks == 0 && Config.Network != Network.RegTest) { throw new NotSupportedException("blocks == 0"); } var headers = blockchainInfo.Headers; if (headers == 0 && Config.Network != Network.RegTest) { throw new NotSupportedException("headers == 0"); } if (blocks != headers) { throw new NotSupportedException("Bitcoin Core is not fully synchronized."); } Logger.LogInfo <RPCClient>("Bitcoin Core is fully synchronized."); var estimateSmartFeeResponse = await RpcClient.TryEstimateSmartFeeAsync(2, EstimateSmartFeeMode.Conservative, simulateIfRegTest : true); if (estimateSmartFeeResponse == null) { throw new NotSupportedException("Bitcoin Core cannot estimate network fees yet."); } Logger.LogInfo <RPCClient>("Bitcoin Core fee estimation is working."); if (Config.Network == Network.RegTest) // Make sure there's at least 101 block, if not generate it { if (blocks < 101) { var generateBlocksResponse = await RpcClient.GenerateAsync(101); if (generateBlocksResponse == null) { throw new NotSupportedException("Bitcoin Core cannot cannot generate blocks on the RegTest."); } blockchainInfo = await RpcClient.GetBlockchainInfoAsync(); blocks = blockchainInfo.Blocks; if (blocks == 0) { throw new NotSupportedException("blocks == 0"); } Logger.LogInfo <RPCClient>($"Generated 101 block on RegTest. Number of blocks {blocks}."); } } } catch (WebException) { Logger.LogError($"Bitcoin Core is not running, or incorrect RPC credentials or network is given in the config file: `{Config.FilePath}`."); throw; } }
public static int GetSubscribersCountAsync(string topic, WalletOptions options = null) { options = options ?? new WalletOptions(); return(RpcClient.GetSubscribersCount(options.RpcServerAddress, topic)); }
public RpcBase(string uri) { System.Net.Http.Headers.AuthenticationHeaderValue headerValue = null; this.client = new RpcClient(new Uri(uri), headerValue); }
public static GetLatestBlockHashResult GetLatestBlockAsync(WalletOptions options = null) { options = options ?? new WalletOptions(); return(RpcClient.GetLatestBlockHash(options.RpcServerAddress)); }
public JsonRpcClient(Context ctx, PhpString url) { _client = new RpcClient(new Uri(url.ToString(ctx))); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services .AddLocalization(options => options.ResourcesPath = "Resources") .AddEntityFrameworkNpgsql() .AddDbContext <ApplicationDbContext>(options => options.UseNpgsql(Configuration.GetConnectionString("CWPConnection"))) .AddDbContext <DataProtectionDbContext>(options => options.UseNpgsql(Configuration.GetConnectionString("DPConnection")), ServiceLifetime.Singleton, ServiceLifetime.Singleton) .AddAuthorization() .AddTransient <IEmailSender, EmailSender>() .AddSingleton <ISlackClient, SlackClient>(config => { var conf = config.GetService <IOptions <SlackSettings> >(); return(new SlackClient(conf.Value.SubscribeChannelUrl)); }) .Configure <MailSettings>(Configuration.GetSection("MailSettings")) .Configure <SlackSettings>(Configuration.GetSection("SlackWebHooks")) .Configure <IdentityOptions>(options => { // Password settings options.Password.RequireDigit = true; options.Password.RequiredLength = 8; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = true; options.Password.RequiredUniqueChars = 6; // Lockout settings options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings options.User.RequireUniqueEmail = true; // Confirmations options.SignIn.RequireConfirmedEmail = false; options.SignIn.RequireConfirmedPhoneNumber = false; }); services.Configure <DataProtectionTokenProviderOptions>(o => { o.Name = "Default"; o.TokenLifespan = TimeSpan.FromHours(24); }); services.AddMvc(); services.AddDataProtection() .PersistKeysToSql() .SetDefaultKeyLifetime(TimeSpan.FromDays(7)) .SetApplicationName("CWPIO"); services.AddIdentity <ApplicationUser, IdentityRole>() .AddEntityFrameworkStores <ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddAuthentication() .AddFacebook(options => { options.AppId = Configuration["Authentication:Facebook:AppId"]; options.AppSecret = Configuration["Authentication:Facebook:AppSecret"]; }) .AddGoogle(options => { options.ClientId = Configuration["Authentication:Google:ClientId"]; options.ClientSecret = Configuration["Authentication:Google:ClientSecret"]; }) .AddTwitter(options => { options.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"]; options.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"]; }); services.Configure <EthSettings>(Configuration.GetSection("Ether")); services.AddSingleton(s => { var settings = s.GetService <IOptions <EthSettings> >().Value; var password = settings.AppPrivateKey; var account = new Account(settings.AppPrivateKey); // var authHeader = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{settings.NodeLogin}:{settings.NodePass}")); var uri = new Uri(settings.NodeUrl ?? "http://localhost:8545"); var authHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(uri.UserInfo)); var client = new RpcClient(uri, new AuthenticationHeaderValue("Basic", authHeader)); return(new Web3(account, client)); }); services.AddSingleton <TokenSaleContract>(); services.Configure <RateStoreSettings>(Configuration.GetSection("RateStore")); services.AddSingleton <IRateStore, RateStore>(); services.AddMemoryCache(); //load general configuration from appsettings.json services.Configure <IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); //load client rules from appsettings.json services.Configure <IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies")); // inject counter and rules stores services.AddSingleton <IIpPolicyStore, MemoryCacheIpPolicyStore>(); services.AddSingleton <IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); services.Configure <GoogleDriveSettings>(Configuration.GetSection("GDrive")); services.AddSingleton(s => { var settings = s.GetRequiredService <IOptions <GoogleDriveSettings> >().Value; var serviceAccountEmail = settings.ServiceAccount; var certificate = new X509Certificate2(settings.P12CertPath, "notasecret", X509KeyStorageFlags.Exportable); ServiceAccountCredential credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail) { Scopes = new[] { DriveService.Scope.Drive } }.FromCertificate(certificate)); return(new DriveService(new BaseClientService.Initializer { ApplicationName = "CWPIO", HttpClientInitializer = credential })); }); services.AddSingleton <IFileRepository, FileRepository>(); services.AddSingleton <Crypto>(); services.AddResponseCompression(); }
public async Task <dynamic> ExecuteTestAsync(RpcClient client) { var ethGasPrice = new EthGasPrice(client); return(await ethGasPrice.SendRequestAsync()); }
internal BlocksQuery(RpcClient client, string query) : base(client, query) { }
public async Task <dynamic> ExecuteTestAsync(RpcClient client) { var ethAccounts = new EthAccounts(client); return(await ethAccounts.SendRequestAsync()); }
public async Task ExecuteNextPhaseAsync(CcjRoundPhase expectedPhase) { using (await RoundSynchronizerLock.LockAsync()) { try { Logger.LogInfo <CcjRound>($"Round ({RoundId}): Phase change requested: {expectedPhase.ToString()}."); if (Status == CcjRoundStatus.NotStarted) // So start the input registration phase { if (expectedPhase != CcjRoundPhase.InputRegistration) { return; } // Calculate fees var inputSizeInBytes = (int)Math.Ceiling(((3 * Constants.P2wpkhInputSizeInBytes) + Constants.P2pkhInputSizeInBytes) / 4m); var outputSizeInBytes = Constants.OutputSizeInBytes; try { var estimateSmartFeeResponse = await RpcClient.EstimateSmartFeeAsync(ConfirmationTarget, EstimateSmartFeeMode.Conservative, simulateIfRegTest : true); if (estimateSmartFeeResponse is null) { throw new InvalidOperationException("FeeRate is not yet initialized"); } var feeRate = estimateSmartFeeResponse.FeeRate; Money feePerBytes = (feeRate.FeePerK / 1000); // Make sure min relay fee (1000 sat) is hit. FeePerInputs = Math.Max(feePerBytes * inputSizeInBytes, new Money(500)); FeePerOutputs = Math.Max(feePerBytes * outputSizeInBytes, new Money(250)); } catch (Exception ex) { // If fee hasn't been initialized once, fall back. if (FeePerInputs is null || FeePerOutputs is null) { var feePerBytes = new Money(100); // 100 satoshi per byte // Make sure min relay fee (1000 sat) is hit. FeePerInputs = Math.Max(feePerBytes * inputSizeInBytes, new Money(500)); FeePerOutputs = Math.Max(feePerBytes * outputSizeInBytes, new Money(250)); } Logger.LogError <CcjRound>(ex); } Status = CcjRoundStatus.Running; } else if (Status != CcjRoundStatus.Running) // Aborted or succeeded, swallow { return; } else if (Phase == CcjRoundPhase.InputRegistration) { if (expectedPhase != CcjRoundPhase.ConnectionConfirmation) { return; } RoundHash = NBitcoinHelpers.HashOutpoints(Alices.SelectMany(x => x.Inputs).Select(y => y.OutPoint)); Phase = CcjRoundPhase.ConnectionConfirmation; } else if (Phase == CcjRoundPhase.ConnectionConfirmation) { if (expectedPhase != CcjRoundPhase.OutputRegistration) { return; } Phase = CcjRoundPhase.OutputRegistration; } else if (Phase == CcjRoundPhase.OutputRegistration) { if (expectedPhase != CcjRoundPhase.Signing) { return; } // Build CoinJoin // 1. Set new denomination: minor optimization. Money newDenomination = Alices.Min(x => x.OutputSumWithoutCoordinatorFeeAndDenomination); var transaction = RpcClient.Network.Consensus.ConsensusFactory.CreateTransaction(); // 2. Add Bob outputs. foreach (Bob bob in Bobs) { transaction.AddOutput(newDenomination, bob.ActiveOutputAddress.ScriptPubKey); } BitcoinWitPubKeyAddress coordinatorAddress = Constants.GetCoordinatorAddress(RpcClient.Network); // 3. If there are less Bobs than Alices, then add our own address. The malicious Alice, who will refuse to sign. for (int i = 0; i < Alices.Count - Bobs.Count; i++) { transaction.AddOutput(newDenomination, coordinatorAddress); } // 4. Start building Coordinator fee. Money coordinatorFeePerAlice = newDenomination.Percentange(CoordinatorFeePercent) * Alices.Count; Money coordinatorFee = Alices.Count * coordinatorFeePerAlice; // 5. Add the inputs and the changes of Alices. var spentCoins = new List <Coin>(); foreach (Alice alice in Alices) { foreach (var input in alice.Inputs) { transaction.AddInput(new TxIn(input.OutPoint)); spentCoins.Add(new Coin(input.OutPoint, input.Output)); } Money changeAmount = alice.GetChangeAmount(newDenomination, coordinatorFeePerAlice); if (changeAmount > Money.Zero) // If the coordinator fee would make change amount to be negative or zero then no need to pay it. { Money minimumOutputAmount = Money.Coins(0.0001m); // If the change would be less than about $1 then add it to the coordinator. Money onePercentOfDenomination = newDenomination.Percentange(1m); // If the change is less than about 1% of the newDenomination then add it to the coordinator fee. Money minimumChangeAmount = Math.Max(minimumOutputAmount, onePercentOfDenomination); if (changeAmount < minimumChangeAmount) { coordinatorFee += changeAmount; } else { transaction.AddOutput(changeAmount, alice.ChangeOutputAddress.ScriptPubKey); } } else { coordinatorFee -= coordinatorFeePerAlice; } } // 6. Add Coordinator fee only if > about $3, else just let it to be miner fee. if (coordinatorFee > Money.Coins(0.0003m)) { transaction.AddOutput(coordinatorFee, coordinatorAddress); } // 7. Create the unsigned transaction. var builder = new TransactionBuilder(); UnsignedCoinJoin = builder .ContinueToBuild(transaction) .Shuffle() .BuildTransaction(false); // 8. Try optimize fees. try { // 8.1. Estimate the current FeeRate. Note, there are no signatures yet! int estimatedSigSizeBytes = UnsignedCoinJoin.Inputs.Count * Constants.P2wpkhInputSizeInBytes; int estimatedFinalTxSize = UnsignedCoinJoin.GetSerializedSize() + estimatedSigSizeBytes; Money fee = UnsignedCoinJoin.GetFee(spentCoins.ToArray()); // There is a currentFeeRate null check later. FeeRate currentFeeRate = fee is null ? null : new FeeRate(fee, estimatedFinalTxSize); // 8.2. Get the most optimal FeeRate. EstimateSmartFeeResponse estimateSmartFeeResponse = await RpcClient.EstimateSmartFeeAsync(ConfirmationTarget, EstimateSmartFeeMode.Conservative, simulateIfRegTest : true); if (estimateSmartFeeResponse is null) { throw new InvalidOperationException("FeeRate is not yet initialized"); } FeeRate optimalFeeRate = estimateSmartFeeResponse.FeeRate; if (!(optimalFeeRate is null) && optimalFeeRate != FeeRate.Zero && !(currentFeeRate is null) && currentFeeRate != FeeRate.Zero) // This would be really strange if it'd happen. { var sanityFeeRate = new FeeRate(2m); // 2 s/b optimalFeeRate = optimalFeeRate < sanityFeeRate ? sanityFeeRate : optimalFeeRate; if (optimalFeeRate < currentFeeRate) { // 8.2 If the fee can be lowered, lower it. // 8.2.1. How much fee can we save? Money feeShouldBePaid = new Money(estimatedFinalTxSize * (int)optimalFeeRate.SatoshiPerByte); Money toSave = fee - feeShouldBePaid; // 8.2.2. Get the outputs to divide the savings between. int maxMixCount = UnsignedCoinJoin.GetIndistinguishableOutputs().Max(x => x.count); Money bestMixAmount = UnsignedCoinJoin.GetIndistinguishableOutputs().Where(x => x.count == maxMixCount).Max(x => x.value); int bestMixCount = UnsignedCoinJoin.GetIndistinguishableOutputs().First(x => x.value == bestMixAmount).count; // 8.2.3. Get the savings per best mix outputs. long toSavePerBestMixOutputs = toSave.Satoshi / bestMixCount; // 8.2.4. Modify the best mix outputs in the transaction. if (toSavePerBestMixOutputs > 0) { foreach (TxOut output in UnsignedCoinJoin.Outputs.Where(x => x.Value == bestMixAmount)) { output.Value += toSavePerBestMixOutputs; } } } } else { Logger.LogError <CcjRound>($"This is impossible. {nameof(optimalFeeRate)}: {optimalFeeRate}, {nameof(currentFeeRate)}: {currentFeeRate}."); } } catch (Exception ex) { Logger.LogWarning <CcjRound>("Couldn't optimize fees. Fallback to normal fees."); Logger.LogWarning <CcjRound>(ex); } SignedCoinJoin = Transaction.Parse(UnsignedCoinJoin.ToHex(), RpcClient.Network); Phase = CcjRoundPhase.Signing; }
public void Synchronize() { Task.Run(async() => { try { if (Interlocked.Read(ref _workerCount) >= 2) { return; } Interlocked.Increment(ref _workerCount); while (Interlocked.Read(ref _workerCount) != 1) { await Task.Delay(100).ConfigureAwait(false); } if (IsStopping) { return; } try { Interlocked.Exchange(ref _serviceStatus, Running); while (IsRunning) { try { SyncInfo syncInfo = await GetSyncInfoAsync().ConfigureAwait(false); uint currentHeight; uint256?currentHash = null; using (await IndexLock.LockAsync()) { if (Index.Count != 0) { var lastIndex = Index[^ 1]; currentHeight = lastIndex.Header.Height; currentHash = lastIndex.Header.BlockHash; } else { currentHash = StartingHeight == 0 ? uint256.Zero : await RpcClient.GetBlockHashAsync((int)StartingHeight - 1).ConfigureAwait(false); currentHeight = StartingHeight - 1; } } var coreNotSynced = !syncInfo.IsCoreSynchronized; var tipReached = syncInfo.BlockCount == currentHeight; var isTimeToRefresh = DateTimeOffset.UtcNow - syncInfo.BlockchainInfoUpdated > TimeSpan.FromMinutes(5); if (coreNotSynced || tipReached || isTimeToRefresh) { syncInfo = await GetSyncInfoAsync().ConfigureAwait(false); } // If wasabi filter height is the same as core we may be done. if (syncInfo.BlockCount == currentHeight) { // Check that core is fully synced if (syncInfo.IsCoreSynchronized && !syncInfo.InitialBlockDownload) { // Mark the process notstarted, so it can be started again // and finally block can mark it as stopped. Interlocked.Exchange(ref _serviceStatus, NotStarted); return; } else { // Knots is catching up give it a 10 seconds await Task.Delay(10000).ConfigureAwait(false); continue; } } uint nextHeight = currentHeight + 1; uint256 blockHash = await RpcClient.GetBlockHashAsync((int)nextHeight).ConfigureAwait(false); VerboseBlockInfo block = await RpcClient.GetVerboseBlockAsync(blockHash).ConfigureAwait(false); // Check if we are still on the best chain, // if not rewind filters till we find the fork. if (currentHash != block.PrevBlockHash) { Logger.LogWarning("Reorg observed on the network."); await ReorgOneAsync().ConfigureAwait(false); // Skip the current block. continue; } var filter = BuildFilterForBlock(block); var smartHeader = new SmartHeader(block.Hash, block.PrevBlockHash, nextHeight, block.BlockTime); var filterModel = new FilterModel(smartHeader, filter); await File.AppendAllLinesAsync(IndexFilePath, new[] { filterModel.ToLine() }).ConfigureAwait(false); using (await IndexLock.LockAsync()) { Index.Add(filterModel); } // If not close to the tip, just log debug. if (syncInfo.BlockCount - nextHeight <= 3 || nextHeight % 100 == 0) { Logger.LogInfo($"Created filter for block: {nextHeight}."); } else { Logger.LogDebug($"Created filter for block: {nextHeight}."); } LastFilterBuildTime = DateTimeOffset.UtcNow; }