сбой gRPC при выполнении цепного кода на блокчейне Hyperledger Fabric на нескольких узлах - PullRequest
0 голосов
/ 18 сентября 2018

Я хотел бы запустить свой собственный блокчейн Hyperledger на нескольких узлах.

У меня есть следующие настройки:

На моем ПК с Ubuntu размещен один сервер заказов, одноранговых узлов, couch db, CA.

Мой Raspberry Pi (работает под управлением Ubuntu Mate) хостинг: один пэр и дБ базы данных.

Оба узла находятся в моей группе роя докеров.(Я использовал следующий учебник для настройки и этот для запуска Fabric на RPi.)

Я успешно создал канал.Заказчик и оба партнера смогли присоединиться к нему.Затем я установил и создал экземпляр цепного кода, используя инструмент peer chaincode в интерфейсе командной строки.Я также инициализировал свой регистр с некоторыми значениями.

Если я выполняю следующую команду в образе интерфейса интерфейса командной строки:

peer chaincode query -o orderer.example.com:7050 -C mychannel -n v2x_sc -c '{"function":"queryAllVehicles","Args":[""]}'

Он успешно возвращает все данные из регистра, независимо от того, выполняю ли яcmd на узле RPi или ПК.

Проблема, с которой я сталкиваюсь, заключается в следующем: как только я хочу выполнить тот же запрос через Hyperledger-Fabric-SDK, он по-прежнему возвращает ошибку grpc.

Javascript SDK:

Ниже приведен запрос query.js, который я выполняю (он исходит из этого кода .

Следующая строка: return channel.queryByChaincode(request); возвращает ошибку: ошибка из запроса = ошибка: не удалось подключиться до истечения срока

Я погуглил корни этой ошибки и обнаружил, что это может быть временный сбой grpc, и поэтомуони закрывают его до тех пор, пока кто-то не испытает его снова 1 .

Выполнение:

node query.js
Store path:/.../hfc-key-store
Successfully loaded user1 from persistence
error: [Remote.js]: Error: Failed to connect before the deadline
error: [client-utils.js]: sendPeersProposal - Promise is rejected: Error: Failed to connect before the deadline
    at checkState (/.../node_modules/fabric-client/node_modules/grpc/src/client.js:838:16)
Query has completed, checking results
error from query =  Error: Failed to connect before the deadline
    at checkState (/.../node_modules/fabric-client/node_modules/grpc/src/client.js:838:16)

query.js:

    'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
 * Chaincode query
 */

var Fabric_Client = require('fabric-client');
var path = require('path');
var util = require('util');
var os = require('os');

//
var fabric_client = new Fabric_Client();

// setup the fabric network
var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://192.168.1.13:7051');
channel.addPeer(peer);

//
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log('Store path:'+store_path);
var tx_id = null;

// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({ path: store_path
}).then((state_store) => {
    // assign the store to the fabric client
    fabric_client.setStateStore(state_store);
    var crypto_suite = Fabric_Client.newCryptoSuite();
    // use the same location for the state store (where the users' certificate are kept)
    // and the crypto store (where the users' keys are kept)
    var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
    crypto_suite.setCryptoKeyStore(crypto_store);
    fabric_client.setCryptoSuite(crypto_suite);

    // get the enrolled user from persistence, this user will sign all requests
    return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
    if (user_from_store && user_from_store.isEnrolled()) {
        console.log('Successfully loaded user1 from persistence');
        member_user = user_from_store;
    } else {
        throw new Error('Failed to get user1.... run registerUser.js');
    }

    // queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
    // queryAllCars chaincode function - requires no arguments , ex: args: [''],
    const request = {
        //targets : --- letting this default to the peers assigned to the channel
        chaincodeId: 'v2x_sc',
        fcn: 'queryAllVehicles',
        args: ['']
    };

    // send the query proposal to the peer
    return channel.queryByChaincode(request);
}).then((query_responses) => {
    console.log("Query has completed, checking results");
    // query_responses could have more than one  results if there multiple peers were used as targets
    if (query_responses && query_responses.length == 1) {
        if (query_responses[0] instanceof Error) {
            console.error("error from query = ", query_responses[0]);
        } else {
            console.log("Response is ", query_responses[0].toString());
        }
    } else {
        console.log("No payloads were returned from query");
    }
}).catch((err) => {
    console.error('Failed to query successfully :: ' + err);
});

Так как я был действительно в отчаянии, я попыталсяn Java SDK.Этот код взят из этого урока .

