Пример #1
0
        public async Task <SDChaindcode> DiscoverEndorserEndpointAsync(TransactionContext tContext, string name, CancellationToken token = default(CancellationToken))
        {
            Dictionary <string, SDChaindcode> lchaindcodeMap = chaindcodeMap;
            // check if we have it already.
            SDChaindcode sd = lchaindcodeMap?.GetOrNull(name);

            if (sd != null)
            {
                return(sd);
            }
            ServiceDiscoveryChaincodeCalls        serviceDiscoveryChaincodeCalls = new ServiceDiscoveryChaincodeCalls(name);
            List <ServiceDiscoveryChaincodeCalls> cc = new List <ServiceDiscoveryChaincodeCalls>();

            cc.Add(serviceDiscoveryChaincodeCalls);
            List <List <ServiceDiscoveryChaincodeCalls> > ccl = new List <List <ServiceDiscoveryChaincodeCalls> >();

            ccl.Add(cc);
            Dictionary <string, SDChaindcode> dchaindcodeMap = await DiscoverEndorserEndpointsAsync(tContext, ccl, token).ConfigureAwait(false);

            SDChaindcode sdChaindcode = dchaindcodeMap.GetOrNull(name);

            if (null == sdChaindcode)
            {
                throw new ServiceDiscoveryException($"Failed to find and endorsers for chaincode {name}. See logs for details");
            }
            return(sdChaindcode);
        }
