/// <summary>
        /// The expected sequence of arguments:
        /// <list>
        /// <item>
        /// 1, [network-name] [options] [rpc-command] [rpc-params].
        /// </item>
        /// <item>
        /// 2, [network-name] [options] [api-controller "/" api-command] [api-params].
        /// </item>
        /// </list>
        /// </summary>
        public static void Main(string[] args)
        {
            try
            {
                // Preprocess the command line arguments
                var argList = new List <string>(args);

                string networkName = null;
                if (argList.Any())
                {
                    networkName = argList.First();
                    argList.RemoveAt(0);
                }

                var optionList = new List <string>();
                while ((argList.Any()) && (argList[0].StartsWith('-')))
                {
                    optionList.Add(argList[0]);
                    argList.RemoveAt(0);
                }

                string method = "";
                if (argList.Any())
                {
                    method = argList.First().ToUpper();
                    if (method == "GET" || method == "POST" || method == "DELETE")
                    {
                        argList.RemoveAt(0);
                    }
                    else
                    {
                        method = "";
                    }
                }

                string command = string.Empty;
                if (argList.Any())
                {
                    command = argList.First();
                    argList.RemoveAt(0);
                }

                var commandArgList = new List <string>(argList);

                // Display help if required.
                if (optionList.Contains("-help") || optionList.Contains("--help") || string.IsNullOrWhiteSpace(command))
                {
                    var builder = new StringBuilder();
                    builder.AppendLine("Usage:");
                    builder.AppendLine(" dotnet run <Stratis.Bitcoin.Cli/Stratis.Bitcoin.Cli.dll> [network-name] [options] [method] <command> [arguments]");
                    builder.AppendLine();
                    builder.AppendLine("Command line arguments:");
                    builder.AppendLine();
                    builder.AppendLine("[network-name]                     Name of the network - e.g. \"stratis\" or \"solaris\" or \"bitcoin\".");
                    builder.AppendLine("[options]                          Options for the CLI (optional) - e.g. -help, -rpcuser, see below.");
                    builder.AppendLine("[method]                           Method to use for API calls - 'GET', 'POST' or 'DELETE'.");
                    builder.AppendLine("[command]                          Name of RPC method or API <controller>/<method>.");
                    builder.AppendLine("[arguments]                        Argument by position (RPC) or Name = Value pairs (API) (optional).");
                    builder.AppendLine();
                    builder.AppendLine("Options:");
                    builder.AppendLine("-help                              This help message");
                    builder.AppendLine("-rpcconnect=<ip>                   Send commands to node running on <ip> (default: 127.0.0.1)");
                    builder.AppendLine("-rpcport=<port>                    Connect to JSON-RPC on <port> (default for Stratis: 26174 or default for Solaris: 61000 or default for Bitcoin: 8332)");
                    builder.AppendLine("-rpcuser=<user>                    Username for JSON-RPC connections");
                    builder.AppendLine("-rpcpassword=<pw>                  Password for JSON-RPC connections");
                    builder.AppendLine();
                    builder.AppendLine("Examples:");
                    builder.AppendLine();
                    builder.AppendLine("dotnet run stratis -testnet GET Wallet/history WalletName=testwallet - Lists all the historical transactions of the wallet called 'testwallet' on the stratis test network.");
                    builder.AppendLine("dotnet run stratis -rpcuser=stratistestuser -rpcpassword=stratistestpassword -rpcconnect=127.0.0.3 -rpcport=26174 getinfo - Displays general information about the Stratis node on the 127.0.0.3:26174, authenticating with the RPC specified user.");
                    builder.AppendLine("dotnet run bitcoin -rpcuser=btctestuser -rpcpassword=btctestpass getbalance - Displays the current balance of the opened wallet on the 127.0.0.1:8332 node, authenticating with the RPC specified user.");
                    Console.WriteLine(builder);
                    return;
                }

                // Determine API port.
                NetworksSelector networksSelector = null;

                if (networkName.Contains("stratis"))
                {
                    networksSelector = Networks.Networks.Stratis;
                }
                else if (networkName.Contains("solaris"))
                {
                    networksSelector = Networks.Networks.Solaris;
                }
                else
                {
                    networksSelector = Networks.Networks.Bitcoin;
                }

                // API calls require both the contoller name and the method name separated by "/".
                // If this is not an API call then assume it is an RPC call.
                if (!command.Contains("/"))
                {
                    // Process RPC call.
                    try
                    {
                        string[] options      = optionList.Append("-server").ToArray();
                        var      nodeSettings = new NodeSettings(networksSelector: networksSelector, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: options)
                        {
                            MinProtocolVersion = ProtocolVersion.ALT_PROTOCOL_VERSION
                        };

                        var     rpcSettings = new RpcSettings(nodeSettings);
                        Network network     = nodeSettings.Network;

                        // Find the binding to 127.0.0.1 or the first available. The logic in RPC settings ensures there will be at least 1.
                        System.Net.IPEndPoint nodeEndPoint = rpcSettings.Bind.FirstOrDefault(b => b.Address.ToString() == "127.0.0.1") ?? rpcSettings.Bind[0];
                        var rpcUri = new Uri($"http://{nodeEndPoint}");

                        // Process the command line RPC arguments
                        // TODO: this should probably be moved to the NodeSettings.FromArguments
                        if (options.GetValueOf("-rpcbind") != null)
                        {
                            rpcUri = new Uri($"http://{options.GetValueOf("-rpcbind")}");
                        }

                        if (options.GetValueOf("-rpcconnect") != null || options.GetValueOf("-rpcport") != null)
                        {
                            string rpcAddress = options.GetValueOf("-rpcconnect") ?? "127.0.0.1";

                            int rpcPort = rpcSettings.RPCPort;
                            int.TryParse(options.GetValueOf("-rpcport"), out rpcPort);

                            rpcUri = new Uri($"http://{rpcAddress}:{rpcPort}");
                        }
                        rpcSettings.RpcUser     = options.GetValueOf("-rpcuser") ?? rpcSettings.RpcUser;
                        rpcSettings.RpcPassword = options.GetValueOf("-rpcpassword") ?? rpcSettings.RpcPassword;

                        Console.WriteLine($"Connecting to the following RPC node: http://{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}@{rpcUri.Authority}.");

                        // Initialize the RPC client with the configured or passed userid, password and endpoint.
                        var rpcClient = new RPCClient($"{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}", rpcUri, network);

                        // Execute the RPC command
                        Console.WriteLine($"Sending RPC command '{command} {string.Join(" ", commandArgList)}' to '{rpcUri}'.");
                        RPCResponse response = rpcClient.SendCommand(command, commandArgList.ToArray());

                        // Return the result as a string to the console.
                        Console.WriteLine(response.ResultString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }
                }
                else
                {
                    // Process API call.
                    string[] options      = optionList.ToArray();
                    var      nodeSettings = new NodeSettings(networksSelector: networksSelector, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: options)
                    {
                        MinProtocolVersion = ProtocolVersion.ALT_PROTOCOL_VERSION
                    };

                    var apiSettings = new ApiSettings(nodeSettings);

                    string url = $"http://localhost:{apiSettings.ApiPort}/api".AppendPathSegment(command);

                    object commandArgObj = GetAnonymousObjectFromDictionary(commandArgList
                                                                            .Select(a => a.Split('='))
                                                                            .ToDictionary(a => a[0], a => a[1]));

                    HttpResponseMessage httpResponse;

                    switch (method)
                    {
                    case "POST":
                        httpResponse = CallApiPost(url, commandArgObj);
                        break;

                    case "DELETE":
                        httpResponse = CallApiDelete(url, commandArgObj);
                        break;

                    default:
                        httpResponse = CallApiGet(url, commandArgObj);
                        break;
                    }

                    var response = httpResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                    // Format and return the result as a string to the console.
                    Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(response), Formatting.Indented));
                }
            }
            catch (Exception err)
            {
                // Report any errors to the console.
                Console.WriteLine(ExceptionToString(err));
            }
        }