Я сталкиваюсь с подобной ошибкой при запуске.Эта строка: channel.initialize(); вызывает следующую ошибку:

ОШИБКА Канал - Сбой при отправке предложения на peer0.org1.example.com из-за: сбой gRPC = Статус {код = НЕИЗВЕСТНО, описание = доступ запрещен: канал [mychannel] создатель org [Org1MSP], причина = ноль}

Ниже приведена трассировка исключения:

ERROR Channel - Sending proposal to peer0.org1.example.com failed because of: gRPC failure=Status{code=UNKNOWN, description=access denied: channel [mychannel] creator org [Org1MSP], cause=null}
java.lang.Exception: io.grpc.StatusRuntimeException: UNKNOWN: access denied: channel [mychannel] creator org [Org1MSP]
    at org.hyperledger.fabric.sdk.Channel.sendProposalToPeers(Channel.java:3619)
    at org.hyperledger.fabric.sdk.Channel.getConfigBlock(Channel.java:834)
    at org.hyperledger.fabric.sdk.Channel.parseConfigBlock(Channel.java:1759)
    at org.hyperledger.fabric.sdk.Channel.loadCACertificates(Channel.java:1596)
    at org.hyperledger.fabric.sdk.Channel.initialize(Channel.java:1083)
    at Main.getChannel(Main.java:119)
    at Main.main(Main.java:65)

Main.java:

import org.apache.log4j.Logger;
import org.hyperledger.fabric.sdk.*;
import org.hyperledger.fabric.sdk.exception.CryptoException;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;
import org.hyperledger.fabric.sdk.exception.TransactionException;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.util.Collection;
import java.util.Properties;

/**
 * <h1>HFJavaSDKBasicExample</h1>
 * <p>
 * Simple example showcasing basic fabric-ca and fabric actions.
 * The demo required fabcar fabric up and running.
 * <p>
 * The demo shows
 * <ul>
 * <li>connecting to fabric-ca</li>
 * <li>enrolling admin to get new key-pair, certificate</li>
 * <li>registering and enrolling a new user using admin</li>
 * <li>creating HF client and initializing channel</li>
 * <li>invoking chaincode query</li>
 * </ul>
 *
 */
public class Main {

    private static final Logger log = Logger.getLogger(Main.class);

    public static final String CERT_FOLDER_PATH = "/home/filip/masterthesis/prototype/features_analyser/hyperledger-fabric/Build-Multi-Host-Network-Hyperledger/v2x_java/hfc-key-store";


    public static void main(String[] args) throws Exception {
        // create fabric-ca client
        HFCAClient caClient = getHfCaClient("http://localhost:7054", null);

        // enroll or load admin
        AppUser admin = getAdmin(caClient);
        log.info(admin);

        // register and enroll new user
        AppUser appUser = getUser(caClient, admin, "hfuser");
        log.info(appUser);


        // get HFC client instance
        HFClient client = getHfClient();
        // set user context
        client.setUserContext(admin);

        // get HFC channel using the client
        Channel channel = getChannel(client);
        log.info("Channel: " + channel.getName());

        // call query blockchain example
        queryBlockChain(client);
    }


    /**
     * Invoke blockchain query
     *
     * @param client The HF Client
     * @throws ProposalException
     * @throws InvalidArgumentException
     */
    static void queryBlockChain(HFClient client) throws ProposalException, InvalidArgumentException {
        // get channel instance from client
        Channel channel = client.getChannel("mychannel");
        // create chaincode request
        QueryByChaincodeRequest qpr = client.newQueryProposalRequest();
        // build cc id providing the chaincode name. Version is omitted here.
        ChaincodeID fabcarCCId = ChaincodeID.newBuilder().setName("v2x_sc").build();
        qpr.setChaincodeID(fabcarCCId);
        // CC function to be called
        qpr.setFcn("queryAllVehicles");
        Collection<ProposalResponse> res = channel.queryByChaincode(qpr);
        // display response
        for (ProposalResponse pres : res) {
            String stringResponse = new String(pres.getChaincodeActionResponsePayload());
            log.info(stringResponse);
        }
    }