Пример #2
0
        public async Task <Dictionary <string, SDChaindcode> > DiscoverEndorserEndpointsAsync(TransactionContext tContext, List <List <ServiceDiscoveryChaincodeCalls> > chaincodeNames, CancellationToken token = default(CancellationToken))
        {
            if (null == chaincodeNames)
            {
                logger.Warn("Discover of chaincode names was null.");
                return(new Dictionary <string, SDChaindcode>());
            }

            if (chaincodeNames.Count == 0)
            {
                logger.Warn("Discover of chaincode names was empty.");
                return(new Dictionary <string, SDChaindcode>());
            }

            if (IS_DEBUG_LEVEL)
            {
                StringBuilder cns = new StringBuilder(1000);
                string        sep = "";
                cns.Append("[");
                foreach (List <ServiceDiscoveryChaincodeCalls> s in chaincodeNames)
                {
                    ServiceDiscoveryChaincodeCalls n = s[0];
                    cns.Append(sep).Append(n.Write(s.GetRange(1, s.Count - 1)));
                    sep = ", ";
                }

                cns.Append("]");
                logger.Debug($"Channel {channelName} doing discovery for chaincodes: {cns}");
            }

            List <Peer> speers = serviceDiscoveryPeers.Shuffle().ToList();
            Dictionary <string, SDChaindcode> ret = new Dictionary <string, SDChaindcode>();

            sdNetwork = await NetworkDiscoveryAsync(tContext, false, token).ConfigureAwait(false);

            token.ThrowIfCancellationRequested();
            ServiceDiscoveryException serviceDiscoveryException = null;

            foreach (Peer serviceDiscoveryPeer in speers)
            {
                serviceDiscoveryException = null;
                try
                {
                    logger.Debug($"Channel {channelName} doing discovery for chaincodes on peer: {serviceDiscoveryPeer}");
                    TransactionContext ltransactionContext        = tContext.RetryTransactionSameContext();
                    byte[]             clientTLSCertificateDigest = serviceDiscoveryPeer.GetClientTLSCertificateDigest();
                    if (null == clientTLSCertificateDigest)
                    {
                        logger.Warn($"Channel {channelName} peer {serviceDiscoveryPeer} requires mutual tls for service discovery.");
                        continue;
                    }

                    ByteString clientIdent    = ltransactionContext.Identity.ToByteString();
                    ByteString tlshash        = ByteString.CopyFrom(clientTLSCertificateDigest);
                    AuthInfo   authentication = new AuthInfo();
                    authentication.ClientIdentity    = clientIdent;
                    authentication.ClientTlsCertHash = tlshash;
                    List <Query> fq = new List <Query>(chaincodeNames.Count);
                    foreach (List <ServiceDiscoveryChaincodeCalls> chaincodeName in chaincodeNames)
                    {
                        if (ret.ContainsKey(chaincodeName[0].Name))
                        {
                            continue;
                        }

                        List <ChaincodeCall> chaincodeCalls = new List <ChaincodeCall>();
                        chaincodeName.ForEach(serviceDiscoveryChaincodeCalls => chaincodeCalls.Add(serviceDiscoveryChaincodeCalls.Build()));
                        List <ChaincodeInterest> cinn = new List <ChaincodeInterest>(1);
                        //chaincodeName.ForEach(ServiceDiscoveryChaincodeCalls.Build);
                        ChaincodeInterest cci = new ChaincodeInterest();
                        cci.Chaincodes.Add(chaincodeCalls);
                        cinn.Add(cci);
                        ChaincodeQuery chaincodeQuery = new ChaincodeQuery();
                        chaincodeQuery.Interests.AddRange(cinn);
                        Query q = new Query();
                        q.Channel = channelName;
                        q.CcQuery = chaincodeQuery;
                        fq.Add(q);
                    }

                    if (fq.Count == 0)
                    {
                        //this would be odd but lets take care of it.
                        break;
                    }

                    Request request = new Request();
                    request.Queries.AddRange(fq);
                    request.Authentication = authentication;
                    ByteString    payloadBytes   = request.ToByteString();
                    ByteString    signatureBytes = ltransactionContext.SignByteStrings(payloadBytes);
                    SignedRequest sr             = new SignedRequest();
                    sr.Payload   = payloadBytes;
                    sr.Signature = signatureBytes;
                    if (IS_TRACE_LEVEL && null != diagnosticFileDumper) // dump protobuf we sent
                    {
                        logger.Trace($"Service discovery channel {channelName} {serviceDiscoveryPeer} service chaincode query sent {diagnosticFileDumper.CreateDiagnosticProtobufFile(sr.ToByteArray())}");
                    }
                    logger.Debug($"Channel {channelName} peer {serviceDiscoveryPeer} sending chaincode query request");
                    Response response = await serviceDiscoveryPeer.SendDiscoveryRequestAsync(sr, SERVICE_DISCOVERY_WAITTIME, token).ConfigureAwait(false);

                    if (IS_TRACE_LEVEL && null != diagnosticFileDumper) // dump protobuf we get
                    {
                        logger.Trace($"Service discovery channel {channelName} {serviceDiscoveryPeer} query returned {diagnosticFileDumper.CreateDiagnosticProtobufFile(response.ToByteArray())}");
                    }
                    logger.Debug($"Channel {channelName} peer {serviceDiscoveryPeer} completed chaincode query request");
                    //serviceDiscoveryPeer.HasConnected();
                    foreach (QueryResult queryResult in response.Results)
                    {
                        if (queryResult.ResultCase == QueryResult.ResultOneofCase.Error)
                        {
                            ServiceDiscoveryException discoveryException = new ServiceDiscoveryException($"Error {queryResult.Error.Content}");
                            logger.Error(discoveryException.Message);
                            continue;
                        }

                        if (queryResult.ResultCase != QueryResult.ResultOneofCase.CcQueryRes)
                        {
                            ServiceDiscoveryException discoveryException = new ServiceDiscoveryException($"Error expected chaincode endorsement query but got {queryResult.ResultCase.ToString()}");
                            logger.Error(discoveryException.Message);
                            continue;
                        }

                        ChaincodeQueryResult ccQueryRes = queryResult.CcQueryRes;
                        if (ccQueryRes.Content.Count == 0)
                        {
                            throw new ServiceDiscoveryException($"Error {queryResult.Error.Content}");
                        }

                        foreach (EndorsementDescriptor es in ccQueryRes.Content)
                        {
                            string          chaincode = es.Chaincode;
                            List <SDLayout> layouts   = new List <SDLayout>();
                            foreach (Layout layout in es.Layouts)
                            {
                                SDLayout sdLayout = null;
                                Dictionary <string, uint> quantitiesByGroupMap = layout.QuantitiesByGroup.ToDictionary(a => a.Key, a => a.Value);
                                foreach (string key in quantitiesByGroupMap.Keys)
                                {
                                    uint quantity = quantitiesByGroupMap[key];
                                    if (quantity < 1)
                                    {
                                        continue;
                                    }

                                    Peers peers = es.EndorsersByGroups.GetOrNull(key);
                                    if (peers == null || peers.Peers_.Count == 0)
                                    {
                                        continue;
                                    }

                                    List <SDEndorser> sdEndorsers = new List <SDEndorser>();

                                    foreach (Protos.Discovery.Peer pp in peers.Peers_)
                                    {
                                        SDEndorser ppp      = new SDEndorser(channel, pp, null, null);
                                        string     endPoint = ppp.Endpoint;
                                        SDEndorser nppp     = sdNetwork.GetEndorserByEndpoint(endPoint);
                                        if (null == nppp)
                                        {
                                            sdNetwork = await NetworkDiscoveryAsync(tContext, true, token).ConfigureAwait(false);

                                            if (null == sdNetwork)
                                            {
                                                throw new ServiceDiscoveryException("Failed to discover network resources.");
                                            }

                                            nppp = sdNetwork.GetEndorserByEndpoint(ppp.Endpoint);
                                            if (null == nppp)
                                            {
                                                throw new ServiceDiscoveryException($"Failed to discover peer endpoint information {ppp.Endpoint} for chaincode {chaincode}");
                                            }
                                        }

                                        sdEndorsers.Add(nppp);
                                    }

                                    if (sdLayout == null)
                                    {
                                        sdLayout = new SDLayout();
                                        layouts.Add(sdLayout);
                                    }

                                    sdLayout.AddGroup(key, (int)quantity, sdEndorsers);
                                }
                            }

                            if (layouts.Count == 0)
                            {
                                logger.Warn($"Channel {channelName} chaincode {chaincode} discovered no layouts!");
                            }
                            else
                            {
                                if (IS_DEBUG_LEVEL)
                                {
                                    StringBuilder sb = new StringBuilder(1000);
                                    sb.Append("Channel ").Append(channelName).Append(" found ").Append(layouts.Count).Append(" layouts for chaincode: ").Append(es.Chaincode);

                                    sb.Append(", layouts: [");

                                    string sep = "";
                                    foreach (SDLayout layout in layouts)
                                    {
                                        sb.Append(sep).Append(layout);

                                        sep = ", ";
                                    }

                                    sb.Append("]");

                                    logger.Debug(sb.ToString());
                                }

                                ret[chaincode] = new SDChaindcode(es.Chaincode, layouts);
                            }
                        }
                    }

                    if (ret.Count == chaincodeNames.Count)
                    {
                        break; // found them all.
                    }
                }
                catch (ServiceDiscoveryException e)
                {
                    logger.Warn($"Service discovery error on peer {serviceDiscoveryPeer}. Error: {e.Message}");
                    serviceDiscoveryException = e;
                }
                catch (Exception e)
                {
                    logger.Warn($"Service discovery error on peer {serviceDiscoveryPeer}. Error: {e.Message}");
                    serviceDiscoveryException = new ServiceDiscoveryException(e.Message, e);
                }
            }

            if (null != serviceDiscoveryException)
            {
                throw serviceDiscoveryException;
            }

            if (ret.Count != chaincodeNames.Count())
            {
                logger.Warn($"Channel {channelName} failed to find all layouts for chaincodes. Expected: {chaincodeNames.Count} and found: {ret.Count}");
            }

            return(ret);
        }