Exemplo n.º 2
0
    private void DrawConsoleUI(float fYOffset)
    {
        if (m_bNeedResetFocus)
        {
            GUI.FocusControl(null);
            m_bNeedResetFocus = false;
        }

        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        GUILayout.Space(20f);
        Color kOrgColor = GUI.color;

        GUI.color = Color.cyan;
        GUILayout.Label("Please see unity console for output detail.", GUILayout.Width(300));
        GUI.color = kOrgColor;
        GUILayout.EndHorizontal();

        GUILayout.Space(5);

        GUILayout.BeginHorizontal();
        GUILayout.Space(20f);
        GUILayout.Label("RPC Command:", GUILayout.Width(100));
        GUILayout.EndHorizontal();

        //GUILayout.Space(5);

        GUILayoutOption[] arrLO = new GUILayoutOption[2];
        arrLO[0] = GUILayout.Width(170);
        arrLO[1] = GUILayout.Height(20);

        GUILayout.BeginHorizontal();
        GUILayout.Space(20.0f);
        Color kOldC = GUI.color;

        GUI.color = new Color(255 / 255.0f, 160 / 255.0f, 50 / 255.0f);
        GUILayout.Label("Command Type:", GUILayout.Width(120.0f));
        int iSelCmdTypeIndex = EditorGUILayout.Popup(m_iLastSelCmdTypeIndex, m_arrCmdType, arrLO);

        if (iSelCmdTypeIndex != m_iLastSelCmdTypeIndex)
        {
            m_iLastSelCmdIndex     = 0;
            m_iLastSelCmdTypeIndex = iSelCmdTypeIndex;
        }
        GUI.color = kOldC;
        GUILayout.EndHorizontal();

        string[] arrCmd     = m_listCommand[m_iLastSelCmdTypeIndex];
        string[] arrArgInfo = m_listArgsInfo[m_iLastSelCmdTypeIndex];

        GUILayout.BeginHorizontal();
        GUILayout.Space(20.0f);
        kOldC     = GUI.color;
        GUI.color = Color.yellow;
        GUILayout.Label("Command Select:", GUILayout.Width(120.0f));
        int iSelCmdIndex = EditorGUILayout.Popup(m_iLastSelCmdIndex, arrCmd, arrLO);

        GUI.color = kOldC;
        if (iSelCmdIndex != m_iLastSelCmdIndex)
        {
            if (arrCmd[iSelCmdIndex] != COMMAND_SPLITE)
            {
                m_strRawCurArgInfo = arrArgInfo[iSelCmdIndex];
                //m_strCurArgsInfo = arrArgInfo[iSelCmdIndex];
                ResolveArgType();
                if (string.IsNullOrEmpty(m_strCurArgsInfo))
                {
                    m_strRawExeRpcCommand = arrCmd[iSelCmdIndex];
                }
                else
                {
                    m_strRawExeRpcCommand = arrCmd[iSelCmdIndex] + " ";
                }

                GUI.FocusControl("RPCCmdInput");
            }
            else
            {
                m_strRawExeRpcCommand = "";
                m_strCurArgsInfo      = "";
                GUI.FocusControl(null);
            }
            m_iLastSelCmdIndex = iSelCmdIndex;
        }
        GUILayout.Space(5);
        kOldC     = GUI.color;
        GUI.color = new Color(0.69f, 0.77f, 0.95f);
        GUILayout.Label(m_strCurArgsInfo, GUILayout.Width(400.0f));
        GUI.color = kOldC;
        GUILayout.EndHorizontal();

        GUILayout.Space(5);

        GUILayout.BeginHorizontal();
        GUILayout.Space(20f);
        //arrLO = new GUILayoutOption[2];
        float fTAWidth = ms_kSig.position.width - 40.0f;

        arrLO[0] = GUILayout.Width(fTAWidth);
        //arrLO[0] = GUILayout.Width(560);
        arrLO[1] = GUILayout.Height(100);
        GUI.SetNextControlName("RPCCmdInput");
        m_strRawExeRpcCommand = EditorGUILayout.TextArea(m_strRawExeRpcCommand, arrLO);
        //m_strRpcCommand = GUILayout.TextArea(m_strRpcCommand, arrLO);
        GUILayout.EndHorizontal();

        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        float fBtnWidth   = 100.0f;
        float fBtnHeight  = 25.0f;
        float fBtnXOffset = 210.0f;
        float fXSpace     = fBtnXOffset;

        GUILayout.Space(fXSpace);
        arrLO[0] = GUILayout.Width(fBtnWidth);
        arrLO[1] = GUILayout.Height(fBtnHeight);
        if (GUILayout.Button("Execute", arrLO))
        {
            if (m_bCBInited == false)
            {
                if (EditorUtility.DisplayDialog("Erorr", "MagnaChain has not initialized", "OK"))
                {
                    return;
                }
            }

            if (string.IsNullOrEmpty(m_strRawExeRpcCommand))
            {
                if (EditorUtility.DisplayDialog("Prompt", "The rpc command is empty.", "OK"))
                {
                    return;
                }
            }

            try
            {
                ResolveExeCommand();

                RPCResponse kRsp = m_kCB.SendCommand(m_strExeRpcCommand, m_arrRpcArgs);
                if (kRsp == null)
                {
                    LogError("Execute command error!");
                }
                else
                {
                    if (kRsp.Error == null)
                    {
                        LogSys(kRsp.ResultString);
                    }
                    else
                    {
                        LogError("Error: " + kRsp.Error.Code + " msg: " + kRsp.Error.Message);
                    }
                }
            }
            catch (Exception e)
            {
                LogError(e.Message);
            }
        }

        float fXSpace2 = (ms_kSig.position.width * 0.5f - fBtnWidth - fBtnXOffset) * 2.0f;

        //fXSpace = fXSpace2 - fXSpace;
        GUILayout.Space(fXSpace2);
        if (GUILayout.Button("Clear", arrLO))
        {
            m_strRawExeRpcCommand = "";

            GUI.FocusControl(null);
        }
        GUILayout.EndHorizontal();

        GUILayout.Space(20);

        GUILayout.BeginHorizontal();
        GUILayout.Space(20.0f);
        GUILayout.Label("Template Contract:", GUILayout.Width(120.0f));
        ms_iSelTemplateLuaFineIndex = EditorGUILayout.Popup(ms_iSelTemplateLuaFineIndex, ms_arrTemplateLuaFile, GUILayout.Width(200));
        if (ms_arrTemplateLuaFile.Length > 0 && ms_iSelTemplateLuaFineIndex > 0)
        {
            ms_strSelTemplateLuaFile = ms_arrTemplateLuaFile[ms_iSelTemplateLuaFineIndex];

            string strFullPath = ms_strTemplateLuaPrefix + ms_strSelTemplateLuaFile;
            if (strFullPath != m_strLuaFile)
            {
                m_strLuaFile = strFullPath;
            }
        }
        GUILayout.EndHorizontal();

        GUILayout.Space(6);

        //m_strLuaFile = DrawFileChooser("CFLabe", "CFInput", "CFBtn", 20.0f, true, "Contract File:", 90.0f, m_strLuaFile, 220.0f, "", false, false, "lua", 70, 100);
        GUILayout.BeginHorizontal();
        GUILayout.Space(20.0f);
        GUI.SetNextControlName("CFLabe");
        GUILayout.Label("Contract File:", GUILayout.Width(90.0f));    // 120
        //strFilePath = EditorGUILayout.TextField(strFilePath, GUILayout.Width(fTextFiledWidth));   // 330
        float fTFWidth;

        fTFWidth = ms_kSig.position.width - 20.0f - 90.0f - 10.0f - 70.0f - 20.0f - 10.0f - 90.0f;

        //arrLO = new GUILayoutOption[2];
        arrLO[0] = GUILayout.Height(18.0f);
        arrLO[1] = GUILayout.Width(fTFWidth);
        GUI.SetNextControlName("CFInput");

        //strFilePath = GUILayout.TextField(strFilePath, 512, GUILayout.Width(fTextFiledWidth));
        m_strLuaFile = EditorGUILayout.TextField(m_strLuaFile, arrLO);

        GUILayout.Space(10);
        arrLO[1] = GUILayout.Width(70.0f);
        GUI.SetNextControlName("CFBtn");
        if (GUILayout.Button("Browser", arrLO))
        {
            ms_iSelTemplateLuaFineIndex = 0;
            m_strLuaFile = EditorUtility.OpenFilePanel("Choose " + "Contract File:", "", "lua");
        }

        arrLO[0] = GUILayout.Width(70.0f);
        fXSpace  = 5.0f;
        GUILayout.Space(fXSpace);
        if (GUILayout.Button("Edit", arrLO))
        {
            if (!string.IsNullOrEmpty(m_strLuaFile))
            {
                Process process = new Process();
                process.StartInfo.FileName               = "notepad.exe";
                process.StartInfo.Arguments              = m_strLuaFile;
                process.StartInfo.UseShellExecute        = false;
                process.StartInfo.RedirectStandardInput  = false;
                process.StartInfo.RedirectStandardOutput = false;
                process.StartInfo.RedirectStandardError  = false;
                process.StartInfo.CreateNoWindow         = true;
                process.Start();

                m_bEditLuaFile = true;
            }
        }
        GUILayout.EndHorizontal();

        GUILayout.Space(10);

        m_strCostCLAddress = DrawFileChooser("CCALabel", "CCAInput", "CCABtn", 20.0f, false, "Cost MCL Address:", 130.0f, m_strCostCLAddress, 320.0f, "", false, true);

        GUILayout.Space(5);

        m_strCostAmount = DrawFileChooser("CAXLabel", "CAXInput", "CAXBtn", 20.0f, false, "Cost Amount:", 130.0f, m_strCostAmount, 320.0f, "", false, true);

        GUILayout.Space(5);

        m_strSenderCLAddress = DrawFileChooser("CRALabel", "CRAInput", "CRABtn", 20.0f, false, "Sender MCL Address:", 130.0f, m_strSenderCLAddress, 320.0f, "", false, true);

        GUILayout.Space(10);

        GUILayout.BeginHorizontal();
        fBtnWidth = 160.0f;
        arrLO[0]  = GUILayout.Width(fBtnWidth);
        arrLO[1]  = GUILayout.Height(25.0f);
        fXSpace   = (ms_kSig.position.width - fBtnWidth) * 0.5f;
        GUILayout.Space(fXSpace);
        if (GUILayout.Button("Publish Contract", arrLO))
        {
            if (m_bCBInited == false)
            {
                if (EditorUtility.DisplayDialog("Erorr", "MagnaChain has not initialized", "OK"))
                {
                    return;
                }
            }

            if (string.IsNullOrEmpty(m_strLuaFile))
            {
                if (EditorUtility.DisplayDialog("Prompt", "Please select contract file first.", "OK"))
                {
                    return;
                }
            }

            if (m_bEditLuaFile)
            {
                if (EditorUtility.DisplayDialog("Prompt", "You may have modified contract file, please make sure the contract file have saved.", "Continue", "Cancel") == false)
                {
                    return;
                }
                m_bEditLuaFile = false;
            }

            string strTxt = null;

            try
            {
                strTxt = File.ReadAllText(m_strLuaFile);
            }
            catch (Exception e)
            {
                LogError(e.Message);
                return;
            }

            if (string.IsNullOrEmpty(strTxt))
            {
                EditorUtility.DisplayDialog("Prompt", "The contract content is empty!", "OK");
                return;
            }

            float fCostAmount = 0.0f;

            try
            {
                fCostAmount = Convert.ToSingle(m_strCostAmount);
            }
            catch
            {
                fCostAmount = 0.0f;
            }
            bool bRet = m_kCB.PublishContract(out ms_strContractAddress, strTxt, m_strCostCLAddress, fCostAmount, m_strSenderCLAddress);
            if (bRet == false)
            {
                LogError("Publish contract failed: " + m_strLuaFile);
                return;
            }

            LogSys("Publish contract successfully, contract address: " + ms_strContractAddress);

            string strPrefix = Application.dataPath;
            string strKey    = strPrefix + "#ms_strContractAddress";
            PlayerPrefs.SetString(strKey, ms_strContractAddress);
            PlayerPrefs.Save();
        }
        GUILayout.EndHorizontal();

        GUILayout.Space(15);

        ms_strContractAddress = DrawFileChooser("CADLabel", "CADInput", "CADBtn", 20.0f, false, "Contract Address:", 120.0f, ms_strContractAddress, 330.0f, "", false, true);

        GUILayout.Space(5);

        m_strCallFunction = DrawFileChooser("CFLabel", "CFInput", "CFBtn", 20.0f, false, "Call Function:", 120.0f, m_strCallFunction, 330.0f, "", false, true);

        GUILayout.Space(5);

        m_strCallArgs = DrawFileChooser("CALabel", "CAInput", "CABtn", 20.0f, false, "Call Arguments:", 120.0f, m_strCallArgs, 330.0f, "", false, true);

        GUILayout.Space(15);

        GUILayout.BeginHorizontal();

        float fTogWidth = 120.0f;

        arrLO[0] = GUILayout.Width(fTogWidth);
        float fTogX = 40.0f;

        GUILayout.Space(fTogX);
        m_bContractSendCall = GUILayout.Toggle(m_bContractSendCall, "Send Call", arrLO);

        fBtnWidth = 180.0f;
        arrLO[0]  = GUILayout.Width(fBtnWidth);
        fXSpace   = ms_kSig.position.width * 0.5f - fTogWidth - fTogX - fBtnWidth * 0.5f;
        GUILayout.Space(fXSpace);
        if (GUILayout.Button("Call Contract Function", arrLO))
        {
            if (m_bCBInited == false)
            {
                if (EditorUtility.DisplayDialog("Erorr", "MagnaChain has not initialized", "OK"))
                {
                    return;
                }
            }

            if (string.IsNullOrEmpty(ms_strContractAddress))
            {
                if (EditorUtility.DisplayDialog("Prompt", "Please input contract address first.", "OK"))
                {
                    return;
                }
            }

            if (string.IsNullOrEmpty(m_strCallFunction))
            {
                if (EditorUtility.DisplayDialog("Prompt", "Please input call function name first.", "OK"))
                {
                    return;
                }
            }

            float fCostAmount = 0.0f;
            try
            {
                fCostAmount = Convert.ToSingle(m_strCostAmount);
            }
            catch
            {
                fCostAmount = 0.0f;
            }

            object[] arrArg = null;
            if (!string.IsNullOrEmpty(m_strCallArgs))
            {
                //char[] arrSpt = new char[1];
                //arrSpt[0] = ' ';
                arrArg = System.Text.RegularExpressions.Regex.Split(m_strCallArgs, @"\s+");//m_strCallArgs.Split(arrSpt);
            }

            string strRet = m_kCB.CallContractFunction(m_bContractSendCall, ms_strContractAddress, m_strCostCLAddress, fCostAmount, m_strSenderCLAddress, m_strCallFunction, arrArg);
            if (string.IsNullOrEmpty(strRet))
            {
                LogError("CallContractFunction failed!");
                return;
            }
            LogSys("CallContractFunction succeed: " + strRet);
        }

        //fXSpace = ms_kSig.position.width - fBtnOffset * 2.0f - fBtnWidth * 2.0f;
        //GUILayout.Space(fXSpace);
        //if (GUILayout.Button("SendCall Contract", arrLO))
        //{
        //    if (m_bCBInited == false)
        //    {
        //        if (EditorUtility.DisplayDialog("Erorr", "MagnaChain has not initialized", "OK"))
        //        {
        //            return;
        //        }
        //    }

        //    if (string.IsNullOrEmpty(m_strContractAddress))
        //    {
        //        if (EditorUtility.DisplayDialog("Prompt", "Please publish contract first.", "OK"))
        //        {
        //            return;
        //        }
        //    }

        //    if (string.IsNullOrEmpty(m_strCallFunction))
        //    {
        //        if (EditorUtility.DisplayDialog("Prompt", "Please input call function name first.", "OK"))
        //        {
        //            return;
        //        }
        //    }

        //    string strRet = m_kCB.SendCallContract(m_strContractAddress, m_strCallFunction, m_strSenderAddress, m_strCallArgs);
        //    if (string.IsNullOrEmpty(strRet))
        //    {
        //        LogError("SendCallContract failed: " + m_strContractAddress);
        //        return;
        //    }
        //    LogSys("SendCallContract succeed: " + strRet);
        //}
        GUILayout.EndHorizontal();
    }
