/// <summary>
        /// check cur block number should be cache ?
        /// if block is new just by pass
        /// </summary>
        /// <param name="chainid"></param>
        /// <param name="req"></param>
        /// <returns></returns>
        private static bool Check_eth_getBlockByNumber(int chainid, JsonRpcClientReq req)
        {
            if (req.Params.Length != 2)
            {
                return(false);
            }

            if (!BigInteger.TryParse(req.Params[0].ToString().Replace("0x", ""), out BigInteger result))
            {
                return(false);
            }

            var nodes = NodeChecker.Instance.FindCheckerByChainId(chainid);

            if (nodes.Count == 0)
            {
                return(false);
            }

            var first = nodes.OrderByDescending(n => n.GetBlockNumber()).First();

            var curBlockCount = first.GetBlockNumber();
            var i             = Startup.GetConfig <int>("Cache.Eth_IrrevocableBlockCount");

            if (result + i < curBlockCount)
            {
                return(true);
            }

            return(false);
        }
        public static bool EthCacheFilter(int chainid, JsonRpcClientReq req, string result)
        {
            switch (req.Method)
            {
            case "eth_getBlockByNumber":
                return(Check_eth_getBlockByNumber(chainid, req));
            }

            return(false);
        }
示例#3
0
        private async Task <(bool result, string response)> SendRequest(JsonRpcClientReq req, string rpc)
        {
            try {
                using (var client = new HttpClient()) {
                    var resp = await client.PostAsync(rpc,
                                                      new StringContent(
                                                          Newtonsoft.Json.JsonConvert.SerializeObject(req),
                                                          Encoding.UTF8,
                                                          "application/json"));

                    if (!resp.IsSuccessStatusCode)
                    {
                        return(false, await resp.Content.ReadAsStringAsync());
                    }

                    return(true, await resp.Content.ReadAsStringAsync());
                }
            } catch (Exception ex) {
                Logger.Error(ex);
                return(false, ex.Message);
            }
        }
示例#4
0
        public bool AddCache(int chainid, JsonRpcClientReq req, string result)
        {
            if (!EthCacheConfig.Methods.ContainsKey(req.Method))
            {
                return(false);
            }

            var config = EthCacheConfig.Methods[req.Method];

            switch (config.RpcCacheStrategy)
            {
            case RpcCacheStrategy.NotCache:
                break;

            case RpcCacheStrategy.CacheInMemory:
                RedisHelper.Instance.AddRpcCache(chainid,
                                                 req.Method, config.ParamDelegate?.Invoke(req),
                                                 result, config.CacheOption > 0 ? TimeSpan.FromSeconds(config.CacheOption): TimeSpan.Zero);
                break;

            case RpcCacheStrategy.CacheInDb:

                if (config.FilterDelegate?.Invoke(chainid, req, result) == false)
                {
                    Logger.Debug($"{req} cache skip");
                    return(false);
                }

                DbMgr.Instance.AddRpcCache(chainid,
                                           req.Method, config.ParamDelegate?.Invoke(req),
                                           result, config.CacheOption > 0 ? TimeSpan.FromSeconds(config.CacheOption): TimeSpan.Zero);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(true);
        }
示例#5
0
 public static string EmptyParams(JsonRpcClientReq req)
 {
     return(string.Empty);
 }
示例#6
0
 public static string StringSplitParam(JsonRpcClientReq req)
 {
     return(string.Join("|", req.Params));
 }
示例#7
0
        public async Task <IActionResult> Post(JsonRpcClientReq req, int chainid = 0)
        {
            if (chainid == 0)
            {
                return(BadRequest("chainid error"));
            }

            switch (req.Method)
            {
            case "eth_sendRawTransaction": {
                var signer = new TransactionSigner();

                var addr = signer.GetSenderAddress(req.Params[0].ToString());
                var rpc  = NodeChoose.ChooseServer(chainid, addr);

                if (string.IsNullOrEmpty(rpc))
                {
                    return(BadRequest("not find suitable rpc server"));
                }

                var sendResult = await SendRequest(req, rpc);

                if (sendResult.result)
                {
                    return(new ContentResult()
                        {
                            Content = sendResult.response,
                            ContentType = "application/json",
                            StatusCode = 200
                        });
                }
                return(BadRequest(sendResult.response));
            }

            default: {
                var cache = EthRpcCache.Instance.CheckCache(chainid, req);
                if (cache.hasCache)
                {
                    Logger.Debug($"{req} in cache");

                    //update resp id
                    var respObj = JObject.Parse(cache.result);
                    respObj["id"]    = req.Id;
                    respObj["cache"] = cache.strategy.ToString();

                    return(new ContentResult()
                        {
                            Content = respObj.ToString(Formatting.None),
                            ContentType = "application/json",
                            StatusCode = 200
                        });
                }

                var rpc = NodeChoose.ChooseServer(chainid);
                if (string.IsNullOrEmpty(rpc))
                {
                    return(BadRequest("not find suitable rpc server"));
                }

                var sendResult = await SendRequest(req, rpc);

                if (sendResult.result)
                {
                    var respObj = JObject.Parse(sendResult.response);

                    switch (cache.strategy)
                    {
                    case RpcCacheStrategy.NotCache:
                        break;

                    case RpcCacheStrategy.CacheInMemory:
                    case RpcCacheStrategy.CacheInDb:
                        var cacheResult = EthRpcCache.Instance.AddCache(chainid, req, sendResult.response);
                        respObj["cacheOption"] = cache.strategy.ToString();
                        respObj["cacheResult"] = cacheResult;
                        break;
                    }
                    return(new ContentResult()
                        {
                            Content = respObj.ToString(Formatting.None),
                            ContentType = "application/json",
                            StatusCode = 200
                        });
                }

                return(BadRequest(sendResult.response));
            }
            }
        }
示例#8
0
        public (bool hasCache, string result, RpcCacheStrategy strategy) CheckCache(int chainid, JsonRpcClientReq req)
        {
            if (!EthCacheConfig.Methods.ContainsKey(req.Method))
            {
                return(false, string.Empty, RpcCacheStrategy.NotCache);
            }

            var config = EthCacheConfig.Methods[req.Method];

            switch (config.RpcCacheStrategy)
            {
            case RpcCacheStrategy.NotCache:
                return(false, string.Empty, config.RpcCacheStrategy);

            case RpcCacheStrategy.CacheInMemory: {
                {
                    var checkCache = RedisHelper.Instance.GetRpcCache(chainid, req.Method, config.ParamDelegate?.Invoke(req));
                    return(checkCache.hasCache, checkCache.result, config.RpcCacheStrategy);
                }
            }

            case RpcCacheStrategy.CacheInDb: {
                var checkCache = Db.DbMgr.Instance.GetRpcCache(chainid, req.Method, config.ParamDelegate?.Invoke(req));
                return(checkCache.hasCache, checkCache.result, config.RpcCacheStrategy);
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }