private static double ConvertTargetToDifficulty(XMRJob x) { string sDiff = "000000" + x.target + "0000000000000000000000000000000000000000000000000000000000000000"; sDiff = sDiff.Substring(0, 64); System.Numerics.BigInteger biDiff = new System.Numerics.BigInteger(PoolCommon.StringToByteArr(sDiff)); System.Numerics.BigInteger biMin = new System.Numerics.BigInteger(PoolCommon.StringToByteArr("0x00000000FFFF0000000000000000000000000000000000000000000000000000")); System.Numerics.BigInteger bidiff = System.Numerics.BigInteger.Divide(biMin, biDiff); double nDiff = GetDouble(bidiff.ToString()); return(nDiff); }
protected void btnSubmitProposal_Click(object sender, EventArgs e) { string sError = ""; if (txtName.Text.Length < 5) { sError = "Proposal name too short."; } if (txtAddress.Text.Length < 24) { sError = "Address must be valid."; } if (GetDouble(txtAmount.Text) <= 0) { sError = "Amount must be populated."; } if (!gUser(this).LoggedIn) { sError = "You must be logged in."; } bool fValid = PoolCommon.ValidateBiblepayAddress(IsTestNet(this), txtAddress.Text); if (!fValid) { sError = "Address is not valid for this chain."; } if (GetDouble(txtAmount.Text) > 2600000) { sError = "Amount is too high (over superblock limit)."; } double nMyBal = DataOps.GetUserBalance(this); if (nMyBal < 2501) { sError = "Balance too low."; } if (sError != "") { MsgBox("Error", sError, this); } // Submit DataOps.AdjBalance(-1 * 2500, gUser(this).UserId, "Proposal Fee - " + Left(txtURL.Text, 100)); Code.Proposals.gobject_serialize(IsTestNet(this), gUser(this).UserId, gUser(this).UserName, txtName.Text, txtAddress.Text, txtAmount.Text, txtURL.Text, ddCharity.SelectedValue); MsgBox("Success", "Thank you. Your proposal will be submitted in six blocks.", this); }
protected void btnTip_Click(object sender, EventArgs e) { bool bValid = PoolCommon.ValidateBiblepayAddress(IsTestNet(this), txtAddress.Text); double nBalance = DataOps.GetUserBalance(gUser(this).UserId); double dAmt = GetDouble(txtAmount.Text); string sReferrer = Request.QueryString["referrer"].ToNonNullString(); if (dAmt > nBalance) { MsgBox("Balance Too Low", "Sorry, unable to tip user because your balance is too low.", this); return; } if (dAmt < 0 || dAmt > 1000000) { MsgBox("Out of Range", "Sorry you must tip between .01 and 1MM BBP.", this); return; } if (!bValid) { MsgBox("Invalid address", "Sorry, the address is invalid.", this); return; } string txid = Withdraw(gUser(this).UserId, txtAddress.Text, dAmt, "Tip to " + txtAddress.Text); if (txid == "") { MsgBox("Send Failure", "Sorry, the tip failed. Please contact [email protected]", this); return; } else { string sRedirect = "Click <a href='" + sReferrer + "'>here to return to the page you came from</a>."; if (sReferrer == "") { sRedirect = "Have a great day."; } MsgBox("Success!", "You have tipped " + txtAddress.Text + " the amount " + dAmt.ToString() + " BBP. <br><br>" + sRedirect, this); return; } }
protected void Page_Load(object sender, EventArgs e) { string sAction = Request.QueryString["action"].ToNonNullString(); Log("SERVER::" + sAction); if (sAction == "BBP_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.BBP_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "QUERY_UTXO") { Response.Write("<eof>"); Response.End(); } else if (sAction == "QUERY_UTXOS") { Response.Write("<eof>"); Response.End(); return; string sXML = Request.Headers["Action"].ToNonNullString(); string sAddress = ExtractXML(sXML, "<address>", "</address>").ToString(); string sTicker = ExtractXML(sXML, "<ticker>", "</ticker>").ToString(); int nUTXOTime = (int)GetDouble(ExtractXML(sXML, "<timestamp>", "</timestamp>").ToString()); List <SimpleUTXO> l = QueryUTXOs(sTicker, sAddress, nUTXOTime); string sReply = ""; for (int i = 0; i < l.Count; i++) { SimpleUTXO u = l[i]; sReply += SerializeUTXO(u); } sReply += "<eof>"; //Log("Query LISTOF(UTXO) " + sXML + " == REPLY == " + sReply); Response.Write(sReply); Response.End(); } else if (sAction == "PUBKEYDERIVE") { string sMinerID = Request.Headers["MinerID"].ToNonNullString(); string sHash = GetSha256HashI(sMinerID); KeyType k = DeriveNewKey(sHash); string sReply = k.PubKey + "|" + k.PrivKey + "|"; Response.Write(sReply); Response.End(); } else if (sAction == "QUERYADDRESSBALANCE") { string sAddress = Request.Headers["Address"].ToNonNullString(); string sAddress2 = Request.QueryString["Address"].ToNonNullString(); double b = QueryAddressBalance(Coalesce(sAddress, sAddress2)); string sReply = b.ToString(); Log("QUERYADDRBALANCE " + Coalesce(sAddress, sAddress2) + " REPLY " + sReply); Response.Write(sReply); Response.End(); } else if (sAction == "QUERYROKUBALANCE") { string sHWID = Request.Headers["hwid"].ToNonNullString(); KeyType k = DeriveRokuKeypair(sHWID); double b = QueryAddressBalance(k.PubKey); string sReply = b.ToString(); Response.Write(sReply); Response.End(); } else if (sAction == "LISTROKUORPHANNFTS") { string sHWID = Request.Headers["hwid"].ToNonNullString(); string data = Common.ListRokuNFTS(sHWID, false); Response.Write(data); Response.End(); } else if (sAction == "LISTMYROKUORPHANNFTS") { string sHWID = Request.Headers["hwid"].ToNonNullString(); string data = Common.ListRokuNFTS(sHWID, true); Response.Write(data); Response.End(); } else if (sAction == "QUERYROKUADDRESS") { string sHWID = Request.Headers["hwid"].ToNonNullString(); KeyType k = DeriveRokuKeypair(sHWID); Response.Write(k.PubKey); Response.End(); } else if (sAction == "QUERYROKUPRIVATEKEY") { string sHWID = Request.Headers["hwid"].ToNonNullString(); KeyType k = DeriveRokuKeypair(sHWID); Response.Write(k.PrivKey); Response.End(); } else if (sAction == "BUYNFT") { // This lets a Roku TV viewer sponsor an orphan: string sHWID = Request.Headers["hwid"].ToNonNullString(); string sAmt = Request.QueryString["amount"].ToNonNullString(); string sData = Request.Headers["base64data"].ToNonNullString(); string sDecoded = Base64Decode(sData); string sLastOwner = ExtractXML(sDecoded, "<lastcpk>", "</lastcpk>").ToString(); double dAmt = GetDouble(sAmt); if (dAmt > 0 && sHWID != "" && sLastOwner != "") { KeyType k = DeriveRokuKeypair(sHWID); DACResult r = CreateFundingTransaction(dAmt, sLastOwner, k.PrivKey, sDecoded, true); string sResult = r.sTXID.ToNonNullString() + "|" + r.sResult.ToNonNullString() + "|" + r.sError.ToNonNullString(); Log("SPENDING : " + sResult + ", Enc=" + sData + ", Data=" + sDecoded); string sDesc = ExtractXML(sDecoded, "<description>", "</description>").ToString(); string sLo = ExtractXML(sDecoded, "<loqualityurl>", "</loqualityurl>").ToString(); double nPrice = GetDouble(ExtractXML(sDecoded, "<buyitnowamount>", "</buyitnowamount>")); NotifyOfRokuSale(sDesc, "*****@*****.**", r.sTXID, true, sLo, nPrice); Response.Write(sResult); Response.End(); } else { Response.Write("Invalid Funding Transaction"); Response.End(); } } else if (sAction == "SERIALIZENFT") { string sNFTID = Request.Headers["nftid"].ToNonNullString(); if (sNFTID == "") { Response.Write(""); Response.End(); } string sHWID = Request.Headers["hwid"].ToNonNullString(); KeyType k = DeriveRokuKeypair(sHWID); string sBuyerCPK = k.PubKey; string sPayload = PoolCommon.SerializeNFT(sHWID, sNFTID, "BUY"); Response.Write(sPayload); Response.End(); } else if (sAction == "CREATEFUNDINGTRANSACTION") { string sPrivKey = Request.Headers["PRIVKEY"].ToNonNullString(); string sToAddress = Request.Headers["TOADDRESS"].ToNonNullString(); string sAmount = Request.Headers["AMOUNT"].ToNonNullString(); string sNotes = Request.Headers["NOTES"].ToNonNullString(); DACResult r = CreateFundingTransaction(GetDouble(sAmount), sToAddress, sPrivKey, sNotes, true); string sResult = r.sTXID.ToNonNullString() + "|" + r.sResult.ToNonNullString() + "|" + r.sError.ToNonNullString(); Response.Write(sResult); Response.End(); } else if (sAction == "MAIL") { string sXML1 = Request.Headers["Action"].ToNonNullString(); string sXML = Base64Decode(sXML1); DirectMailLetter m = new DirectMailLetter(); string sTo = ExtractXML(sXML, "<to>", "</to>").ToString(); string sFrom = ExtractXML(sXML, "<from>", "</from>").ToString(); m.To.Name = ExtractXML(sTo, "<Name>", "</Name>").ToString(); m.To.AddressLine1 = ExtractXML(sTo, "<AddressLine1>", "</AddressLine1>").ToString(); m.To.AddressLine2 = ExtractXML(sTo, "<AddressLine2>", "</AddressLine2>").ToString(); m.To.City = ExtractXML(sTo, "<City>", "</City>").ToString(); m.To.State = ExtractXML(sTo, "<State>", "</State>").ToString(); m.To.Zip = ExtractXML(sTo, "<Zip>", "</Zip>").ToString(); m.From.Name = ExtractXML(sFrom, "<Name>", "</Name>").ToString(); m.From.AddressLine1 = ExtractXML(sFrom, "<AddressLine1>", "</AddressLine1>").ToString(); m.From.AddressLine2 = ExtractXML(sFrom, "<AddressLine2>", "</AddressLine2>").ToString(); m.From.City = ExtractXML(sFrom, "<City>", "</City>").ToString(); m.From.State = ExtractXML(sFrom, "<State>", "</State>").ToString(); m.From.Zip = ExtractXML(sFrom, "<Zip>", "</Zip>").ToString(); m.Medium = "Letter"; m.Size = "8.5x14"; m.DryRun = GetDouble(ExtractXML(sXML, "<dryrun>", "</dryrun>").ToString()) == 1; // Check to see if they paid for this (requires <txid> and <toaddress>) double nPaidBBP = 0; if (m.DryRun == false) { for (int iSleep = 0; iSleep < 10; iSleep++) { nPaidBBP = BMS.VerifyServicePayment(sXML); if (nPaidBBP > 0) { break; } System.Threading.Thread.Sleep(1000); } } double nAmtPaidUSD = GetUSDAmountFromBBP(nPaidBBP); Log("Mailing " + sXML + ", PAID=" + nPaidBBP.ToString() + ", amtusd = " + nAmtPaidUSD.ToString() + ", dryrun=" + m.DryRun.ToString()); // ************************************ DRY RUN ? ************************************************ if (m.DryRun == false && nAmtPaidUSD < .51) { m.DryRun = true; } m.PostalClass = "First Class"; m.Template = ExtractXML(sXML, "<Template>", "</Template>").ToNonNullString().ToLower(); m.Data = "ea659d20-6031-4f23-abab-3fe39abf381f"; // Easter template string[] vCard = m.Template.Split(" "); if (vCard.Length < 1) { Response.Write("<EOF><HTML>"); return; } m.VariablePayload.ImageURL = "https://foundation.biblepay.org/Uploads/DM/" + vCard[0] + ".jpg"; m.VariablePayload.OpeningSalutation = ExtractXML(sTo, "<OpeningSalutation>", "</OpeningSalutation>").ToString(); m.VariablePayload.Paragraph1 = ExtractXML(sXML, "<paragraph1>", "</paragraph1>").ToString(); m.VariablePayload.Paragraph2 = ExtractXML(sXML, "<paragraph2>", "</paragraph2>").ToString(); m.VariablePayload.ClosingSalutation = ExtractXML(sTo, "<ClosingSalutation>", "</ClosingSalutation>").ToString(); m.VariablePayload.FirstName = m.To.Name; m.VariablePayload.SenderName = m.From.Name; m.VariablePayload.SenderCompany = "Bible Pay"; Log("Create Greeting Card " + m.VariablePayload.ImageURL + ";" + m.Template); m.Description = "tx " + ExtractXML(sXML, "<txid>", "</txid>").ToString(); string response = MailLetter(m) + "<EOF></HTML>"; Response.Write(response); Response.End(); return; } else if (sAction == "statement") { string sBusinessAddress = Request.QueryString["businessaddress"].ToNonNullString(); string sCustomerAddress = Request.QueryString["customeraddress"].ToNonNullString(); int nStart = (int)GetDouble(Request.QueryString["starttime"].ToNonNullString()); int nEnd = (int)GetDouble(Request.QueryString["endtime"].ToNonNullString()); if (nEnd < nStart) { nStart = 0; nEnd = 0; } dynamic oJson2 = PoolCommon.GetStatement(sBusinessAddress, sCustomerAddress, nStart, nEnd); if (oJson2 == null) { Response.Write("<EOF>"); return; } dynamic oJson = oJson2.Result; var jmyc = oJson["Charges"]; var jmyp = oJson["Payments"]; string sTable = "<table width=100% style='text-align:left;'>"; string sCharges = sTable + "<TR><TH>Date</th><th width=50%>Description<th>Amount</th></tr>"; foreach (var jCharge in jmyc) { string sKey = jCharge.Name; string sDesc = jCharge.Value["Description"].Value; var nAmt = jCharge.Value["Amount"].Value; string sFromAddress = jCharge.Value["FromAddress"].Value; string sName = jCharge.Value["Name"].Value; var nTime = jCharge.Value["Time"].Value; string sRow = "<TR><TD>" + UnixTimeStampToDateTime(nTime) + "<TD>" + sDesc + "</TD><TD>" + nAmt.ToString() + "</TR>\r\n"; sCharges += sRow; } sCharges += "</table>"; string sPays = sTable + "<TR><TH>Date</th><th width=50%>Invoice Number</th><th>Amount</th></tr>"; foreach (var jPayment in jmyp) { string sKey = jPayment.Name; string sDesc = jPayment.Value["Notes"].Value; double nAmt = jPayment.Value["Amount"].Value; string sInvoiceNumber = jPayment.Value["InvoiceNumber"].Value; var nTime = jPayment.Value["Time"].Value; var TXID = jPayment.Value["TXID"].Value; string sRow = "<TR><TD>" + UnixTimeStampToDateTime(nTime) + "<td>" + sInvoiceNumber + "<td>" + nAmt.ToNonNullString() + "</td></tr>\r\n"; sPays += sRow; } sPays += "</table>"; string sExtra = sTable + "<TR><TH><TH width=50%>TOTALS:</th><th>Amount</th></tr>"; string sWords = "Prior Charges,Prior Payments,Balance Forward,Current Charges,Current Payments,Current Balance"; string sRow1 = "<TR><TD><TD>Period Start<TD>" + UnixTimeStampToDateTime(oJson["Period Start"].Value) + "</TR>\r\n"; sExtra += sRow1; string sRow2 = "<TR><TD><TD>Period End<TD>" + UnixTimeStampToDateTime(oJson["Period End"].Value) + "</TR>\r\n"; sExtra += sRow2; string[] vWords = sWords.Split(","); for (int i = 0; i < vWords.Length; i++) { var nAmt = oJson[vWords[i]].Value; string sRow = "<TR><TD><TD>" + vWords[i] + "<TD>" + nAmt.ToString() + "</TR>\r\n"; sExtra += sRow; } sExtra += "</table>"; string HTML = UICommon.GetTableBeginning("Statement 04-24-2021 CPKABC123456"); HTML += sCharges + "<br><br>" + sPays + "<br><br>" + sExtra; // To byte array here var result = Pdf.From(HTML).Portrait().Content(); Response.Clear(); Response.ContentType = "application/pdf"; string sPeriod = UnixTimeStampToDateTime(oJson["Period Start"].Value).ToString(); string accName = "Statement - " + sPeriod + ".pdf"; Response.AddHeader("Content-Disposition", "attachment;filename=" + accName); Response.BinaryWrite(result); Response.Flush(); Response.End(); } else if (sAction == "TIP") { string sToAddress = Request.QueryString["ToAddress"].ToNonNullString(); bool bValid = PoolCommon.ValidateBiblepayAddress(false, sToAddress); double dAmt = Code.Common.GetDouble(Request.QueryString["Amount"].ToNonNullString()); if (gUser(this).LoggedIn == false) { MsgBox("Log In Error", "Sorry, you must be logged in first.", this); return; } double nBalance = DataOps.GetUserBalance(gUser(this).UserId); if (dAmt > nBalance) { MsgBox("Balance Too Low", "Sorry, unable to tip user because your balance is too low.", this); return; } if (dAmt < 0 || dAmt > 1000000) { MsgBox("Out of Range", "Sorry you must tip between .01 and 1MM BBP.", this); return; } if (!bValid) { MsgBox("Invalid address", "Sorry, the address is invalid.", this); return; } string txid = Withdraw(gUser(this).UserId, sToAddress, dAmt, "Tip to " + sToAddress); if (txid == "") { MsgBox("Send Failure", "Sorry, the tip failed. Please contact [email protected]", this); return; } else { MsgBox("Success!", "You have tipped " + sToAddress + " the amount " + dAmt.ToString() + " BBP. ", this); return; } } else if (sAction == "XMR_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.XMR_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "DASH_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.DASH_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "LTC_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.LTC_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "ZEC_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.ZEC_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "BCH_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.BCH_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "XLM_PRICE_QUOTE") { string sXLM = Saved.Code.BMS.XLM_PRICE_QUOTE(); Response.Write(sXLM); Response.End(); return; } else if (sAction == "XRP_PRICE_QUOTE") { string s1 = Saved.Code.BMS.XRP_PRICE_QUOTE(); Response.Write(s1); Response.End(); return; } else if (sAction.Contains("GENERIC_PRICE_QUOTE")) { string[] vTicker = sAction.Split("_"); if (vTicker.Length > 2) { double nPQ = Saved.Code.BMS.GetPriceQuote(vTicker[3]); string sRes = nPQ.ToString("0." + new string('#', 339)); string sResult = "<MIDPOINT>" + sRes + "</MIDPOINT><EOF>"; Response.Write(sResult); Response.End(); return; } } else if (sAction == "DOGE_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.DOGE_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "ETH_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.ETH_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "MOBILE_API") { MobileAPI m = new MobileAPI(); //string sBPQ = Saved.Code.BMS.BTC_PRICE_QUOTE(); //string sBBP = Saved.Code.BMS.BBP_PRICE_QUOTE(); m.BTCUSD = BMS.GetPriceQuote("BTC/USD"); double nBBPBTC = BMS.GetPriceQuote("BBP/BTC"); m.BBPUSD = m.BTCUSD * nBBPBTC; m.BBPBTC = nBBPBTC.ToString("0." + new string('#', 339)); String json = Newtonsoft.Json.JsonConvert.SerializeObject(m); Response.Write(json); Response.End(); return; } else if (sAction == "BTC_PRICE_QUOTE") { string sBPQ = Saved.Code.BMS.BTC_PRICE_QUOTE(); Response.Write(sBPQ); Response.End(); return; } else if (sAction == "LAST_MANDATORY_VERSION") { string LMV = Saved.Code.BMS.LAST_MANDATORY_VERSION(); Response.Write(LMV); Response.End(); return; } else if (sAction == "KAIROS_PAYMENTS") { Saved.Code.BMS.KAIROS_PAYMENTS(Response); return; } else if (sAction == "CAMEROON_PAYMENTS") { Saved.Code.BMS.CAMEROON_PAYMENTS(Response); return; } else if (sAction == "CAMEROON_CHILDREN") { Saved.Code.BMS.CAMEROON_CHILDREN(Response); return; } else if (sAction == "KAIROS_CHILDREN") { Saved.Code.BMS.KAIROS_CHILDREN(Response); return; } else if (sAction == "PoolMetrics") { string XML = BMS.GetPoolMetrics(); Response.Write(XML); Response.End(); return; } else if (sAction == "FaucetID") { string sResult = Saved.Code.BMS.FaucetID(Request); Response.Write(sResult); Response.End(); return; } else if (sAction == "GetUTXO") { Response.Write("<EOF></HTML>\r\n"); } else if (sAction == "GetUTXOData") { string sReport = DataOps.GetUTXOReport(); Response.Write(sReport); Response.End(); return; } else if (sAction == "TrackDashPay") { string sResult = Saved.Code.BMS.TrackDashPay(Request); Response.Write(sResult); Response.End(); return; } else if (sAction == "DashPay") { string sResult = Saved.Code.BMS.DashPay(Request); Response.Write(sResult); Response.End(); return; } else { Response.Write("<HTML>NOT FOUND</EOF>"); } }
void InitializeXMR() { retry: TcpListener listener = null; try { { IPAddress ipAddress = IPAddress.Parse(GetBMSConfigurationKeyValue("bindip")); listener = new TcpListener(IPAddress.Any, (int)GetDouble(GetBMSConfigurationKeyValue("XMRPort"))); listener.Start(); Log("BBP XMR POOL is starting up..."); } } catch (Exception ex1) { Log("Problem starting XMR pool:" + ex1.Message); } while (true) { // Complimentary outbound socket try { Thread.Sleep(10); if (listener.Pending()) { Socket client = listener.AcceptSocket(); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); int nSockTrace = 0; string socketid = client.RemoteEndPoint.ToString(); try { PoolCommon.WorkerInfo wban = PoolCommon.Ban(socketid, .25, "XMR-Connect"); nSockTrace = 1; if (!wban.banned) { PoolCommon.iXMRThreadID++; TcpClient tcp = new TcpClient(); nSockTrace = 2; tcp.Connect(GetBMSConfigurationKeyValue("XMRExternalPool"), (int)GetDouble(GetBMSConfigurationKeyValue("XMRExternalPort"))); nSockTrace = 3; ThreadStart starter = delegate { minerXMRThread(client, tcp, socketid); }; var childSocketThread = new Thread(starter); nSockTrace = 4; PoolCommon.iXMRThreadCount++; nSockTrace = 5; childSocketThread.Start(); nSockTrace = 6; } else { // They are already banned nSockTrace = 7; PoolCommon.CloseSocket(client); } }catch (Exception ex) { Log("We have a big issue answering sockets " + ex.Message + ", sock trace=" + nSockTrace.ToString()); } } } catch (ThreadAbortException) { Log("XMR Pool is going down..."); return; } catch (Exception ex) { Log("InitializeXMRPool v1.3: " + ex.Message); Thread.Sleep(5000); goto retry; } } }
public bool SubmitBiblePayShare(string socketid) { if (_pool._template.height < 300000) { //Chain is still syncing... return(false); } try { XMRJob x = RetrieveXMRJob(socketid); if (x.hash == null || x.hash == "") { Log("SubmitBBPShare::emptyhash", true); return(false); } byte[] oRX = PoolCommon.StringToByteArr(x.hash); double nSolutionDiff = PoolCommon.FullTest(oRX); bool fUnique = PoolCommon.IsUnique(x.hash); string revBBPHash = PoolCommon.ReverseHexString(x.hash); // Check to see if this share actually solved the block: NBitcoin.uint256 uBBP = new NBitcoin.uint256(revBBPHash); NBitcoin.uint256 uTarget = new NBitcoin.uint256(_pool._template.target); NBitcoin.arith256 aBBP = new NBitcoin.arith256(uBBP); NBitcoin.arith256 aTarget = new NBitcoin.arith256(uTarget); int nTest = aBBP.CompareTo(aTarget); if (aBBP.CompareTo(aTarget) == -1) { // We solved the block string poolAddress = GetBMSConfigurationKeyValue("PoolAddress"); string hex = PoolCommon.GetBlockForStratumHex(poolAddress, x.seed, x.solution); bool fSuccess = PoolCommon.SubmitBlock(hex); if (fSuccess) { string sql = "Update Share Set Solved=1 where height=@height"; SqlCommand command = new SqlCommand(sql); command.Parameters.AddWithValue("@height", _pool._template.height); gData.ExecCmd(command, false, false, false); Log("SUBMIT_SUCCESS: Success for nonce " + x.nonce + " at height " + _pool._template.height.ToString() + " hex " + hex, true); } else { Log("SUBMITBLOCK: Tried to submit the block for nonce " + x.nonce + " and target " + _pool._template.target + " with seed " + x.seed + " and solution " + x.solution + " with hex " + hex + " and failed"); } _pool._template.updated = 0; // Forces us to get a new block PoolCommon.GetBlockForStratum(); } else { PoolCommon.GetBlockForStratum(); } try { if (dictJobs.Count > 25000) { dictJobs.Clear(); } } catch (Exception ex1) { Log("cant find the job " + x.socketid.ToString() + ex1.Message); } return(true); } catch (Exception ex) { Log("submitshare::Unable to submit bbp share: " + ex.Message); } return(false); }
private void minerXMRThread(Socket client, TcpClient t, string socketid) { bool fCharity = false; string bbpaddress = String.Empty; string moneroaddress = String.Empty; double nTrace = 0; string sData = String.Empty; string sParseData = String.Empty; int nLastReceived = UnixTimeStamp(); try { client.ReceiveTimeout = 5000; client.SendTimeout = 5000; while (true) { int size = 0; int nElapsed = UnixTimeStamp() - nLastReceived; if (nElapsed > (60 * 60)) { client.Close(); t.Close(); PoolCommon.iXMRThreadCount--; return; } if (!client.Connected) { PoolCommon.iXMRThreadCount--; return; } if (client.Available > 0) { byte[] data = new byte[client.Available]; nLastReceived = UnixTimeStamp(); try { size = client.Receive(data); nTrace = 1; } catch (ThreadAbortException) { return; } catch (Exception ex) { if (ex.Message.Contains("An existing connection was forcibly closed")) { Console.WriteLine("ConnectionClosed"); return; } else if (ex.Message.Contains("was aborted")) { return; } Console.WriteLine("Error occurred while receiving data " + ex.Message); } if (size > 0) { nTrace = 2; sData = Encoding.UTF8.GetString(data, 0, data.Length); sData = sData.Replace("\0", ""); // {"id":107,"jsonrpc":"2.0","method":"submit","params":{"id":"1","job_id":"5","nonce":"08af0200","result":"542 // We are seeing nTrace==2, with a truncation occurring around position 107 having no json terminator: if (sData.Contains("jsonrpc") && sData.Contains("submit") && sData.Contains("params") && sData.Length < 128) { if (sData.Contains("{") && sData.Contains("id") && !sData.Contains("}")) { Log("XMRPool::Received " + socketid + " truncated message. ", true); PoolCommon.iXMRThreadCount--; client.Close(); PoolCommon.WorkerInfo wban = PoolCommon.Ban(socketid, 1, "BAD-CONFIG"); return; } } // The Stratum data is first split by \r\n string[] vData = sData.Split("\n"); for (int i = 0; i < vData.Length; i++) { string sJson = vData[i]; if (sJson.Contains("submit")) { // See if this is a biblepay share: if (PoolCommon.fMonero2000) { sParseData = sJson; JObject oStratum = JObject.Parse(sJson); string nonce = "00000000" + oStratum["params"]["nonce"].ToString(); double nJobID = GetDouble(oStratum["params"]["job_id"].ToString()); string hash = oStratum["params"]["result"].ToString(); XMRJob xmrJob = RetrieveXMRJob(socketid); string rxheader = xmrJob.blob; string rxkey = xmrJob.seed; if (rxheader == null) { //Log("cant find the job " + nJobID.ToString()); PoolCommon.WorkerInfo wban = PoolCommon.Ban(socketid, 1, "CANT-FIND-JOB"); } if (rxheader != null) { nTrace = 4; nonce = nonce.Substring(8, 8); xmrJob.solution = rxheader.Substring(0, 78) + nonce + rxheader.Substring(86, rxheader.Length - 86); xmrJob.hash = oStratum["params"]["result"].ToString(); xmrJob.hashreversed = PoolCommon.ReverseHexString(hash); xmrJob.nonce = nonce; xmrJob.bbpaddress = bbpaddress; xmrJob.moneroaddress = moneroaddress; PutXMRJob(xmrJob); SubmitBiblePayShare(xmrJob.socketid); } } } else if (sJson.Contains("login")) { //{"id":1,"jsonrpc":"2.0","method":"login","params":{"login":"******","pass":"******","agent":"bbprig/5.10.0 (Windows NT 6.1; Win64; x64) libuv/1.34.0 gcc/9.2.0","algo":["cn/0","cn/1","cn/2","cn/r","cn/fast","cn/half","cn/xao","cn/rto","cn/rwz","cn/zls","cn/double","","cn-lite/0","cn-lite/1","cn-heavy/0","cn-heavy/tube","cn-heavy/xhv","cn-pico","cn-pico/tlo","rx/0","rx/wow","rx/loki","rx/arq","rx/sfx","rx/keva","argon2/chukwa","argon2/wrkz","astrobwt"]}} nTrace = 8; sParseData = sJson; if (sJson.Contains("User-Agent:") || sJson.Contains("HTTP/1.1") || sJson.Contains("xmrig-proxy")) { // Someone is trying to connect to the pool with a web browser? (Instead of a miner): if (false) { Log("XMRPool::Received " + socketid + " Web browser Request ", true); } PoolCommon.iXMRThreadCount--; client.Close(); PoolCommon.WorkerInfo wban = PoolCommon.Ban(socketid, 1, "BAD-CONFIG"); return; } JObject oStratum = JObject.Parse(sJson); dynamic params1 = oStratum["params"]; if (PoolCommon.fMonero2000) { moneroaddress = params1["login"].ToString(); bbpaddress = params1["pass"].ToString(); if (bbpaddress.Length != 34 || moneroaddress.Length < 95) { PoolCommon.iXMRThreadCount--; client.Close(); PoolCommon.WorkerInfo wban = PoolCommon.Ban(socketid, 1, "BAD-CONFIG"); return; } WorkerInfo w = PoolCommon.GetWorker(socketid); w.moneroaddress = moneroaddress; w.bbpaddress = bbpaddress; w.IP = GetIPOnly(socketid); PoolCommon.SetWorker(w, socketid); PersistWorker(w); } nTrace = 10; } else if (sJson != "") { Console.WriteLine(sJson); } } // Miner->XMR Pool Stream stmOut = t.GetStream(); stmOut.Write(data, 0, size); } else { if (true) { // Keepalive (prevents the pool from hanging up on the miner) nTrace = 15; var json = "{ \"id\": 0, \"method\": \"keepalived\", \"arg\": \"na\" }\r\n"; data = Encoding.ASCII.GetBytes(json); Stream stmOut = t.GetStream(); stmOut.Write(data, 0, json.Length); } } } // ****************************************** In from XMR Pool -> Miner ******************************************************* nTrace = 16; NetworkStream stmIn = t.GetStream(); nTrace = 18; int bytesIn = 0; try { t.ReceiveTimeout = 5777; t.SendTimeout = 4777; nTrace = 19; if (stmIn.DataAvailable) { byte[] bIn = new byte[65536]; bytesIn = stmIn.Read(bIn, 0, 65536); if (bytesIn > 0) { nTrace = 20; sData = Encoding.UTF8.GetString(bIn, 0, bytesIn); sData = sData.Replace("\0", ""); string[] vData = sData.Split("\n"); for (int i = 0; i < vData.Length; i++) { string sJson = vData[i]; if (sJson.Contains("result")) { WorkerInfo w = PoolCommon.GetWorker(socketid); PoolCommon.SetWorker(w, socketid); JObject oStratum = JObject.Parse(sJson); string status = oStratum["result"]["status"].ToString(); int id = (int)GetDouble(oStratum["id"]); if (id == 1 && status == "OK" && sJson.Contains("blob")) { // BiblePay Pool to Miner nTrace = 22; double nJobId = GetDouble(oStratum["result"]["job"]["job_id"].ToString()); XMRJob x = RetrieveXMRJob(socketid); x.blob = oStratum["result"]["job"]["blob"].ToString(); x.target = oStratum["result"]["job"]["target"].ToString(); x.seed = oStratum["result"]["job"]["seed_hash"].ToString(); x.difficulty = ConvertTargetToDifficulty(x); PutXMRJob(x); } else if (id > 1 && status == "OK") { // They solved an XMR int iCharity = fCharity ? 1 : 0; nTrace = 24; // Weight adjusted share XMRJob x = RetrieveXMRJob(socketid); double nShareAdj = WeightAdjustedShare(x); nDebugCount++; System.Diagnostics.Debug.WriteLine("solved " + nDebugCount.ToString()); PoolCommon.InsShare(bbpaddress, nShareAdj, 0, _pool._template.height, nShareAdj, iCharity, moneroaddress); } else if (id > 1 && status != "OK" && status != "KEEPALIVED") { nTrace = 25; PoolCommon.InsShare(bbpaddress, 0, 1, _pool._template.height, 0, 0, moneroaddress); } } else if (sJson.Contains("submit")) { // Noop } else if (sJson.Contains("\"method\":\"job\"")) { nTrace = 26; JObject oStratum = JObject.Parse(sJson); nTrace = 27; double nJobId = GetDouble(oStratum["params"]["job_id"].ToString()); XMRJob x = RetrieveXMRJob(socketid); nTrace = 27.2; x.blob = oStratum["params"]["blob"].ToString(); nTrace = 27.4; x.target = oStratum["params"]["target"].ToString(); nTrace = 27.5; x.seed = oStratum["params"]["seed_hash"].ToString(); nTrace = 27.6; x.difficulty = ConvertTargetToDifficulty(x); PutXMRJob(x); nTrace = 27.9; } else if (sJson != "") { Console.WriteLine(sJson); } } } // Back to Miner if (bytesIn > 0) { // This goes back to the miner SendXMRPacketToMiner(client, bIn, bytesIn); } } } catch (Exception ex) { if (!ex.Message.Contains("did not properly respond")) { Log("minerXMRThread[0]: Trace=" + nTrace.ToString() + ":" + ex.Message); Ban(socketid, 1, ex.Message.Substring(0, 12)); } } Thread.Sleep(100); } } catch (ThreadAbortException) { // Log("minerXMRThread is going down...", true); return; } catch (Exception ex) { if (ex.Message.Contains("was aborted")) { // Noop } else if (ex.Message.Contains("forcibly closed")) { } else if (!ex.Message.Contains("being aborted")) { // This is where we see Unexpected end of content while loading JObject. Path 'params.job_id', line 1, position 72. // and Unterminated string. Expected delimiter: ". Path 'params.result', line 1, position 144. // Invalid character after parsing property name. Expected ':' but got: // and Unterminated string. Expected delimiter: ". Path 'params.id', line 1, position 72. Log("minerXMRThread2 v2.1: " + ex.Message + " [sdata=" + sData + "], Trace=" + nTrace.ToString() + ", PARSEDATA \r\n" + sParseData); } } PoolCommon.iXMRThreadCount = iXMRThreadCount - 1; }