Exemplo n.º 3
0
        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, RoundConfig);

            // 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);
                }
            }
        }
Exemplo n.º 4
0
        public async Task GetTransactionOnUnconfirmedTransactionAsync()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                // Arrange.
                // Create a sending and a receiving node.
                CoreNode sendingNode   = builder.CreateStratisPosNode(this.network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest150Miner).Start();
                CoreNode receivingNode = builder.CreateStratisPosNode(this.network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest150Listener).Start();

                TestHelper.ConnectAndSync(sendingNode, receivingNode);

                // Get an address to send to.
                IEnumerable <string> unusedaddresses = await $"http://localhost:{receivingNode.ApiPort}/api"
                                                       .AppendPathSegment("wallet/unusedAddresses")
                                                       .SetQueryParams(new { walletName = "mywallet", accountName = "account 0", count = 1 })
                                                       .GetJsonAsync <IEnumerable <string> >();

                // Build and send the transaction with an Op_Return.
                WalletBuildTransactionModel buildTransactionModel = await $"http://localhost:{sendingNode.ApiPort}/api"
                                                                    .AppendPathSegment("wallet/build-transaction")
                                                                    .PostJsonAsync(new BuildTransactionRequest
                {
                    WalletName       = "mywallet",
                    AccountName      = "account 0",
                    FeeType          = "low",
                    Password         = "******",
                    ShuffleOutputs   = false,
                    AllowUnconfirmed = true,
                    Recipients       = unusedaddresses.Select(address => new RecipientModel
                    {
                        DestinationAddress = address,
                        Amount             = "1"
                    }).ToList(),
                })
                                                                    .ReceiveJson <WalletBuildTransactionModel>();

                await $"http://localhost:{sendingNode.ApiPort}/api"
                .AppendPathSegment("wallet/send-transaction")
                .PostJsonAsync(new SendTransactionRequest
                {
                    Hex = buildTransactionModel.Hex
                })
                .ReceiveJson <WalletSendTransactionModel>();

                uint256 txId = buildTransactionModel.TransactionId;

                TestBase.WaitLoop(() =>
                {
                    WalletHistoryModel history = $"http://localhost:{receivingNode.ApiPort}/api"
                                                 .AppendPathSegment("wallet/history")
                                                 .SetQueryParams(new { walletName = "mywallet", AccountName = "account 0" })
                                                 .GetAsync()
                                                 .ReceiveJson <WalletHistoryModel>().GetAwaiter().GetResult();

                    return(history.AccountsHistoryModel.First().TransactionsHistory.Any(h => h.Id == txId));
                });

                TestBase.WaitLoop(() =>
                {
                    WalletHistoryModel history = $"http://localhost:{sendingNode.ApiPort}/api"
                                                 .AppendPathSegment("wallet/history")
                                                 .SetQueryParams(new { walletName = "mywallet", AccountName = "account 0" })
                                                 .GetAsync()
                                                 .ReceiveJson <WalletHistoryModel>().GetAwaiter().GetResult();

                    return(history.AccountsHistoryModel.First().TransactionsHistory.Any(h => h.Id == txId));
                });

                Transaction trx = this.network.Consensus.ConsensusFactory.CreateTransaction(buildTransactionModel.Hex);

                RPCClient   rpcReceivingNode  = receivingNode.CreateRPCClient();
                RPCResponse txReceivingWallet = rpcReceivingNode.SendCommand(RPCOperations.gettransaction, txId.ToString());

                RPCClient   rpcSendingNode  = sendingNode.CreateRPCClient();
                RPCResponse txSendingWallet = rpcSendingNode.SendCommand(RPCOperations.gettransaction, txId.ToString());

                // Assert.
                GetTransactionModel resultSendingWallet = txSendingWallet.Result.ToObject <GetTransactionModel>();
                resultSendingWallet.Amount.Should().Be((decimal) - 97999999.9999);
                resultSendingWallet.Fee.Should().Be((decimal) - 0.0001);
                resultSendingWallet.Confirmations.Should().Be(0);
                resultSendingWallet.TransactionId.Should().Be(txId);
                resultSendingWallet.BlockHash.Should().BeNull();
                resultSendingWallet.BlockIndex.Should().BeNull();
                resultSendingWallet.BlockTime.Should().BeNull();
                resultSendingWallet.TimeReceived.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultSendingWallet.Details.Count.Should().Be(2);

                GetTransactionDetailsModel detailsSendingWallet = resultSendingWallet.Details.Last();
                detailsSendingWallet.Address.Should().Be(unusedaddresses.Single());
                detailsSendingWallet.Amount.Should().Be((decimal) - 1.00000000);
                detailsSendingWallet.Fee.Should().Be((decimal) - 0.0001);
                detailsSendingWallet.Category.Should().Be(GetTransactionDetailsCategoryModel.Send);
                detailsSendingWallet.OutputIndex.Should().Be(1); // The output at index 0 is the change.

                GetTransactionModel resultReceivingWallet = txReceivingWallet.Result.ToObject <GetTransactionModel>();
                resultReceivingWallet.Amount.Should().Be((decimal)1.00000000);
                resultReceivingWallet.Fee.Should().BeNull();
                resultReceivingWallet.Confirmations.Should().Be(0);
                resultReceivingWallet.TransactionId.Should().Be(txId);
                resultReceivingWallet.BlockHash.Should().BeNull();
                resultReceivingWallet.BlockIndex.Should().BeNull();
                resultReceivingWallet.BlockTime.Should().BeNull();
                resultReceivingWallet.TimeReceived.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultReceivingWallet.TransactionTime.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultReceivingWallet.Details.Should().ContainSingle();

                GetTransactionDetailsModel detailsReceivingWallet = resultReceivingWallet.Details.Single();
                detailsReceivingWallet.Address.Should().Be(unusedaddresses.Single());
                detailsReceivingWallet.Amount.Should().Be((decimal)1.00000000);
                detailsReceivingWallet.Fee.Should().BeNull();
                detailsReceivingWallet.Category.Should().Be(GetTransactionDetailsCategoryModel.Receive);
                detailsReceivingWallet.OutputIndex.Should().Be(1);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Upload a file to your Brightcove account
        /// </summary>
        /// <param name="video">
        /// The metadata for the video you'd like to create. This takes the form of a
        /// JSON object of name/value pairs, each of which corresponds to a settable
        /// property of the Video object.
        /// </param>
        /// <param name="filename">
        /// The name of the file that's being uploaded. You don't need to specify this in
        /// the JSON if it is specified in the file part of the POST.
        /// </param>
        /// <param name="file">
        /// A byte array of the video file you're uploading. This takes the
        /// form of a file part, in a multipart/form-data HTTP request. This input stream and
        /// the filename and maxSide parameters are automatically inferred from that file part.
        /// </param>
        /// <param name="encode_to">
        /// If the file requires transcoding, use this parameter to specify the target encoding. Valid
        /// values are MP4 or FLV, representing the H264 and VP6 codecs respectively. Note that transcoding
        /// of FLV files to another codec is not currently supported. This parameter is optional and defaults to FLV.
        /// </param>
        /// <param name="create_multiple_renditions">
        /// If the file is a supported transcodeable type, this optional flag can be used to control the
        /// number of transcoded renditions. If true (default), multiple renditions at varying encoding
        /// rates and dimensions are created. Setting this to false will cause a single transcoded VP6
        /// rendition to be created at the standard encoding rate and dimensions.
        /// </param>
        /// <param name="H264NoProcessing">
        /// If the video file is H.264 encoded and if create_multiple_ renditions=true, then multiple
        /// VP6 renditions are created and in addition the H.264 source is retained as an additional rendition.
        /// </param>
        /// <param name="preserve_source_rendition">
        /// Use this option to prevent H.264 source files from being transcoded. This parameter cannot be
        /// used in combination with create_multiple_renditions. It is optional and defaults to false.
        /// </param>
        /// <param name="maxsize">
        /// The maximum size that the file will be. This is used as a limiter to know when
        /// something has gone wrong with the upload. The maxSize is same as the file you uploaded.
        /// You don't need to specify this in the JSON if it is specified in the file part of the POST.
        /// </param>
        /// <param name="file_checksum">
        /// An optional MD5 hash of the file. The checksum can be used to verify that the file checked
        /// into your Brightcove Media Library is the same as the file you uploaded.
        /// </param>
        /// <returns>
        /// The id of the video that's been created. if null or error returns -1
        /// </returns>
        private RPCResponse <long> CreateVideo(BCVideo video, string filename, byte[] file, BCEncodeType encode_to, bool create_multiple_renditions,
                                               bool H264NoProcessing, bool preserve_source_rendition, long maxsize, string file_checksum, string fileFullPath)
        {
            // Generate post objects
            Dictionary <string, object> postParams = new Dictionary <string, object>();

            //add video to the post params
            RPCRequest rpc = new RPCRequest();

            rpc.method     = "create_video";
            rpc.parameters = "\"video\": " + video.ToCreateJSON() + ", \"token\": \"" + Account.WriteToken.Value + "\"";
            if (maxsize > -1)
            {
                rpc.parameters += ", \"maxsize\": " + maxsize.ToString();
            }
            if (file_checksum != null)
            {
                rpc.parameters += ", \"file_checksum\": \"" + file_checksum + "\"";
            }
            if (!encode_to.Equals(BCEncodeType.UNDEFINED))
            {
                rpc.parameters += ", \"encode_to\": " + encode_to.ToString();
            }
            rpc.parameters += ", \"create_multiple_renditions\": " + create_multiple_renditions.ToString().ToLower();
            rpc.parameters += ", \"H264NoProcessing\": " + H264NoProcessing.ToString().ToLower();
            rpc.parameters += ", \"preserve_source_rendition\": " + preserve_source_rendition.ToString().ToLower();
            postParams.Add("json", rpc.ToJSON());

            //add the file to the post
            if (!string.IsNullOrEmpty(filename))
            {
                rpc.parameters += ", \"filename\": \"" + filename + "\"";
            }
            if (!string.IsNullOrEmpty(filename) && file != null)
            {
                postParams.Add("file", new FileParameter(file, filename));
            }
            else if (!string.IsNullOrEmpty(fileFullPath))
            {
                postParams.Add("file", new UploadFileParameter(fileFullPath));
            }

            //Get the JSon reader returned from the APIRequest
            RPCResponse rpcr = string.IsNullOrEmpty(fileFullPath) ?
                               BCAPIRequest.ExecuteWrite(postParams, this.Account) :
                               BCAPIRequest.ExecuteWriteNew(postParams, this.Account);

            RPCResponse <long> rpcr2 = new RPCResponse <long>();

            rpcr2.error = rpcr.error;
            rpcr2.id    = rpcr.id;
            if (!string.IsNullOrEmpty(rpcr.result))
            {
                rpcr2.result = long.Parse(rpcr.result);
            }
            else
            {
                rpcr2.result = -1;
            }

            return(rpcr2);
        }
