Пример #1
0
        /// <summary>
        /// Sends a request to daemon
        /// </summary>
        /// <param name="Method">The method the request is using</param>
        /// <param name="Params">The parameters to pass in the request</param>
        public Task SendRequestAsync(RequestMethod Method, JObject Params, out JObject Result)
        {
            try
            {
                // Create a POST request
                HttpWebRequest HttpWebRequest = (HttpWebRequest)WebRequest.Create("http://" + Address + ":" + Port + "/json_rpc");
                HttpWebRequest.ContentType = "application/json-rpc";
                HttpWebRequest.Method      = "POST";

                // Create a JSON request
                JObject JRequest = new JObject();
                if (Params.Count > 0)
                {
                    JRequest["params"] = JObject.FromObject(Params);
                }
                JRequest.Add(new JProperty("jsonrpc", "2.0"));
                JRequest.Add(new JProperty("id", "0"));
                JRequest.Add(new JProperty("method", Method.ToString()));
                JRequest.Add(new JProperty("password", TurtleCoin.EncodeString(Hash)));
                String Request = JRequest.ToString();

                // Send bytes to server
                byte[] ByteArray = Encoding.UTF8.GetBytes(Request);
                HttpWebRequest.ContentLength = ByteArray.Length;
                Stream Stream = HttpWebRequest.GetRequestStream();
                Stream.Write(ByteArray, 0, ByteArray.Length);
                Stream.Close();

                // Receive reply from server
                WebResponse  WebResponse = HttpWebRequest.GetResponse();
                StreamReader reader      = new StreamReader(WebResponse.GetResponseStream(), Encoding.UTF8);

                // Get response
                Result = JObject.Parse(reader.ReadToEnd());
                if (Result["result"] != null)
                {
                    Result = (JObject)Result["result"];
                }
                else
                {
                    ThrowError(ErrorCode.BAD_REQUEST);
                }

                // Dispose of pieces
                reader.Dispose();
                WebResponse.Dispose();
            }
            catch
            {
                Result = new JObject();
                ThrowError(ErrorCode.BAD_REQUEST);
            }

            // Completed
            return(Task.CompletedTask);
        }
