Ejemplo n.º 1
0
        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);
                    }
                }
        }
Ejemplo n.º 2
0
 /// <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);
     }
 }
Ejemplo n.º 3
0
        public Task <TxResponse> Transaction(TxRequest request)
        {
            var response = new TxResponse()
            {
                Msg = "follower拒绝服务", Status = false
            };

            return(Task.FromResult(response));
        }
Ejemplo n.º 4
0
        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);
                        }
                    }
            }));
        }
Ejemplo n.º 5
0
        /// <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));
        }
Ejemplo n.º 6
0
        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);
            }
        }
Ejemplo n.º 7
0
        /// <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);
            }
        }