Exemplo n.º 6
0
    IEnumerator FetchTile(Vector2 index)
    {
        Vector3 pos = indexToPosition(index);

        // Temporal Placeholder
        GameObject plane  = Instantiate(baseTile, pos, Quaternion.identity);
        GameObject loader = Instantiate(loading, pos, Quaternion.identity);

        loader.transform.position = new Vector3(pos.x, pos.y + 2, pos.z);

        // Basic Auth
        Dictionary <string, string> headers = new Dictionary <string, string>();

        headers["Authorization"] = "Basic " + System.Convert.ToBase64String(
            System.Text.Encoding.ASCII.GetBytes("bitcoinrpc:38Dpwnjsj1zn3QETJ6GKv8YkHomA"));

        // JSON Data
        string json = "{\"method\":\"gettile\",\"params\":[" + index [0] + "," + index [1] + "],\"id\":0}";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(json.ToCharArray());

        WWW www = new WWW("http://s1.decentraland.org:8301", data, headers);

        yield return(www);

        if (string.IsNullOrEmpty(www.error))
        {
            RPCResponse response = JsonUtility.FromJson <RPCResponse>(www.text);
            Destroy(loader);
            if (response.IsEmpty())
            {
                // TODO: do empty behavior
            }
            else if (response.IsUnmined())
            {
                names.Add(index, "Unclaimed Land");
            }
            else if (response.HasData())
            {
                // Download tile content
                string fileName = "" + index [0] + "." + index [1] + ".lnd";
                www = new WWW("http://s1.decentraland.org:9301/tile/" + fileName);
                yield return(www);

                if (string.IsNullOrEmpty(www.error))
                {
                    Debug.Log("Downloaded content for tile (" + index[0] + "," + index[1] + ")");
                    STile t = STile.FromBytes(www.bytes);
                    t.ToInstance(pos);
                    names.Add(index, t.GetName());
                }
                else
                {
                    Debug.Log("Can't fetch tile content! " + index + " " + www.error);
                }
            }
        }
        else
        {
            Debug.Log("Error on RPC call 'gettile': " + www.error);
        }
    }
Exemplo n.º 7
0
        protected void Page_Load(object sender, EventArgs e)
        {
            //available querystring values for context info (id, language, version, database)

            try {
                //get the current item and database
                currentDB   = Sitecore.Configuration.Factory.GetDatabase("master");
                currentItem = new VideoItem(currentDB.Items[HttpContext.Current.Request.QueryString["id"].ToString()]);
                Item acct = currentItem.videoItem.Parent.Parent;
                //if current parent isn't the account then it's the parent of the folder
                if (!acct.TemplateName.Equals("Account Folder"))
                {
                    acct = acct.Parent;
                }
                accountItem = new AccountItem(acct.ID, acct.InnerData, acct.Database);
                bc          = new BCAPI(accountItem.PublisherID);

                //set the form values for the video
                if (!IsPostBack)
                {
                    loadFormWithCurrentValues();
                }

                //show the video id
                ltlVideoID.Text = currentItem.VideoID.ToString();

                //show the video upload status
                RPCResponse <UploadStatusEnum> rpcr = bc.GetUploadStatus(currentItem.VideoID);
                ltlStatus.Text = rpcr.result.ToString();

                ltlCreation.Text  = currentItem.CreationDate.ToString("MMMM d, yyyy");
                ltlModified.Text  = currentItem.LastModifiedDate.ToString("MMMM d, yyyy");
                ltlPublished.Text = currentItem.PublishedDate.ToString("MMMM d, yyyy");
                try {
                    long   milliseconds = currentItem.Length;
                    string lengthText   = "";
                    long   hours        = (milliseconds / 60000000);
                    if (hours >= 1)
                    {
                        milliseconds -= hours * 60000000;
                        lengthText   += hours + " hours, ";
                    }
                    long mins = (milliseconds / 60000);
                    if (mins >= 1)
                    {
                        milliseconds -= mins * 60000;
                        lengthText   += mins + " minutes, ";
                    }
                    long secs = (milliseconds / 1000);
                    if (secs >= 1)
                    {
                        milliseconds -= secs * 1000;
                        lengthText   += secs + " seconds";
                    }
                    ltlLength.Text = lengthText;
                }
                catch (Exception ex) {
                }
                ltlPlays.Text         = currentItem.PlaysTotal.ToString();
                ltlPlaysTrailing.Text = currentItem.PlaysTrailingWeek.ToString();
            }
            catch (Exception ex) {
                ltlError.Text = ex.ToString();
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// The expected sequence of arguments:
        /// <list>
        /// <item>
        /// 1, [network-name] [options] [rpc-command] [rpc-params].
        /// </item>
        /// <item>
        /// 2, [network-name] [options] [api-controller "/" api-command] [api-params].
        /// </item>
        /// </list>
        /// </summary>
        public static void Main(string[] args)
        {
            try
            {
                // Preprocess the command line arguments
                var argList = new List <string>(args);

                string networkName = null;
                if (argList.Any())
                {
                    networkName = argList.First();
                    argList.RemoveAt(0);
                }

                var optionList = new List <string>();
                while ((argList.Any()) && (argList[0].StartsWith('-')))
                {
                    optionList.Add(argList[0]);
                    argList.RemoveAt(0);
                }

                string command = string.Empty;
                if (argList.Any())
                {
                    command = argList.First();
                    argList.RemoveAt(0);
                }

                var commandArgList = new List <string>(argList);

                // Display help if required.
                if (optionList.Contains("-help") || optionList.Contains("--help") || string.IsNullOrWhiteSpace(command))
                {
                    var builder = new StringBuilder();
                    builder.AppendLine("Usage:");
                    builder.AppendLine(" dotnet run <Stratis.Bitcoin.Cli/Stratis.Bitcoin.Cli.dll> [network-name] [options] <command> [arguments]");
                    builder.AppendLine();
                    builder.AppendLine("Command line arguments:");
                    builder.AppendLine();
                    builder.AppendLine("[network-name]                     Name of the network - e.g. \"stratis\", \"stratismain\", \"stratistest\", \"bitcoinmain\", \"bitcointest\".");
                    builder.AppendLine("[options]                          Options for the CLI (optional) - e.g. -help, -rpcuser, see below.");
                    builder.AppendLine("[command]                          Name of RPC method or API <controller>/<method>.");
                    builder.AppendLine("[arguments]                        Argument by position (RPC) or Name = Value pairs (API) (optional).");
                    builder.AppendLine();
                    builder.AppendLine("Options:");
                    builder.AppendLine("-help                              This help message");
                    builder.AppendLine("-rpcconnect=<ip>                   Send commands to node running on <ip> (default: 127.0.0.1)");
                    builder.AppendLine("-rpcport=<port>                    Connect to JSON-RPC on <port> (default for Stratis: 26174 or default for Bitcoin: 8332)");
                    builder.AppendLine("-rpcuser=<user>                    Username for JSON-RPC connections");
                    builder.AppendLine("-rpcpassword=<pw>                  Password for JSON-RPC connections");
                    builder.AppendLine();
                    builder.AppendLine("Examples:");
                    builder.AppendLine();
                    builder.AppendLine("dotnet run stratis Wallet/history WalletName=testwallet - Lists all the historical transactions of the wallet called 'testwallet'.");
                    builder.AppendLine("dotnet run stratis getinfo -rpcuser=stratistestuser -rpcpassword=stratistestpassword -rpcconnect=127.0.0.3 -rpcport=26174 - Displays general information about the Stratis node on the 127.0.0.3:26174, authenticating with the RPC specified user.");
                    builder.AppendLine("dotnet run bitcoin getbalance -rpcuser=btctestuser -rpcpassword=btctestpass - Displays the current balance of the opened wallet on the 127.0.0.1:8332 node, authenticating with the RPC specified user.");
                    Console.WriteLine(builder);
                    return;
                }

                // Determine API port.
                int     defaultRestApiPort = 0;
                Network network            = null;

                if (networkName.Contains("stratis"))
                {
                    defaultRestApiPort = 37221;
                    network            = Network.StratisMain;
                }
                else
                {
                    defaultRestApiPort = 37220;
                    network            = Network.Main;
                }



                // API calls require both the contoller name and the method name separated by "/".
                // If this is not an API call then assume it is an RPC call.
                if (!command.Contains("/"))
                {
                    // Process RPC call.
                    try
                    {
                        var options = optionList.Append("-server").ToArray();

                        NodeSettings nodeSettings = new NodeSettings(network, args: options);

                        var rpcSettings = new RpcSettings(nodeSettings);

                        // Find the binding to 127.0.0.1 or the first available. The logic in RPC settings ensures there will be at least 1.
                        System.Net.IPEndPoint nodeEndPoint = rpcSettings.Bind.FirstOrDefault(b => b.Address.ToString() == "127.0.0.1") ?? rpcSettings.Bind[0];
                        Uri rpcUri = new Uri($"http://{nodeEndPoint}");

                        // Process the command line RPC arguments
                        // TODO: this should probably be moved to the NodeSettings.FromArguments
                        if (options.GetValueOf("-rpcbind") != null)
                        {
                            rpcUri = new Uri($"http://{options.GetValueOf("-rpcbind")}");
                        }

                        if (options.GetValueOf("-rpcconnect") != null || options.GetValueOf("-rpcport") != null)
                        {
                            string rpcAddress = options.GetValueOf("-rpcconnect") ?? "127.0.0.1";

                            int rpcPort = rpcSettings.RPCPort;
                            int.TryParse(options.GetValueOf("-rpcport"), out rpcPort);

                            rpcUri = new Uri($"http://{rpcAddress}:{rpcPort}");
                        }
                        rpcSettings.RpcUser     = options.GetValueOf("-rpcuser") ?? rpcSettings.RpcUser;
                        rpcSettings.RpcPassword = options.GetValueOf("-rpcpassword") ?? rpcSettings.RpcPassword;

                        Console.WriteLine($"Connecting to the following RPC node: http://{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}@{rpcUri.Authority}...");

                        // Initialize the RPC client with the configured or passed userid, password and endpoint.
                        var rpcClient = new RPCClient($"{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}", rpcUri, network);

                        // Execute the RPC command
                        Console.WriteLine($"Sending RPC command '{command} {string.Join(" ", commandArgList)}' to '{rpcUri}'...");
                        RPCResponse response = rpcClient.SendCommand(command, commandArgList.ToArray());

                        // Return the result as a string to the console.
                        Console.WriteLine(response.ResultString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }
                }
                else
                {
                    // Process API call.
                    using (var client = new HttpClient())
                    {
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                        var url = $"http://localhost:{defaultRestApiPort}/api/{command}";
                        if (commandArgList.Any())
                        {
                            url += $"?{string.Join("&", commandArgList)}";
                        }
                        try
                        {
                            // Get the response.
                            Console.WriteLine($"Sending API command to {url}...");
                            var response = client.GetStringAsync(url).GetAwaiter().GetResult();

                            // Format and return the result as a string to the console.
                            Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(response), Formatting.Indented));
                        }
                        catch (Exception err)
                        {
                            Console.WriteLine(ExceptionToString(err));
                        }
                    }
                }
            }
            catch (Exception err)
            {
                // Report any errors to the console.
                Console.WriteLine(ExceptionToString(err));
            }
        }
Exemplo n.º 9
0
    void PublishTile(Vector2 index, string content)
    {
        publishing   = true;
        publishError = false;
        published    = false;

        // Basic Auth
        Dictionary <string, string> headers = new Dictionary <string, string>();

        headers["Authorization"] = "Basic " + System.Convert.ToBase64String(
            System.Text.Encoding.ASCII.GetBytes("bitcoinrpc:" + nodeAuth)
            );

        // TODO: fix compression efforts
        // byte[] binaryContent = System.Text.Encoding.ASCII.GetBytes(content);
        // byte[] compressedBinaryContent = CLZF2.Compress(binaryContent);

        // Debug.Log("Content length:");
        // Debug.Log(binaryContent.Length);
        // Debug.Log("Content length compressed:");
        // Debug.Log(compressedBinaryContent.Length);

        // string json = "{\"method\":\"settile\",\"params\":[" + index [0] + "," + index [1] + ",\"" + compressedBinaryContent + "\"],\"id\":0}";

        string json = "{\"method\":\"settile\",\"params\":[" + index[0] + "," + index[1] + ",\"" + content + "\"],\"id\":0}";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(json.ToCharArray());

        WWW www = new WWW(nodeAddress, data, headers);

        while (!www.isDone)
        {
        }                               // busy wait

        // Web transaction error
        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log("Error publishing tile! Web error: " + www.error);
            publishError = true;
        }
        else
        {
            // Process RPC response
            string responseJson = www.text;
            Debug.Log(responseJson);
            RPCResponse response = JsonUtility.FromJson <RPCResponse>(responseJson);

            // RPC error response

            /*
             * NOTE: Not great as it assumes code 0 is success, nowhere guaranteed in JSONRPC or the bitcoin API.
             * Artifact of the JsonUtility deserialization which generates an instance for a `null` value in the JSON.
             * Should not be done this way in production.
             */
            if (response.error != null && response.error.code != 0)
            {
                Debug.Log("Error publishing tile! RPC error: " + response.error.message);
                publishError = true;
            }
            else
            {
                Debug.Log("Successfully published tile!");
                published = true;
            }
        }

        publishing = false;
    }
