public void PublishTxResponse(List <Envelope> errorTx, string errorMsg) { if (errorTx.Count == 0) { return; } var channelId = errorTx.First().TxReqeust.Header.ChannelId; //factory.UserName = user; //factory.Password = pass; //factory.VirtualHost = 虚拟主机; using (var connection = _factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.ExchangeDeclare("channel", ExchangeType.Direct, true, false, null); //channel.QueueDeclare(channelId, true, false, false, null); //channel.QueueBind(channelId, "channel", "", null); foreach (var item in errorTx) { var response = new TxResponse(); response.ChannelId = channelId; response.Status = false; response.Msg = errorMsg; response.TxId = item.TxReqeust.Data.TxId; response.Data = item.PayloadReponse.Message; var body = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(response)); channel.BasicPublish(channelId, response.TxId, null, body); } } }
/// <summary> /// 推送交易结果 /// </summary> public void PublishTxResponse(QMBlockSDK.Ledger.Block block, string errorMsg) { if (string.IsNullOrEmpty(errorMsg)) { using (var connection = _factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: block.Header.ChannelId, ExchangeType.Direct, true, false, null); //channel.QueueDeclare("txchannel", true, false, false, null); foreach (var item in block.Data.Envelopes) { var response = new TxResponse { ChannelId = block.Header.ChannelId, Status = true, Msg = "上链成功", TxId = item.TxReqeust.Data.TxId, Data = item.PayloadReponse.Message, BlockNumber = block.Header.Number, BlockDataHash = block.Header.DataHash, BlockTimestamp = block.Header.Timestamp }; var body = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(response)); channel.BasicPublish(block.Header.ChannelId, item.TxReqeust.Header.TxHeaderId, null, body); } } } else { PublishTxResponse(block.Data.Envelopes, errorMsg); } }
public Task <TxResponse> Transaction(TxRequest request) { var response = new TxResponse() { Msg = "follower拒绝服务", Status = false }; return(Task.FromResult(response)); }
private async Task <TxResponse> ListenTx(TxHeader txHeader) { var factory = new ConnectionFactory() { HostName = "localhost" }; return(await Task.Run(() => { var status = false; TxResponse response = null; using (var connection = factory.CreateConnection()) using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(txHeader.ChannelId, ExchangeType.Direct, true, false, null); var queueName = channel.QueueDeclare().QueueName; channel.QueueBind(queueName, txHeader.ChannelId, txHeader.TxHeaderId); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { try { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); Console.WriteLine(message); response = Newtonsoft.Json.JsonConvert.DeserializeObject <TxResponse>(message); } catch (Exception ex) { response = new TxResponse { Status = false, Msg = "反序列化TxResponse失败" }; _logger.LogError(ex, ex.Message); } finally { status = true; } }; channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer); while (true) { if (status) { return response; } System.Threading.Thread.Sleep(200); } } })); }
/// <summary> /// 如果是查询交易 直接返回本地查询结果 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task <TxResponse> TransactionCommit(TxRequest request) { ///如果是查询获取本地的结果就行并且不用背书 if (request.Data.Type == TxType.Query) { var rs = await ChainCodeSubmit(request); var response = new TxResponse(); response.Msg = rs.Message; response.Status = rs.StatusCode == StatusCode.Successful; if (!response.Status) { response.Msg += "||" + rs.StatusCode.ToString(); } response.Data = rs.Data; return(response); } //转发交易 return(await State.TranspondTx(request)); }
private async Task FaucetProcessMessage(Message m) { var chat = m.Chat; var userId = m.From.Id; var text = (m.Text?.Trim() ?? "").Trim('\'', '"', '`', '*', '[', ']'); var args = text.Split(" "); var cliArgs = CLIHelper.GetNamedArguments(args); await _TBC.SendChatActionAsync(chat, ChatAction.Typing); //simulate keystrokes var token = args.TryGetValueOrDefault(2)?.TrimStartSingle("$"); // $ATOM if (token?.ToLower() == "kex" && Environment.GetEnvironmentVariable($"{token?.ToLower()}_PROPS").IsNullOrWhitespace()) { await _TBC.SendTextMessageAsync(chatId : chat, $"That one's comming 🔜 😉", replyToMessageId : m.MessageId, parseMode : ParseMode.Default); return; } if (!await this.CheckMasterChatMembership(m)) { return; } if (await GetDeposit(m)) { return; } var props = await GetTokenFaucetProps(m); if (props == null) //failed to read properties { return; } var acc = new AsmodatStandard.Cryptography.Cosmos.Account(props.prefix, (uint)props.index); acc.InitializeWithMnemonic(_mnemonic.Release()); var cosmosAdress = acc.CosmosAddress; TxResponse txResponse = null; Account accountInfo = null; Token accountBalance = null; long faucetTokenBalance = 0; var notEnoughFunds = false; var client = new CosmosHub(lcd: props.lcd, timeoutSeconds: _cosmosHubClientTimeout); if (props.address != cosmosAdress) { try { var userAccountInfo = await client.GetAccount(account : props.address); var userAccountBalance = userAccountInfo?.coins?.FirstOrDefault(x => x?.denom?.ToLower() == props.denom); var userBalance = (userAccountBalance?.amount ?? "0").ToBigIntOrDefault(0); if (userBalance >= props.amount) { await _TBC.SendTextMessageAsync(text : $"Your account balance exceeds `{props.amount} {props.denom}`", chatId : new ChatId(m.Chat.Id), replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return; } props.amount = props.amount - userBalance; //only send difference up to max amount } catch (Exception ex) { _logger.Log($"[ERROR] => Filed to fetch '{props.denom ?? "undefined"}' balance of '{props.address ?? "undefined"}' from '{props.lcd ?? "undefined"}': '{ex.JsonSerializeAsPrettyException(Newtonsoft.Json.Formatting.Indented)}'"); } } var sequenceKey = $"{cosmosAdress}-{props.network}"; await _ssLocker.Lock(async() => { accountInfo = await client.GetAccount(account: cosmosAdress); accountBalance = accountInfo?.coins?.FirstOrDefault(x => x?.denom?.ToLower() == props.denom.ToLower()); faucetTokenBalance = (accountBalance?.amount).ToLongOrDefault(0); if (faucetTokenBalance < (props.amount + props.fees)) { notEnoughFunds = true; return; } var sequence = accountInfo.sequence.ToLongOrDefault(); var oldSeque = sequences.GetValueOrDefault(sequenceKey, -1); sequences[sequenceKey] = Math.Max(sequence, oldSeque + 1); accountInfo.sequence = sequences[sequenceKey].ToString(); }); if (notEnoughFunds) { await _TBC.SendTextMessageAsync(chatId : chat, $"Faucet does not have enough `{props.denom ?? "undefined"}` tokens ({faucetTokenBalance}) or coin index ({props.index}) is invalid.\n\n" + $"Network Id: `{props.network ?? "undefined"}`\n" + $"Faucet Public Address: `{cosmosAdress}`", replyToMessageId : m.MessageId, parseMode : Telegram.Bot.Types.Enums.ParseMode.Markdown); return; } var doc = await client.CreateMsgSend( account : accountInfo, to : props.address, amount : props.amount, denom : accountBalance?.denom ?? props.denom, fees : props.fees, gas : props.gas, memo : props.memo ?? "Kira Interchain Faucet - Join us at https://t.me/kirainterex"); var tx = doc.CreateTx(acc); txResponse = await client.PostTx(tx); var inviteLink = await GetMasterChatInviteLink(); string debugLog = null; if (text.Contains("--debug")) { debugLog = $"\nDebug Log: {txResponse?.raw_log}"; } if (txResponse == null || txResponse.height.ToLongOrDefault(0) <= 0 || !txResponse.error.IsNullOrWhitespace()) { await _TBC.SendTextMessageAsync(chatId : chat, $"*Failed* 😢 sending `{props.amount} {props.denom}` to {m.From.GetMarkDownUsername()} ❌\n" + $"Debug Log: `{txResponse?.raw_log ?? txResponse?.error}`\n" + $"Network Id: `{props?.network ?? "undefined"}`\n" + $"Sequence: `{accountInfo?.sequence}`\n" + $"Tx Hash: `{txResponse?.txhash}`", replyToMessageId : m.MessageId, parseMode : ParseMode.Markdown); sequences[sequenceKey] = sequences.GetValueOrDefault(sequenceKey, -1) - 1; } else { await _TBC.SendTextMessageAsync(chatId : chat, $"*SUCCESS* 😄 {inviteLink} sent you `{props.amount} {props.denom}` 💸\n" + $"{debugLog}\n" + $"Network Id: `{props.network ?? "undefined"}`\n" + $"Tx Hash: `{txResponse.txhash}`", replyToMessageId : m.MessageId, parseMode : ParseMode.Markdown); } }
/// <summary> /// 将交易发给需要背书的背书节点 /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task <TxResponse> Transaction(TxRequest request) { var requestData = request.Data; var txResponse = new TxResponse(); //获取链码配置中的背书节点, var peers = _configProviders.GetEndorsePeer(requestData.Channel.Chaincode); var taskList = new Dictionary <string, Task <EndorseResponse> >(); var endorseDir = new Dictionary <string, EndorseResponse>(); var endorseRequest = new EndorseRequest { ChannelId = request.Header.ChannelId, Request = request }; //添加背书task foreach (var item in peers) { if (item.Id == CurrentState.Id) { taskList.Add(item.Id, Endorse(request)); } else { taskList.Add(item.Id, item.Endorse(endorseRequest)); } } var txResult = false; var count = 0; while (true) { taskList = taskList.Where(p => !endorseDir.ContainsKey(p.Key)).ToDictionary(p => p.Key, p => p.Value); //如果没有进行过背书 则返回false if (taskList.Count() == 0) { txResponse.Msg = "不满足背书策略"; break; } foreach (var item in taskList) { if (item.Value.IsCompleted) { endorseDir.Add(item.Key, await item.Value); } } ///验证背书策略 var rs = _configProviders.ValidateEndorse(requestData.Channel.Chaincode, endorseDir); if (rs) { txResult = true; break; } Thread.Sleep(20); if (count * 20 > _configProviders.GetEndorseTimeOut()) { txResponse.Msg = "背书超时"; break; } } //如果背书策略通过 if (txResult) { //交易封装对象 交易头 背书结果 背书签名 var envelopr = new Envelope { TxReqeust = request }; var endorses = endorseDir.Select(p => p.Value).ToList(); foreach (var item in endorses) { //将背书结果赋值给交易信封 只需要赋值一次 if (envelopr.PayloadReponse.Status == false) { envelopr.PayloadReponse.Status = item.Status; envelopr.PayloadReponse.Message = item.Msg; envelopr.PayloadReponse.TxReadWriteSet = item.TxReadWriteSet; } envelopr.Endorsements.Add(item.Endorsement); } //交易加入交易池中 _node.TxPool.Add(envelopr); return(new TxResponse() { Status = true, Msg = "等待上链", TxId = request.Data.TxId }); /* * //var statusRs = await _node.TxPool.TxStatus(envelopr.TxReqeust.Data.TxId); * if (statusRs == "0") * { * txResponse.Status = true; * txResponse.Msg = "上链成功"; * } * if (statusRs == "1") * { * txResponse.Status = false; * txResponse.Msg = "上链失败"; * } * if (statusRs == "2") * { * txResponse.Status = true; * txResponse.Msg = "服务器忙"; * } */ //return txResponse; } else { //失败的 var errorTx = endorseDir.Where(p => p.Value.Status == false).Select(p => p.Key + ":" + p.Value.Msg).ToList(); txResponse.Msg = "背书失败"; txResponse.Data = errorTx; txResponse.Status = false; txResponse.TxId = request.Data.TxId; return(txResponse); } }