Пример #2
0
        /// <summary>
        /// Main update loop
        /// </summary>
        private async void Update()
        {
            // Loop as long as the wallet is connected
            while (Connected)
            {
                try
                {
                    // Ensure network connection is still alive
                    if (!Local && !TurtleCoin.Ping(Address, Port))
                    {
                        // Connection was lost
                        await Exit();

                        ThrowError(ErrorCode.CONNECTION_LOST);
                        LogLine("Connection lost");
                        OnDisconnect?.Invoke(this, EventArgs.Empty);
                        break;
                    }
                    else if (Local && Process.HasExited)
                    {
                        // Connection was lost
                        await Exit();

                        ThrowError(ErrorCode.CONNECTION_LOST);
                        LogLine("Connection lost");
                        OnDisconnect?.Invoke(this, EventArgs.Empty);
                        break;
                    }

                    // Create a result object to recycle throughout updates
                    JObject Result = new JObject();

                    // Update status
                    await SendRequestAsync(RequestMethod.GET_STATUS, new JObject { }, out Result);

                    PeerCount       = (double)Result["peerCount"];
                    BlockCount      = (double)Result["blockCount"];
                    LastBlockHash   = (string)Result["lastBlockHash"];
                    KnownBlockCount = (double)Result["knownBlockCount"];

                    // Check if wallet is synced
                    if (!Synced && Daemon.Synced && BlockCount >= Daemon.NetworkHeight - 2) // Fuzzy sync status
                    {
                        // Set ready status
                        Synced = true;

                        // Trigger ready event handler
                        LogLine("Synced");
                        OnSynced?.Invoke(this, EventArgs.Empty);
                    }
                    else
                    {
                        Synced = false;
                    }

                    // Update balance
                    await SendRequestAsync(RequestMethod.GET_BALANCE, new JObject { }, out Result);

                    AvailableBalance = (double)Result["availableBalance"] / 100;
                    LockedAmount     = (double)Result["lockedAmount"] / 100;

                    // Invoke update event
                    OnUpdate?.Invoke(this, EventArgs.Empty);

                    // Wait for specified amount of time
                    await Task.Delay(RefreshRate, CancellationSource.Token);
                }
                catch { }
            }
        }
        /// <summary>
        /// Main update loop
        /// </summary>
        private async void Update()
        {
            // Loop as long as the daemon is connected
            while (Connected)
            {
                try
                {
                    // Ensure network connection is still alive
                    if (!Local && !TurtleCoin.Ping(Address, Port))
                    {
                        // Connection was lost
                        await Exit();

                        ThrowError(ErrorCode.CONNECTION_LOST);
                        LogLine("Connection lost");
                        OnDisconnect?.Invoke(this, EventArgs.Empty);
                        break;
                    }
                    else if (Local && Process.HasExited)
                    {
                        // Connection was lost
                        await Exit();

                        ThrowError(ErrorCode.CONNECTION_LOST);
                        LogLine("Connection lost");
                        OnDisconnect?.Invoke(this, EventArgs.Empty);
                        break;
                    }

                    // Create a result object to recycle throughout updates
                    JObject Result = new JObject();

                    // Update status
                    await SendRequestAsync(RequestMethod.GET_INFO, new JObject { }, out Result);

                    // Make sure daemon is correct version
                    if (Result["synced"] == null)
                    {
                        // Incorrect daemon version
                        await Exit();

                        ThrowError(ErrorCode.INCORRECT_DAEMON_VERSION);
                        LogLine("Daemon is wrong version, use a newer version");
                        OnDisconnect?.Invoke(this, EventArgs.Empty);
                        break;
                    }

                    // Populate network info
                    AltBlocksCount           = (double)Result["alt_blocks_count"];
                    Difficulty               = (double)Result["difficulty"];
                    GreyPeerlistSize         = (double)Result["grey_peerlist_size"];
                    Hashrate                 = (double)Result["hashrate"];
                    Height                   = (double)Result["height"];
                    IncomingConnectionsCount = (double)Result["incoming_connections_count"];
                    LastKnownBlockIndex      = (double)Result["last_known_block_index"];
                    NetworkHeight            = (double)Result["network_height"];
                    OutgoingConnectionsCount = (double)Result["outgoing_connections_count"];
                    Status                   = (string)Result["status"];
                    TransactionCount         = (double)Result["tx_count"];
                    TransactionPoolSize      = (double)Result["tx_pool_size"];
                    WhitePeerlistSize        = (double)Result["white_peerlist_size"];

                    // Check if daemon is ready
                    if (!Synced && (bool)Result["synced"] == true)
                    {
                        // Set ready status
                        Synced = true;

                        // Trigger ready event handler
                        LogLine("Synced");
                        OnSynced?.Invoke(this, EventArgs.Empty);
                    }
                    else
                    {
                        Synced = false;
                    }

                    // Do updating

                    // Invoke update event
                    OnUpdate?.Invoke(this, EventArgs.Empty);

                    // Wait for specified amount of time
                    await Task.Delay(RefreshRate, CancellationSource.Token);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Initializes a daemon connection
        /// </summary>
        /// <param name="Path">Path to daemon (local path or node address)</param>
        /// <param name="Port">Port daemon will connect through</param>
        public Task InitializeAsync(Daemon Daemon, string Path, string File, string Password, int Port = 8070)
        {
            // Set local variables
            this.Daemon   = Daemon;
            this.Path     = Path;
            this.File     = File;
            this.Password = Password;
            this.Port     = Port;

            LogLine("Initializing");

            // Ensure daemon is connected
            if (Daemon.Connected)
            {
                Connected = true;
            }
            else
            {
                LogLine("Daemon not connected");
                ThrowError(ErrorCode.DAEMON_NOT_CONNECTED);
                return(Task.CompletedTask);
            }

            // Check if given path is local or remote
            string ConvertedPath;

            try
            {
                // If path starts with http, it is external
                if (Path.StartsWith("http"))
                {
                    ConvertedPath = Path.Replace("http:", "").Replace("\\", "").Replace("/", "");
                    Local         = false;
                }
                else
                {
                    ConvertedPath = Path;
                    if (IPAddress.TryParse(Path, out IPAddress i))
                    {
                        Local = false;
                    }
                    else
                    {
                        Local = new Uri(Path).IsFile;
                    }
                }
            }
            catch
            {
                ThrowError(ErrorCode.INVALID_PATH);
                return(Task.CompletedTask);
            }

            // If path is local
            if (Local)
            {
                // Set address
                Address = "localhost";
                LogLine("Set address to {0}", Address);

                // Check if port is already in use
                if (TurtleCoin.Ping(Address, Port))
                {
                    ThrowError(ErrorCode.PORT_IN_USE);
                    return(Task.CompletedTask);
                }

                // Launch wallet locally
                LogLine("Creating process");
                if (!System.IO.File.Exists(ConvertedPath))
                {
                    ThrowError(ErrorCode.INVALID_FILE);
                    return(Task.CompletedTask);
                }

                // Create wallet process
                Process = new Process();
                Process.StartInfo.FileName               = ConvertedPath;
                Process.StartInfo.UseShellExecute        = false;
                Process.StartInfo.RedirectStandardInput  = true;
                Process.StartInfo.RedirectStandardOutput = true;
                Process.StartInfo.RedirectStandardError  = true;

                // Assign event handlers
                Process.OutputDataReceived += WalletOutputDataReceived;
                Process.ErrorDataReceived  += WalletErrorDataReceived;
                Process.Exited             += WalletExited;

                // Create process arguments
                Process.StartInfo.Arguments = string.Format("--daemon-address {0} --daemon-port {1} -w \"{2}\" -p \"{3}\" --bind-port {4} --rpc-password \"{5}\"",
                                                            Daemon.Address, Daemon.Port, TurtleCoin.EncodeString(File), TurtleCoin.EncodeString(Password), Port, TurtleCoin.EncodeString(Hash));

                // Start process
                if (Process.Start())
                {
                    // Begin redirecting output
                    Process.BeginOutputReadLine();
                    Process.BeginErrorReadLine();

                    // Trigger wallet connected event
                    Connected = true;
                    OnConnect?.Invoke(this, EventArgs.Empty);
                }

                // Process failed to start
                else
                {
                    ThrowError(ErrorCode.PROCESS_NOT_CREATED);
                }
            }

            // Completed
            return(Task.CompletedTask);
        }
        /// <summary>
        /// Initializes a daemon connection
        /// </summary>
        /// <param name="Path">Path to daemon (local path or node address)</param>
        /// <param name="Port">Port daemon will connect through</param>
        public Task InitializeAsync(string Path, int Port = 11898)
        {
            // Set local variables
            this.Path = Path;
            this.Port = Port;

            LogLine("Initializing");

            // Check if given path is local or remote
            string ConvertedPath;

            try
            {
                // If path starts with http, it is external
                if (Path.StartsWith("http"))
                {
                    ConvertedPath = Path.Replace("http:", "").Replace("\\", "").Replace("/", "");
                    Local         = false;
                }
                else
                {
                    ConvertedPath = Path;
                    if (IPAddress.TryParse(Path, out IPAddress i))
                    {
                        Local = false;
                    }
                    else
                    {
                        Local = new Uri(Path).IsFile;
                    }
                }
            }
            catch
            {
                ThrowError(ErrorCode.INVALID_PATH);
                return(Task.CompletedTask);
            }

            // If path is local
            if (Local)
            {
                // Set address
                Address = "localhost";
                LogLine("Set address to {0}", Address);

                // Check if port is already in use
                if (TurtleCoin.Ping(Address, Port))
                {
                    ThrowError(ErrorCode.PORT_IN_USE);
                    return(Task.CompletedTask);
                }

                // Launch daemon locally
                LogLine("Creating process");
                if (!File.Exists(ConvertedPath))
                {
                    ThrowError(ErrorCode.INVALID_FILE);
                    return(Task.CompletedTask);
                }

                // Create daemon process
                Process = new Process();
                Process.StartInfo.FileName               = ConvertedPath;
                Process.StartInfo.UseShellExecute        = false;
                Process.StartInfo.RedirectStandardInput  = true;
                Process.StartInfo.RedirectStandardOutput = true;
                Process.StartInfo.RedirectStandardError  = true;

                // Assign event handlers
                Process.OutputDataReceived += DaemonOutputDataReceived;
                Process.ErrorDataReceived  += DaemonErrorDataReceived;
                Process.Exited             += DaemonExited;

                // Start process
                if (Process.Start())
                {
                    // Begin redirecting output
                    Process.BeginOutputReadLine();
                    Process.BeginErrorReadLine();

                    // Wait for a connection
                    LogLine("Waiting for height data");
                    while (!Connected)
                    {
                        SendRequestAsync(RequestMethod.GET_INFO, new JObject(), out JObject Result);
                        if (Result["height"] != null)
                        {
                            Connected = true;
                        }
                    }

                    // Trigger daemon connected event
                    OnConnect?.Invoke(this, EventArgs.Empty);
                }

                // Process failed to start
                else
                {
                    ThrowError(ErrorCode.PROCESS_NOT_CREATED);
                }
            }

            // If path is remote node
            else
            {
                // Set address
                Address = ConvertedPath;
                LogLine("Set address to {0}", Address);

                // Check if a connection can be made
                if (!TurtleCoin.Ping(Address, Port))
                {
                    ThrowError(ErrorCode.BAD_CONNECTION);
                    return(Task.CompletedTask);
                }

                // Trigger daemon connection event
                Connected = true;
                LogLine("Connected");
                OnConnect?.Invoke(this, EventArgs.Empty);
            }

            // Completed
            return(Task.CompletedTask);
        }