Exemplo n.º 10
0
        public CcjCoordinator(Network network, TrustedNodeNotifyingBehavior trustedNodeNotifyingBehavior, string folderPath, RPCClient rpc, CcjRoundConfig roundConfig)
        {
            Network = Guard.NotNull(nameof(network), network);
            TrustedNodeNotifyingBehavior = Guard.NotNull(nameof(trustedNodeNotifyingBehavior), trustedNodeNotifyingBehavior);
            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>();
            CoinJoinsLock = new AsyncLock();

            Directory.CreateDirectory(FolderPath);

            UtxoReferee = new UtxoReferee(Network, FolderPath, RpcClient, RoundConfig);

            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);
                        }
                        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);
                }
            }

            try
            {
                string roundCountFilePath = Path.Combine(folderPath, "RoundCount.txt");
                if (File.Exists(roundCountFilePath))
                {
                    string roundCount = File.ReadAllText(roundCountFilePath);
                    CcjRound.RoundCount = long.Parse(roundCount);
                }
                else
                {
                    // First time initializes (so the first constructor will increment it and we'll start from 1.)
                    CcjRound.RoundCount = 0;
                }
            }
            catch (Exception ex)
            {
                CcjRound.RoundCount = 0;
                Logger.LogInfo <CcjCoordinator>($"{nameof(CcjRound.RoundCount)} file was corrupt. Resetting to 0.");
                Logger.LogDebug <CcjCoordinator>(ex);
            }

            TrustedNodeNotifyingBehavior.Block += TrustedNodeNotifyingBehavior_BlockAsync;
        }
Exemplo n.º 11
0
        public static async Task <RPCCapabilities> TestRPCAsync(NBXplorerNetwork networkInfo, RPCClient rpcClient, CancellationToken cancellation)
        {
            var network = networkInfo.NBitcoinNetwork;

            Logs.Configuration.LogInformation($"{networkInfo.CryptoCode}: Testing RPC connection to " + rpcClient.Address.AbsoluteUri);

            RPCResponse blockchainInfo = null;

            try
            {
                int time = 0;
retry:
                try
                {
                    blockchainInfo = await rpcClient.SendCommandAsync("getblockchaininfo");

                    blockchainInfo.ThrowIfError();
                }
                catch (RPCException ex) when(IsTransient(ex))
                {
                    Logs.Configuration.LogInformation($"{networkInfo.CryptoCode}: Transient error '{ex.Message}', retrying soon...");
                    time++;
                    await Task.Delay(Math.Min(1000 * time, 10000), cancellation);

                    goto retry;
                }
            }
            catch (ConfigException)
            {
                throw;
            }
            catch (RPCException ex)
            {
                Logs.Configuration.LogError($"{networkInfo.CryptoCode}: Invalid response from RPC server " + ex.Message);
                throw new ConfigException();
            }
            catch (Exception ex)
            {
                Logs.Configuration.LogError($"{networkInfo.CryptoCode}: Error connecting to RPC server " + ex.Message);
                throw new ConfigException();
            }

            Logs.Configuration.LogInformation($"{networkInfo.CryptoCode}: RPC connection successful");
            if (blockchainInfo?.Result["chain"]?.Value <string>() is string rpcChain)
            {
                List <string> expectedNames = new List <string>();
                expectedNames.Add(network.ChainName.ToString());
                expectedNames.Add(network.ChainName.ToString().Replace("net", string.Empty, StringComparison.OrdinalIgnoreCase));
                if (!expectedNames.Any(e => rpcChain.Equals(e, StringComparison.OrdinalIgnoreCase)))
                {
                    Logs.Configuration.LogError($"{networkInfo.CryptoCode}: NBXplorer expected chain is '{network.ChainName}', but the RPC node is running '{rpcChain}'");
                    throw new ConfigException();
                }
            }

            var capabilities = await rpcClient.ScanRPCCapabilitiesAsync();

            if (capabilities.Version < networkInfo.MinRPCVersion)
            {
                Logs.Configuration.LogError($"{networkInfo.CryptoCode}: The minimum node version required is {networkInfo.MinRPCVersion} (detected: {capabilities.Version})");
                throw new ConfigException();
            }
            Logs.Configuration.LogInformation($"{networkInfo.CryptoCode}: Full node version detected: {capabilities.Version}");
            return(capabilities);
        }
Exemplo n.º 12
0
        private static async Task AssertRpcNodeFullyInitializedAsync()
        {
            try
            {
                var         blockchainInfoRequest = new RPCRequest(RPCOperations.getblockchaininfo, parameters: null);
                RPCResponse blockchainInfo        = await RpcClient.SendCommandAsync(blockchainInfoRequest, throwIfRPCError : true);

                if (string.IsNullOrWhiteSpace(blockchainInfo?.ResultString))                 // should never happen
                {
                    throw new NotSupportedException("string.IsNullOrWhiteSpace(blockchainInfo?.ResultString) == true");
                }

                int blocks = blockchainInfo.Result.Value <int>("blocks");
                if (blocks == 0 && Config.Network != Network.RegTest)
                {
                    throw new NotSupportedException("blocks == 0");
                }

                int headers = blockchainInfo.Result.Value <int>("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.");

                if (Config.Network != Network.RegTest)                 // RegTest cannot estimate fees.
                {
                    var estimateSmartFeeResponse = await RpcClient.TryEstimateSmartFeeAsync(2, EstimateSmartFeeMode.Conservative);

                    if (estimateSmartFeeResponse == null)
                    {
                        throw new NotSupportedException($"Bitcoin Core cannot estimate network fees yet.");
                    }
                    Logger.LogInfo <RPCClient>("Bitcoin Core fee estimation is working.");
                }
                else                 // 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.");
                        }

                        blockchainInfoRequest = new RPCRequest(RPCOperations.getblockchaininfo, parameters: null);
                        blockchainInfo        = await RpcClient.SendCommandAsync(blockchainInfoRequest, throwIfRPCError : true);

                        blocks = blockchainInfo.Result.Value <int>("blocks");
                        if (blocks == 0)
                        {
                            throw new NotSupportedException("blocks == 0");
                        }
                        Logger.LogInfo <RPCClient>($"Generated 101 block on RegTest. Number of blocks {blocks}.");
                    }
                }
            }
            catch (WebException)
            {
                Logger.LogInfo($"Bitcoin Core is not running, or incorrect RPC credentials or network is given in the config file: `{ConfigFilePath}`.");
                throw;
            }
        }