    /**
     * Initialize and get HF channel
     *
     * @param client The HFC client
     * @return Initialized channel
     * @throws InvalidArgumentException
     * @throws TransactionException
     */
    static Channel getChannel(HFClient client) throws InvalidArgumentException, TransactionException {
        // initialize channel
        // peer name and endpoint in fabcar network
        Peer peer = client.newPeer("peer0.org1.example.com", "grpc://192.168.1.24:8051");
        // eventhub name and endpoint in fabcar network
        EventHub eventHub = client.newEventHub("eventhub01", "grpc://localhost:7053");
        // orderer name and endpoint in fabcar network
        Orderer orderer = client.newOrderer("orderer.example.com", "grpc://localhost:7050");
        // channel name in fabcar network
        Channel channel = client.newChannel("mychannel");
        channel.addPeer(peer);
        channel.addEventHub(eventHub);
        channel.addOrderer(orderer);
        channel.initialize();
        return channel;
    }

    /**
     * Create new HLF client
     *
     * @return new HLF client instance. Never null.
     * @throws CryptoException
     * @throws InvalidArgumentException
     */
    static HFClient getHfClient() throws Exception {
        // initialize default cryptosuite
        CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
        // setup the client
        HFClient client = HFClient.createNewInstance();
        client.setCryptoSuite(cryptoSuite);
        return client;
    }


    /**
     * Register and enroll user with userId.
     * If AppUser object with the name already exist on fs it will be loaded and
     * registration and enrollment will be skipped.
     *
     * @param caClient  The fabric-ca client.
     * @param registrar The registrar to be used.
     * @param userId    The user id.
     * @return AppUser instance with userId, affiliation,mspId and enrollment set.
     * @throws Exception
     */
    static AppUser getUser(HFCAClient caClient, AppUser registrar, String userId) throws Exception {
        AppUser appUser = tryDeserialize(userId);
        if (appUser == null) {
            RegistrationRequest rr = new RegistrationRequest(userId, "org1");
            String enrollmentSecret = caClient.register(rr, registrar);
            Enrollment enrollment = caClient.enroll(userId, enrollmentSecret);
            appUser = new AppUser(userId, "org1", "Org1MSP", enrollment);
            serialize(appUser);
        }
        return appUser;
    }

    /**
     * Enroll admin into fabric-ca using {@code admin/adminpw} credentials.
     * If AppUser object already exist serialized on fs it will be loaded and
     * new enrollment will not be executed.
     *
     * @param caClient The fabric-ca client
     * @return AppUser instance with userid, affiliation, mspId and enrollment set
     * @throws Exception
     */
    static AppUser getAdmin(HFCAClient caClient) throws Exception {
        AppUser admin = tryDeserialize("admin");
        if (admin == null) {
            Enrollment adminEnrollment = caClient.enroll("admin", "adminpw");
            admin = new AppUser("admin", "org1", "Org1MSP", adminEnrollment);
            serialize(admin);
        }
        return admin;
    }

    /**
     * Get new fabic-ca client
     *
     * @param caUrl              The fabric-ca-server endpoint url
     * @param caClientProperties The fabri-ca client properties. Can be null.
     * @return new client instance. never null.
     * @throws Exception
     */
    static HFCAClient getHfCaClient(String caUrl, Properties caClientProperties) throws Exception {
        CryptoSuite cryptoSuite = CryptoSuite.Factory.getCryptoSuite();
        HFCAClient caClient = HFCAClient.createNewInstance(caUrl, caClientProperties);
        caClient.setCryptoSuite(cryptoSuite);
        return caClient;
    }


    // user serialization and deserialization utility functions
    // files are stored in the base directory

    /**
     * Serialize AppUser object to file
     *
     * @param appUser The object to be serialized
     * @throws IOException
     */
    static void serialize(AppUser appUser) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(
                Paths.get(appUser.getName() + ".jso")))) {
            oos.writeObject(appUser);
        }
    }

    /**
     * Deserialize AppUser object from file
     *
     * @param name The name of the user. Used to build file name ${name}.jso
     * @return
     * @throws Exception
     */
    static AppUser tryDeserialize(String name) throws Exception {
        if (Files.exists(Paths.get(name + ".jso"))) {
            return deserialize(name);
        }
        return null;
    }

    static AppUser deserialize(String name) throws Exception {
        try (ObjectInputStream decoder = new ObjectInputStream(
                Files.newInputStream(Paths.get(name + ".jso")))) {
            return (AppUser) decoder.readObject();
        }
    }
}

Может кто-нибудь помочь мне разобраться, пожалуйста?Одно интересное замечание: если я запускаю сеть Hyperledger локально на моем ПК.Оба кода (JS и Java) работают без ошибок.

1 Ответ

0 голосов
/ 02 октября 2018

Проблема заключалась в том, что я использовал неправильные номера портов при подключении к узлам.Я немного перепутал отображение портов докера.У меня сейчас работает.

...