Пример #1
0
        public async Task GetResource_Test()
        {
            var transaction = new Transaction
            {
                From       = Address.Generate(),
                To         = Address.Generate(),
                Params     = ByteString.CopyFromUtf8("test"),
                MethodName = "TestMethod"
            };
            var result = await _resourceUsageDetectionService.GetResources(transaction);

            result.Count().ShouldBe(2);
            result.Contains($"test1.{transaction.From.GetFormatted()}").ShouldBeTrue();
            result.Contains("test2");
        }
Пример #2
0
        //TODO: for testnet we only have a single chain, thus grouper only take care of txList in one chain (hence Process has chainId as parameter)
        public async Task <Tuple <List <List <Transaction> >, Dictionary <Transaction, Exception> > > ProcessNaive(int chainId, List <Transaction> transactions)
        {
            var txResourceHandle = new Dictionary <Transaction, string>();
            var failedTxs        = new Dictionary <Transaction, Exception>();

            if (transactions.Count == 0)
            {
                return(new Tuple <List <List <Transaction> >, Dictionary <Transaction, Exception> >(new List <List <Transaction> >(), failedTxs));
            }

            Dictionary <string, UnionFindNode> resourceUnionSet = new Dictionary <string, UnionFindNode>();

            //set up the union find set as the representation of graph and the connected components will be the resulting groups
            foreach (var tx in transactions)
            {
                UnionFindNode first = null;
                List <string> resources;
                try
                {
                    resources = (await _resourceUsageDetectionService.GetResources(tx)).ToList();
                }
                catch (Exception e)
                {
                    failedTxs.Add(tx, e);
                    continue;
                }

                //Logger.LogDebug(string.Format("tx {0} have resource [{1}]", tx.From, string.Join(" ||| ", resources)));
                foreach (var resource in resources)
                {
                    if (!resourceUnionSet.TryGetValue(resource, out var node))
                    {
                        node = new UnionFindNode();
                        resourceUnionSet.Add(resource, node);
                    }
                    if (first == null)
                    {
                        first = node;
                        txResourceHandle.Add(tx, resource);
                    }
                    else
                    {
                        node.Union(first);
                    }
                }
            }

            Dictionary <int, List <Transaction> > grouped = new Dictionary <int, List <Transaction> >();
            List <List <Transaction> >            result  = new List <List <Transaction> >();

            foreach (var tx in transactions)
            {
                if (txResourceHandle.TryGetValue(tx, out var firstResource))
                {
                    int nodeId = resourceUnionSet[firstResource].Find().NodeId;
                    if (!grouped.TryGetValue(nodeId, out var group))
                    {
                        group = new List <Transaction>();
                        grouped.Add(nodeId, group);
                    }
                    group.Add(tx);
                }
                else
                {
                    if (!failedTxs.ContainsKey(tx))
                    {
                        //each "resource-free" transaction have its own group
                        result.Add(new List <Transaction>()
                        {
                            tx
                        });
                    }
                }
            }
            result.AddRange(grouped.Values);

            Logger.LogInformation(string.Format(
                                      "Grouper on chainId \"{0}\" group [{1}] transactions into [{2}] groups with sizes [{3}], There are also {4} transactions failed retriving resource", ChainHelpers.ConvertChainIdToBase58(chainId),
                                      transactions.Count, result.Count, string.Join(", ", result.Select(a => a.Count)), failedTxs.Count));

            return(new Tuple <List <List <Transaction> >, Dictionary <Transaction, Exception> >(result, failedTxs));
        }