Exemplo n.º 13
0
        public override void Deprecated_Page_Load()
        {
            long vid        = 0;
            bool doFormLoad = true;

            vcErrorCode = "0";;

            if (!this.IsAdmin)
            {
                message.InnerHtml = "<p class=\"error\">ERROR: user " + this.CurrentUser.LoginName + " is not an administrator</p>";
                doFormLoad        = false;
            }

            long.TryParse(Request["videoid"], out vid);
            this.Page.Form.Enctype = "multipart/form-data";

            // Check for deletion
            if (Request.Form["btnCancel"] == "Cancel")
            {
                doFormLoad = false;
            }
            else if (this.IsAdmin && (vid > 0) && (Request.Form["btnDelete"] == "Delete"))
            {
                RPCResponse response = this.bcApi.DeleteVideo(vid);

                if (string.IsNullOrEmpty(response.result))
                {
                    message.InnerHtml = "<p class=\"success\">Your changes have been saved. Allow up to five minutes for the changes to propagate through the Brightcove Video Cloud.</p>";
                }
                else
                {
                    message.InnerHtml = "<p class=\"error\">ERROR: Your changes could not be saved. " + response.result + "</p>";
                }

                doFormLoad = false;
            }
            else
            {
                this.SetVideo(vid);
            }

            if (doFormLoad && this.IsPostBack)
            {
                int            fileIndex = 1;
                HttpPostedFile file      = null;

                file = Request.Files["file" + fileIndex.ToString()];

                if ((file != null) && !string.IsNullOrEmpty(file.FileName))
                {
                    message.InnerHtml = string.Empty;

                    do
                    {
                        // Check for 2GB or smaller file size
                        long maxSize = (long)2 * 1024 * 1024 * 1024;

                        if (file.InputStream.Length > maxSize)
                        {
                            message.InnerHtml = "<p class=\"error\">ERROR: File size is greater than 2GB</p>";
                        }
                        else
                        {
                            byte[] buffer = new byte[file.InputStream.Length];

                            file.InputStream.Read(buffer, 0, buffer.Length);

                            if (vid <= 0)
                            {
                                RPCResponse <long> response = null;

                                for (int i = 0; (i < this.writeTokenList.Length) && (i < 5); i++)
                                {
                                    response = this.bcApi.CreateVideo(this.video, file.FileName, buffer, BCEncodeType.UNDEFINED, true);

                                    // Detect error: 213, ConcurrentWritesExceededError
                                    if (response.error.code == "213")
                                    {
                                        this.accountConfig.WriteToken.Value = writeTokenList[i];
                                        this.ResetApiConnection();
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (response.result <= 0)
                                {
                                    vid = 0;
                                    message.InnerHtml += "<p class=\"error\">ERROR: " + response.error.message + "</p>";
                                    vcErrorCode        = response.error.code;
                                }
                                else
                                {
                                    vid                = Convert.ToInt64(response.result);
                                    this.video.id      = vid;
                                    message.InnerHtml += "SUCCESS - " + vid.ToString() + "<br />";

                                    // Update thumbnail image
                                    if (!this.AddImage(Request.Files["file_thumbnailUrl"], ImageTypeEnum.THUMBNAIL, this.video.thumbnailURL))
                                    {
                                        message.InnerHtml += ", thumbnail file upload failed";
                                    }

                                    // Update video still image
                                    if (!this.AddImage(Request.Files["file_videoStillUrl"], ImageTypeEnum.VIDEO_STILL, this.video.videoStillURL))
                                    {
                                        message.InnerHtml += ", video still file upload failed";
                                    }
                                }

                                // Reset the video ID
                                vid = 0;
                            }
                        }

                        fileIndex++;
                        file = Request.Files["file" + fileIndex.ToString()];
                    } while ((file != null) && !string.IsNullOrEmpty(file.FileName));
                }
                else
                {
                    if (!string.IsNullOrEmpty(this.video.name) &&
                        !string.IsNullOrEmpty(this.video.shortDescription))
                    {
                        // Only update the video if valid
                        this.bcApi.UpdateVideo(this.video);
                        message.InnerHtml = "SUCCESS - " + vid.ToString();
                    }
                }


                if (vid > 0)
                {
                    // Update thumbnail image
                    if (!this.AddImage(Request.Files["file_thumbnailUrl"], ImageTypeEnum.THUMBNAIL, this.video.thumbnailURL))
                    {
                        message.InnerHtml += ", thumbnail file upload failed";
                    }

                    // Update video still image
                    if (!this.AddImage(Request.Files["file_videoStillUrl"], ImageTypeEnum.VIDEO_STILL, this.video.videoStillURL))
                    {
                        message.InnerHtml += ", video still file upload failed";
                    }
                }
            }

            if (this.video != null)
            {
                if (string.IsNullOrEmpty(this.video.name))
                {
                    this.video.name = " ";
                }

                string output = string.Format(
                    @"<script language=""javascript"" type=""text/javascript"" charset=""utf-8"" defer=""defer"">/*<![CDATA[*/
    var vcVideoResult = {0};
    var vcIsAdmin = {1};
    var vcErrorCode = {2};

    if (vcVideoResult != null)
    {{
        var video = document.forms[0];

        if (vcVideoResult.name)
        {{
            if (vcVideoResult.name == ' ')
            {{
                vcVideoResult.name = '';
            }}

            video['name'].value = vcVideoResult.name;
        }}

        if (vcVideoResult.shortDescription) video['shortDesc'].value = vcVideoResult.shortDescription;
        if (vcVideoResult.longDescription) video['longDesc'].value = vcVideoResult.longDescription;

        if (vcVideoResult.itemState)
        {{
            if (vcVideoResult.itemState != 'ACTIVE')
            {{
                video['isActive'].selectedIndex = 1;
            }}
        }}

        if (vcVideoResult.linkURL) video['linkUrl'].value = vcVideoResult.linkURL;
        if (vcVideoResult.linkText) video['linkText'].value = vcVideoResult.linkText;
        if (vcVideoResult.videoStillURL) video['videoStillUrl'].value = vcVideoResult.videoStillURL;
        if (vcVideoResult.thumbnailURL) video['thumbnailUrl'].value = vcVideoResult.thumbnailURL;
        if (vcVideoResult.referenceId) video['referenceId'].value = vcVideoResult.referenceId;
        if (vcVideoResult.economics)
        {{
            if (vcVideoResult.economics == 'FREE')
            {{
                video['economics'].selectedIndex = 1;
            }}
            else if (vcVideoResult.economics == 'AD_SUPPORTED')
            {{
                video['economics'].selectedIndex = 2;
            }}
        }}
        if (vcVideoResult.startDate) video['startDate'].value = new Date(new Number(vcVideoResult.startDate)).format('M/dd/yyyy');
        if (vcVideoResult.endDate) video['endDate'].value = new Date(new Number(vcVideoResult.endDate)).format('M/dd/yyyy');

        if (vcVideoResult.customFields)
        {{
            for (var key in vcVideoResult.customFields)
            {{
                video['customFields'].value += key + ':' + vcVideoResult.customFields[key] + ',';
            }}
        }}

        if (vcVideoResult.tags) video['tags'].value = vcVideoResult.tags;
    }}
/*]]>*/</script>", this.video.ToJSON().Replace(": AD_SUPPORTED", ": \"AD_SUPPORTED\"").Replace(": FREE", ": \"FREE\""), this.IsAdmin.ToString().ToLower(), vcErrorCode);

                this.Controls.Add(new LiteralControl(output));
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// The expected sequence of arguments:
        ///    1) [network-name] [rpc-command] [rpc-params].
        /// OR
        ///    2) [network-name] [api-controller "/" api-command] [api-params].
        /// </summary>
        public static void Main(string[] args)
        {
            try
            {
                // Display help if required.
                if (args.Length == 0 || args.Contains("-help") || args.Contains("--help"))
                {
                    var builder = new StringBuilder();
                    builder.AppendLine("Usage:");
                    builder.AppendLine(" dotnet run <Stratis.Bitcoin.Cli/Stratis.Bitcoin.Cli.dll> [network-name] [command] [arguments]");
                    builder.AppendLine();
                    builder.AppendLine("Command line arguments:");
                    builder.AppendLine();
                    builder.AppendLine("[network-name]            Name of the network - e.g. \"stratis\".");
                    builder.AppendLine("[command]                 Name of RPC method or API <controller>/<method>.");
                    builder.AppendLine("[arguments]               Argument by position (RPC) or Name = Value pairs (API).");
                    Console.WriteLine(builder);
                    return;
                }

                // Determine API port.
                string blockchain = "bitcoin";
                int    apiPort    = 37220;
                if (args.Any(a => a.Contains("stratis")))
                {
                    blockchain = "stratis";
                    apiPort    = 37221;
                    // hack until static flags are removed.
                    var s  = Network.StratisMain;
                    var st = Network.StratisTest;
                }

                // The first argument is the network name.
                var network = Network.GetNetwork(args.First());

                // API calls require both the contoller name and the method name separated by "/".
                // If this is not an API call then assume it is an RPC call.
                if (!args.ElementAt(1).Contains("/"))
                {
                    // Process RPC call.
                    try
                    {
                        NodeSettings nodeSettings = new NodeSettings(blockchain, network).LoadArguments(args);
                        var          rpcSettings  = new RpcSettings();
                        rpcSettings.Load(nodeSettings);

                        // Find the binding to 127.0.0.1 or the first available. The logic in RPC settings ensures there will be at least 1.
                        System.Net.IPEndPoint nodeEndPoint = rpcSettings.Bind.FirstOrDefault(b => b.Address.ToString() == "127.0.0.1") ?? rpcSettings.Bind[0];

                        // Initialize the RPC client with the configured or passed userid, password and endpoint
                        RPCClient rpc = new RPCClient($"{rpcSettings.RpcUser}:{rpcSettings.RpcPassword}", new Uri($"http://{nodeEndPoint}"));

                        // Execute the RPC command
                        Console.WriteLine($"Sending RPC command '{string.Join(" ", args.Skip(1))}' to 'http://{nodeEndPoint}'...");
                        RPCResponse response = rpc.SendCommand(args.ElementAt(1), args.Skip(2).ToArray());

                        // Return the result as a string to the console.
                        Console.WriteLine(response.ResultString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err.Message);
                    }
                }
                else
                {
                    // Process API call.
                    using (var client = new HttpClient())
                    {
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                        var url = $"http://localhost:{apiPort}/api/{args.ElementAt(1)}?{string.Join("&", args.Skip(2))}";
                        try
                        {
                            // Get the response.
                            Console.WriteLine($"Sending API command to {url}...");
                            var response = client.GetStringAsync(url).GetAwaiter().GetResult();

                            // Format and return the result as a string to the console.
                            Console.WriteLine(JsonConvert.SerializeObject(JsonConvert.DeserializeObject <object>(response), Formatting.Indented));
                        }
                        catch (Exception err)
                        {
                            Console.WriteLine(ExceptionToString(err));
                        }
                    }
                }
            }
            catch (Exception err)
            {
                // Report any errors to the console.
                Console.WriteLine(ExceptionToString(err));
            }
        }
Exemplo n.º 15
0
        public async Task <RPCResponse> SendCommandAsync(RPCRequest request, bool throwIfRPCError = true)
        {
            RPCResponse    response   = null;
            HttpWebRequest webRequest = response == null?CreateWebRequest() : null;

            if (response == null)
            {
                var writer = new StringWriter();
                request.WriteJSON(writer);
                writer.Flush();
                var json  = writer.ToString();
                var bytes = Encoding.UTF8.GetBytes(json);
#if !(PORTABLE || NETCORE)
                webRequest.ContentLength = bytes.Length;
#endif
                var dataStream = await webRequest.GetRequestStreamAsync().ConfigureAwait(false);

                await dataStream.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);

                await dataStream.FlushAsync().ConfigureAwait(false);

                dataStream.Dispose();
            }
            WebResponse webResponse   = null;
            WebResponse errorResponse = null;
            try
            {
                webResponse = response == null ? await webRequest.GetResponseAsync().ConfigureAwait(false) : null;

                response = response ?? RPCResponse.Load(await ToMemoryStreamAsync(webResponse.GetResponseStream()).ConfigureAwait(false));

                if (throwIfRPCError)
                {
                    response.ThrowIfError();
                }
            }
            catch (WebException ex)
            {
                if (ex.Response == null || ex.Response.ContentLength == 0 ||
                    !ex.Response.ContentType.Equals("application/json", StringComparison.Ordinal))
                {
                    throw;
                }
                errorResponse = ex.Response;
                response      = RPCResponse.Load(await ToMemoryStreamAsync(errorResponse.GetResponseStream()).ConfigureAwait(false));
                if (throwIfRPCError)
                {
                    response.ThrowIfError();
                }
            }
            finally
            {
                if (errorResponse != null)
                {
                    errorResponse.Dispose();
                    errorResponse = null;
                }
                if (webResponse != null)
                {
                    webResponse.Dispose();
                    webResponse = null;
                }
            }
            return(response);
        }
Exemplo n.º 16
0
        public void CanSendCommand()
        {
            RPCResponse response = this.rpcTestFixture.RpcClient.SendCommand(RPCOperations.getinfo);

            Assert.NotNull(response.Result);
        }
Exemplo n.º 17
0
        public Transaction PerformBreezeRegistration(BreezeConfiguration config, string regStorePath, string configurationHash, string onionAddress, RsaKey tumblerKey)
        {
            Network network = Network.ImpleumMain;

            if (config.TumblerNetwork == Network.TestNet || config.TumblerNetwork == Network.RegTest)
            {
                network = Network.ImpleumTest;
            }

            RPCHelper     stratisHelper   = null;
            RPCClient     stratisRpc      = null;
            BitcoinSecret privateKeyEcdsa = null;

            try {
                stratisHelper   = new RPCHelper(network);
                stratisRpc      = stratisHelper.GetClient(config.RpcUser, config.RpcPassword, config.RpcUrl);
                privateKeyEcdsa = stratisRpc.DumpPrivKey(BitcoinAddress.Create(config.TumblerEcdsaKeyAddress));
            }
            catch (Exception e) {
                Console.WriteLine("ERROR: Unable to retrieve private key to fund registration transaction");
                Console.WriteLine("Is the Stratis wallet unlocked & RPC enabled?");
                Console.WriteLine(e);
                Environment.Exit(0);
            }

            RegistrationToken registrationToken = new RegistrationToken(PROTOCOL_VERSION_TO_USE, config.TumblerEcdsaKeyAddress, config.Ipv4Address, config.Ipv6Address, onionAddress, configurationHash, config.Port, privateKeyEcdsa.PubKey);

            byte[] msgBytes = registrationToken.GetRegistrationTokenBytes(tumblerKey, privateKeyEcdsa);

            // Create the registration transaction using the bytes generated above
            Transaction rawTx = CreateBreezeRegistrationTx(network, msgBytes, config.TxOutputValueSetting);

            TransactionUtils  txUtils  = new TransactionUtils();
            RegistrationStore regStore = new RegistrationStore(regStorePath);

            try {
                // Replace fundrawtransaction with C# implementation. The legacy wallet
                // software does not support the RPC call.
                Transaction fundedTx = txUtils.FundRawTx(stratisRpc, rawTx, config.TxFeeValueSetting, BitcoinAddress.Create(config.TumblerEcdsaKeyAddress));
                RPCResponse signedTx = stratisRpc.SendCommand("signrawtransaction", fundedTx.ToHex());
                Transaction txToSend = new Transaction(((JObject)signedTx.Result)["hex"].Value <string>());

                RegistrationRecord regRecord = new RegistrationRecord(DateTime.Now,
                                                                      Guid.NewGuid(),
                                                                      txToSend.GetHash().ToString(),
                                                                      txToSend.ToHex(),
                                                                      registrationToken,
                                                                      null);

                regStore.Add(regRecord);

                stratisRpc.SendRawTransaction(txToSend);

                return(txToSend);
            }
            catch (Exception e)
            {
                Console.WriteLine("ERROR: Unable to broadcast registration transaction");
                Console.WriteLine(e);
            }

            return(null);
        }
Exemplo n.º 18
0
        public async Task GetTransactionOnConfirmedTransactionAsync()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                // Arrange.
                // Create a sending and a receiving node.
                CoreNode sendingNode   = builder.CreateStratisPosNode(this.network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest150Miner).Start();
                CoreNode receivingNode = builder.CreateStratisPosNode(this.network).WithReadyBlockchainData(ReadyBlockchain.StratisRegTest150Listener).Start();

                TestHelper.ConnectAndSync(sendingNode, receivingNode);

                // Get an address to send to.
                IEnumerable <string> unusedaddresses = await $"http://localhost:{receivingNode.ApiPort}/api"
                                                       .AppendPathSegment("wallet/unusedAddresses")
                                                       .SetQueryParams(new { walletName = "mywallet", accountName = "account 0", count = 1 })
                                                       .GetJsonAsync <IEnumerable <string> >();

                // Build and send the transaction with an Op_Return.
                WalletBuildTransactionModel buildTransactionModel = await $"http://localhost:{sendingNode.ApiPort}/api"
                                                                    .AppendPathSegment("wallet/build-transaction")
                                                                    .PostJsonAsync(new BuildTransactionRequest
                {
                    WalletName       = "mywallet",
                    AccountName      = "account 0",
                    FeeType          = "low",
                    Password         = "******",
                    ShuffleOutputs   = false,
                    AllowUnconfirmed = true,
                    Recipients       = unusedaddresses.Select(address => new RecipientModel
                    {
                        DestinationAddress = address,
                        Amount             = "1"
                    }).ToList(),
                })
                                                                    .ReceiveJson <WalletBuildTransactionModel>();

                await $"http://localhost:{sendingNode.ApiPort}/api"
                .AppendPathSegment("wallet/send-transaction")
                .PostJsonAsync(new SendTransactionRequest
                {
                    Hex = buildTransactionModel.Hex
                })
                .ReceiveJson <WalletSendTransactionModel>();

                uint256 txId = buildTransactionModel.TransactionId;

                // Mine and sync so that we make sure the receiving node is up to date.
                TestHelper.MineBlocks(sendingNode, 1);
                TestHelper.WaitForNodeToSync(sendingNode, receivingNode);

                // Get the block that was mined.
                string lastBlockHash = await $"http://localhost:{sendingNode.ApiPort}/api"
                                       .AppendPathSegment("consensus/getbestblockhash")
                                       .GetJsonAsync <string>();

                BlockModel blockModelAtTip = await $"http://localhost:{sendingNode.ApiPort}/api"
                                             .AppendPathSegment("blockstore/block")
                                             .SetQueryParams(new { hash = lastBlockHash, outputJson = true })
                                             .GetJsonAsync <BlockModel>();

                Transaction trx = this.network.Consensus.ConsensusFactory.CreateTransaction(buildTransactionModel.Hex);

                RPCClient   rpcReceivingNode  = receivingNode.CreateRPCClient();
                RPCResponse txReceivingWallet = rpcReceivingNode.SendCommand(RPCOperations.gettransaction, txId.ToString());

                RPCClient   rpcSendingNode  = sendingNode.CreateRPCClient();
                RPCResponse txSendingWallet = rpcSendingNode.SendCommand(RPCOperations.gettransaction, txId.ToString());

                // Assert.
                GetTransactionModel resultSendingWallet = txSendingWallet.Result.ToObject <GetTransactionModel>();
                resultSendingWallet.Amount.Should().Be((decimal) - 1.00000000);
                resultSendingWallet.Fee.Should().Be((decimal) - 0.0001);
                resultSendingWallet.Confirmations.Should().Be(1);
                resultSendingWallet.Isgenerated.Should().BeNull();
                resultSendingWallet.TransactionId.Should().Be(txId);
                resultSendingWallet.BlockHash.Should().Be(uint256.Parse(blockModelAtTip.Hash));
                resultSendingWallet.BlockIndex.Should().Be(1);
                resultSendingWallet.BlockTime.Should().Be(blockModelAtTip.Time);
                resultSendingWallet.TimeReceived.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultSendingWallet.TransactionTime.Should().Be(((PosTransaction)trx).Time);
                resultSendingWallet.Details.Count.Should().Be(1);

                GetTransactionDetailsModel detailsSendingWallet = resultSendingWallet.Details.Single();
                detailsSendingWallet.Address.Should().Be(unusedaddresses.First());
                detailsSendingWallet.Amount.Should().Be((decimal) - 1.00000000);
                detailsSendingWallet.Fee.Should().Be((decimal) - 0.0001);
                detailsSendingWallet.Category.Should().Be(GetTransactionDetailsCategoryModel.Send);
                detailsSendingWallet.OutputIndex.Should().Be(1);

                GetTransactionModel resultReceivingWallet = txReceivingWallet.Result.ToObject <GetTransactionModel>();
                resultReceivingWallet.Amount.Should().Be((decimal)1.00000000);
                resultReceivingWallet.Fee.Should().BeNull();
                resultReceivingWallet.Confirmations.Should().Be(1);
                resultReceivingWallet.Isgenerated.Should().BeNull();
                resultReceivingWallet.TransactionId.Should().Be(txId);
                resultReceivingWallet.BlockHash.Should().Be(uint256.Parse(blockModelAtTip.Hash));
                resultReceivingWallet.BlockIndex.Should().Be(1);
                resultReceivingWallet.BlockTime.Should().Be(blockModelAtTip.Time);
                resultReceivingWallet.TimeReceived.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultReceivingWallet.TransactionTime.Should().BeGreaterThan((DateTimeOffset.Now - TimeSpan.FromMinutes(1)).ToUnixTimeSeconds());
                resultReceivingWallet.Details.Should().ContainSingle();

                GetTransactionDetailsModel detailsReceivingWallet = resultReceivingWallet.Details.Single();
                detailsReceivingWallet.Address.Should().Be(unusedaddresses.Single());
                detailsReceivingWallet.Amount.Should().Be((decimal)1.00000000);
                detailsReceivingWallet.Fee.Should().BeNull();
                detailsReceivingWallet.Category.Should().Be(GetTransactionDetailsCategoryModel.Receive);
                detailsReceivingWallet.OutputIndex.Should().Be(1);
            }
        }
Exemplo n.º 19
0
        public async Task <IActionResult> InputsAsync([FromBody] InputsRequest request)
        {
            var roundId = Global.StateMachine.RoundId;

            TumblerPhase phase = TumblerPhase.InputRegistration;

            try
            {
                if (Global.StateMachine.Phase != TumblerPhase.InputRegistration || !Global.StateMachine.AcceptRequest)
                {
                    return(new ObjectResult(new FailureResponse {
                        Message = "Wrong phase"
                    }));
                }

                // Check not nulls
                string blindedOutputString = request.BlindedOutput.Trim();
                if (string.IsNullOrWhiteSpace(blindedOutputString))
                {
                    return(new BadRequestResult());
                }
                if (string.IsNullOrWhiteSpace(request.ChangeOutput))
                {
                    return(new BadRequestResult());
                }
                if (request.Inputs == null || request.Inputs.Count() == 0)
                {
                    return(new BadRequestResult());
                }

                // Check format (parse everyting))
                if (Global.StateMachine.BlindedOutputs.Contains(blindedOutputString))
                {
                    throw new ArgumentException("Blinded output has already been registered");
                }
                byte[]  blindedOutput = HexHelpers.GetBytes(blindedOutputString);
                Network network       = Global.Config.Network;
                var     changeOutput  = new BitcoinWitPubKeyAddress(request.ChangeOutput, expectedNetwork: network);
                if (request.Inputs.Count() > Global.Config.MaximumInputsPerAlices)
                {
                    throw new NotSupportedException("Too many inputs provided");
                }
                var inputs = new HashSet <(TxOut Output, OutPoint OutPoint)>();

                var alicesToRemove = new HashSet <Guid>();
                using (await InputRegistrationLock.LockAsync())
                {
                    foreach (InputProofModel input in request.Inputs)
                    {
                        var op = new OutPoint();
                        op.FromHex(input.Input);
                        if (inputs.Any(x => x.OutPoint.Hash == op.Hash && x.OutPoint.N == op.N))
                        {
                            throw new ArgumentException("Attempting to register an input twice is not permitted");
                        }
                        foreach (var a in Global.StateMachine.Alices)
                        {
                            if (a.Inputs.Any(x => x.OutPoint.Hash == op.Hash && x.OutPoint.N == op.N))
                            {
                                alicesToRemove.Add(a.UniqueId);                                 // input is already registered by this alice, remove it if all the checks are completed fine
                            }
                        }

                        BannedUtxo banned = Global.UtxoReferee.Utxos.FirstOrDefault(x => x.Utxo.Hash == op.Hash && x.Utxo.N == op.N);
                        if (banned != default(BannedUtxo))
                        {
                            var maxBan  = (int)TimeSpan.FromDays(30).TotalMinutes;
                            int banLeft = maxBan - (int)((DateTimeOffset.UtcNow - banned.TimeOfBan).TotalMinutes);
                            throw new ArgumentException($"Input is banned for {banLeft} minutes");
                        }

                        var getTxOutResponse = await Global.RpcClient.GetTxOutAsync(op.Hash, (int)op.N, true);

                        // Check if inputs are unspent
                        if (getTxOutResponse == null)
                        {
                            throw new ArgumentException("Provided input is not unspent");
                        }
                        // Check if inputs are unconfirmed, if so check if they are part of previous CoinJoin
                        if (getTxOutResponse.Confirmations <= 0)
                        {
                            if (!Global.CoinJoinStore.Transactions
                                .Any(x => x.State >= CoinJoinTransactionState.Succeeded && x.Transaction.GetHash() == op.Hash))
                            {
                                throw new ArgumentException("Provided input is not confirmed, nor spends a previous CJ transaction");
                            }
                            else
                            {
                                // after 24 unconfirmed cj in the mempool dont't let unconfirmed coinjoin to be registered
                                var unconfirmedCoinJoins = Global.CoinJoinStore.Transactions.Where(x => x.State == CoinJoinTransactionState.Succeeded);
                                if (unconfirmedCoinJoins.Count() >= 24)
                                {
                                    var toFailed    = new HashSet <uint256>();
                                    var toConfirmed = new HashSet <uint256>();
                                    foreach (var tx in unconfirmedCoinJoins)
                                    {
                                        RPCResponse getRawTransactionResponse = (await Global.RpcClient.SendCommandAsync("getrawtransaction", tx.Transaction.GetHash().ToString(), true));
                                        if (string.IsNullOrWhiteSpace(getRawTransactionResponse?.ResultString))
                                        {
                                            toFailed.Add(tx.Transaction.GetHash());
                                        }
                                        if (getRawTransactionResponse.Result.Value <int>("confirmations") > 0)
                                        {
                                            toConfirmed.Add(tx.Transaction.GetHash());
                                        }
                                    }
                                    foreach (var tx in toFailed)
                                    {
                                        Global.CoinJoinStore.TryUpdateState(tx, CoinJoinTransactionState.Failed);
                                    }
                                    foreach (var tx in toConfirmed)
                                    {
                                        Global.CoinJoinStore.TryUpdateState(tx, CoinJoinTransactionState.Confirmed);
                                    }
                                    if (toFailed.Count + toConfirmed.Count > 0)
                                    {
                                        await Global.CoinJoinStore.ToFileAsync(Global.CoinJoinStorePath);
                                    }
                                    // if couldn't remove any unconfirmed tx then refuse registration
                                    if (Global.CoinJoinStore.Transactions.Count(x => x.State == CoinJoinTransactionState.Succeeded) >= 24)
                                    {
                                        throw new ArgumentException("Registering unconfirmed CJ transaction output is currently not allowed due to too long mempool chain");
                                    }
                                }
                            }
                        }
                        // Check coinbase > 100
                        if (getTxOutResponse.Confirmations < 100)
                        {
                            if (getTxOutResponse.IsCoinBase)
                            {
                                throw new ArgumentException("Provided input is unspendable");
                            }
                        }
                        // Check if inputs are native segwit
                        if (getTxOutResponse.ScriptPubKeyType != "witness_v0_keyhash")
                        {
                            throw new ArgumentException("Provided input is not witness_v0_keyhash");
                        }

                        var txout = getTxOutResponse.TxOut;

                        var address = (BitcoinWitPubKeyAddress)txout.ScriptPubKey.GetDestinationAddress(network);
                        // Check if proofs are valid
                        var validProof = address.VerifyMessage(blindedOutputString, input.Proof);
                        if (!validProof)
                        {
                            throw new ArgumentException("Provided proof is invalid");
                        }

                        inputs.Add((txout, op));
                    }

                    // Check if inputs have enough coins
                    Money amount = Money.Zero;
                    foreach (Money val in inputs.Select(x => x.Output.Value))
                    {
                        amount += val;
                    }
                    Money feeToPay     = (inputs.Count() * Global.StateMachine.FeePerInputs + 2 * Global.StateMachine.FeePerOutputs);
                    Money changeAmount = amount - (Global.StateMachine.Denomination + feeToPay);
                    if (changeAmount < Money.Zero + new Money(548))                     // 546 is dust
                    {
                        throw new ArgumentException("Total provided inputs must be > denomination + fee + dust");
                    }

                    byte[] signature = Global.RsaKey.SignBlindedData(blindedOutput);
                    Global.StateMachine.BlindedOutputs.Add(blindedOutputString);

                    Guid uniqueId = Guid.NewGuid();

                    var alice = new Alice
                    {
                        UniqueId     = uniqueId,
                        ChangeOutput = changeOutput,
                        ChangeAmount = changeAmount,
                        State        = AliceState.InputsRegistered
                    };
                    alice.Inputs = new ConcurrentHashSet <(TxOut Output, OutPoint OutPoint)>();
                    foreach (var input in inputs)
                    {
                        alice.Inputs.Add(input);
                    }

                    AssertPhase(roundId, phase);
                    foreach (var aliceToRemove in alicesToRemove)
                    {
                        if (Global.StateMachine.TryRemoveAlice(aliceToRemove))
                        {
                            await Global.StateMachine.BroadcastPeerRegisteredAsync();
                        }
                    }
                    Global.StateMachine.Alices.Add(alice);

                    await Global.StateMachine.BroadcastPeerRegisteredAsync();

                    if (Global.StateMachine.Alices.Count >= Global.StateMachine.AnonymitySet)
                    {
                        Global.StateMachine.UpdatePhase(TumblerPhase.ConnectionConfirmation);
                    }
                    TumblerStateMachine.EstimateInputAndOutputSizes(out int inputSizeInBytes, out int outputSizeInBytes);
                    int estimatedTxSize = Global.StateMachine.Alices.SelectMany(x => x.Inputs).Count() * inputSizeInBytes + 2 * outputSizeInBytes;
                    if (estimatedTxSize >= 90000)                    // standard transaction is < 100KB
                    {
                        Global.StateMachine.UpdatePhase(TumblerPhase.ConnectionConfirmation);
                    }

                    var ret = new ObjectResult(new InputsResponse()
                    {
                        UniqueId            = uniqueId.ToString(),
                        SignedBlindedOutput = HexHelpers.ToString(signature)
                    });
                    return(ret);
                }
            }
            catch (Exception ex)
            {
                return(new ObjectResult(new FailureResponse {
                    Message = ex.Message
                }));
            }
        }