public void SubmitSolution(string digest, string fromAddress, string challenge, string difficulty, string target, string solution, Miner.IMiner sender) { lock (this) { if (m_submittedChallengeList.Contains(challenge)) { Program.Print(string.Format("[INFO] Submission cancelled, nonce has been submitted for the current challenge.")); return; } var transactionID = string.Empty; var gasLimit = new HexBigInteger(1704624ul); var userGas = new HexBigInteger(UnitConversion.Convert.ToWei(new BigDecimal(m_gasToMine), UnitConversion.EthUnit.Gwei)); var oSolution = new BigInteger(Utils.Numerics.HexStringToByte32Array(solution).ToArray()); // Note: do not directly use -> new HexBigInteger(solution).Value //Because two's complement representation always interprets the highest-order bit of the last byte in the array //(the byte at position Array.Length- 1) as the sign bit, //the method returns a byte array with an extra element whose value is zero //to disambiguate positive values that could otherwise be interpreted as having their sign bits set. var dataInput = new object[] { oSolution, HexByteConvertorExtensions.HexToByteArray(digest) }; var retryCount = 0u; while (string.IsNullOrWhiteSpace(transactionID)) { try { var txCount = m_web3.Eth.Transactions.GetTransactionCount.SendRequestAsync(fromAddress).Result; var estimatedGasLimit = m_mintMethod.EstimateGasAsync(from: fromAddress, gas: gasLimit, value: new HexBigInteger(0), functionInput: dataInput).Result; var transaction = m_mintMethod.CreateTransactionInput(from: fromAddress, gas: estimatedGasLimit, gasPrice: userGas, value: new HexBigInteger(0), functionInput: dataInput); var encodedTx = Web3.OfflineTransactionSigner.SignTransaction(privateKey: m_account.PrivateKey, to: m_contract.Address, amount: 0, nonce: txCount.Value, gasPrice: userGas, gasLimit: estimatedGasLimit, data: transaction.Data); if (!Web3.OfflineTransactionSigner.VerifyTransaction(encodedTx)) { throw new Exception("Failed to verify transaction."); } transactionID = m_web3.Eth.Transactions.SendRawTransaction.SendRequestAsync("0x" + encodedTx).Result; if (!string.IsNullOrWhiteSpace(transactionID)) { if (!m_submittedChallengeList.Contains(challenge)) { m_submittedChallengeList.Insert(0, challenge); if (m_submittedChallengeList.Count > 100) { m_submittedChallengeList.Remove(m_submittedChallengeList.Last()); } } Task.Factory.StartNew(() => GetTransactionReciept(transactionID, fromAddress, gasLimit, userGas)); } } catch (AggregateException ex) { var errorMessage = "[ERROR] " + ex.Message; foreach (var iEx in ex.InnerExceptions) { errorMessage += "\n " + iEx.Message; } Program.Print(errorMessage); if (m_submittedChallengeList.Contains(challenge)) { return; } } catch (Exception ex) { var errorMessage = "[ERROR] " + ex.Message; if (ex.InnerException != null) { errorMessage += "\n " + ex.InnerException.Message; } Program.Print(errorMessage); if (m_submittedChallengeList.Contains(challenge) || ex.Message == "Failed to verify transaction.") { return; } } System.Threading.Thread.Sleep(1000); if (string.IsNullOrWhiteSpace(transactionID)) { retryCount++; } if (retryCount > 10) { Program.Print("[ERROR] Failed to submit solution for more than 10 times, please check settings."); sender.StopMining(); } } } }
private MiningParameters(string ethAddress, Function getMiningDifficulty, Function getMiningTarget, Function getChallengeNumber) { EthAddress = ethAddress; var retryCount = 0; var exceptions = new List <Exception>(); while (retryCount < 10) { try { MiningDifficulty = new HexBigInteger(getMiningDifficulty.CallAsync <BigInteger>().Result); break; } catch (AggregateException ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex.InnerExceptions[0]); } else { Task.Delay(200).Wait(); } } catch (Exception ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex); } } } while (retryCount < 10) { try { MiningTarget = new HexBigInteger(getMiningTarget.CallAsync <BigInteger>().Result); MiningTargetByte32 = Utils.Numerics.FilterByte32Array(MiningTarget.Value.ToByteArray(littleEndian: false)); MiningTargetByte32String = Utils.Numerics.BigIntegerToByte32HexString(MiningTarget.Value); break; } catch (AggregateException ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex.InnerExceptions[0]); } else { Task.Delay(200).Wait(); } } catch (Exception ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex); } else { Task.Delay(200).Wait(); } } } while (retryCount < 10) { try { ChallengeNumberByte32 = Utils.Numerics.FilterByte32Array(getChallengeNumber.CallAsync <byte[]>().Result); ChallengeNumber = new HexBigInteger(HexByteConvertorExtensions.ToHex(ChallengeNumberByte32, prefix: true)); ChallengeNumberByte32String = Utils.Numerics.BigIntegerToByte32HexString(ChallengeNumber.Value); break; } catch (AggregateException ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex.InnerExceptions[0]); } else { Task.Delay(200).Wait(); } } catch (Exception ex) { retryCount++; if (retryCount == 10) { exceptions.Add(ex); } else { Task.Delay(200).Wait(); } } } var exMessage = string.Join(Environment.NewLine, exceptions.Select(ex => ex.Message)); if (exceptions.Any()) { throw new Exception(exMessage); } }