[JAVA] Comment ajouter Hyperledger Iroha Peer

Contenu de l'article

Cet article décrit comment ajouter Peer avec Hyperledger Iroha. Il existe également un moyen de l'ajouter avec "iroha-cli", mais cette fois, il est ajouté en utilisant la bibliothèque Java. Si vous voulez l'ajouter avec "iroha-cli", vous pouvez obtenir la clé publique et la clé privée avec le code de l'article, donc je pense que vous pouvez facilement le faire en utilisant les informations de clé.

Je vais d'abord écrire la conclusion, mais cette procédure ne parvient pas à ajouter Peer. Le programme supplémentaire Peer se termine normalement et est inclus dans le bloc, mais la communication entre pairs ne fonctionne pas.

Je ne suis pas sûr qu'il s'agisse d'un problème environnemental ou d'un problème d'Iroha, alors je vais laisser une note car cela n'a pas fonctionné.

environnement

Dans le travail de cet article, nous travaillons en démarrant quatre consoles. Écrivez soigneusement afin que la console de l'article ne prête pas à confusion.

  1. console de vérification des journaux du démon iroha Unit 1 iroha
  2. console de commande du conteneur iroha Unit 1
  3. console d'opération de conteneur some-postgres de l'unité iroha 1
  4. console de commande du conteneur iroha Unit 2 iroha

Préparation préalable

Nous construirons l'environnement pour iroha pour deux voitures. Chargez de manière appropriée les blocs de versement, etc. sur l'unité 1 à l'avance. L'unité 2 n'aura plus que le bloc Genesis.

Préparer une clé à utiliser lors de l'ajout de Peer

À l'origine? Je me demande si je préparerai une clé publique en utilisant OpenSSL etc. Vous pouvez facilement créer une clé en utilisant l'exemple de code écrit dans la documentation Iroha, donc cette fois, nous allons créer les informations de clé en Java.

Traitement supplémentaire de Peer

Programme supplémentaire par les pairs

Code qui n'ajoute que Peer.

import java.net.URI;
import java.security.KeyPair;

import org.testcontainers.shaded.org.apache.commons.codec.binary.Hex;

import jp.co.soramitsu.crypto.ed25519.Ed25519Sha3;
import jp.co.soramitsu.iroha.java.IrohaAPI;
import jp.co.soramitsu.iroha.java.Transaction;
import jp.co.soramitsu.iroha.java.TransactionStatusObserver;
import lombok.val;

public class AddPeer {

    private static final Ed25519Sha3 crypto = new Ed25519Sha3();

    private static final KeyPair peerKeypair = crypto.generateKeypair();

    public static void main(String[] args) throws Exception{

 // Cette IP est l'adresse de l'unité iroha 1
        URI uri = new URI(null,null, "192.168.33.20",50051,null,null,null);

        IrohaAPI api = new IrohaAPI(uri);

        byte[] pubByte = Hex.decodeHex("313a07e6384776ed95447710d15e59148473ccfc052a681317a72a69f2a49910");
        byte[] privByte = Hex.decodeHex("f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70");

        KeyPair adminKeyPair = Ed25519Sha3.keyPairFromBytes(privByte, pubByte);

 // Cette IP est l'adresse IP de l'unité iroha 2
        val addPeerTx = Transaction.builder("admin@test")
                          .addPeer("192.168.33.21:10001", peerKeypair.getPublic())
                          .sign(adminKeyPair)
                          .build();
                          
        val observer = TransactionStatusObserver.builder()
            // executed when stateless or stateful validation is failed
            .onTransactionFailed(t -> System.out.println(String.format(
                "transaction %s failed with msg: %s",
                t.getTxHash(),
                t.getErrOrCmdName()
            )))
            // executed when got any exception in handlers or grpc
            .onError(e -> System.out.println("Failed with exception: " + e))
            // executed when we receive "committed" status
            .onTransactionCommitted((t) -> System.out.println("Committed :)"))
            // executed when transfer is complete (failed or succeed) and observable is closed
            .onComplete(() -> System.out.println("Complete"))
            .build();

 // Exécuter la transaction
        api.transaction(addPeerTx).blockingSubscribe(observer);

        api.close();
        System.out.println("PubKey :" + Hex.encodeHexString(peerKeypair.getPublic().getEncoded()));
        System.out.println("PrivKey:" + Hex.encodeHexString(peerKeypair.getPrivate().getEncoded()));       
    }
}

Confirmation du résultat de l'exécution (bloc)

Un bloc avec AddPeer est créé sous "/ tmp / block_store" du conteneur iroha.

(Iroha Unit 1 Iroha Container Operation Console)

{
  "blockV1": {
    "payload": {
      "transactions": [
        {
          "payload": {
            "reducedPayload": {
              "commands": [
                {
                  "addPeer": {
                    "peer": {
                      "address": "192.168.33.21:10001",
                      "peerKey": "28CF79DEF117456ABC5413DC15F7B99B192C6D5A162ABDEF39F0BAF6C7CE0B48"
                    }
                  }
                }
              ],
              "creatorAccountId": "admin@test",
              "createdTime": "1571213725207",
              "quorum": 1
            }
          },
          "signatures": [
            {
              "publicKey": "313A07E6384776ED95447710D15E59148473CCFC052A681317A72A69F2A49910",
              "signature": "A018F697EB5F6797BD478F8CF04759F8D0ACDA48D4E1FE8B8BBE5D538E6D47A423896E689AA780DD260763ED1B97B12F9AF1EA41D7D391FB2F9C49EDB429DC0C"
            }
          ]
        }
      ],
      "height": "16",
      "prevBlockHash": "e602693381ff5ac383a2d62503d94ede87951ffdedefe9b4628a188036fd6c89",
      "createdTime": "1571213727036"
    },
    "signatures": [
      {
        "publicKey": "bddd58404d1315e0eb27902c5d7c8eb0602c16238f005773df406bc191308929",
        "signature": "863b38942a290640e05bbb2339ab63d94a8ab6ca3bfba1abaf673fe490f7eb46236a72cdb54d95a3c11254c440ebe3ef1110466a989e0dc4221952749b87ec0b"
      }
    ]
  }
}

L'adresse IP intégrée dans le programme et la pubKey créée sont enregistrées en tant qu'informations d'homologue dans la commande addPeer.

Confirmation du résultat de l'exécution (postgres)

Connectez-vous à "some-postgres" dans le conteneur Docker et jetez un œil au contenu de la table qui contient les informations sur le pair. (Iroha Unit 1 some-postgres container operation console)

root@f7d412e03bfb:/# psql -U postgres
psql (9.5.19)
Type "help" for help.

postgres=# \l
                                 List of databases
    Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
  postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
  template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
            |          |          |            |            | postgres=CTc/postgres
  template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
            |          |          |            |            | postgres=CTc/postgres
(3 rows)

postgres=# \d
                        List of relations
  Schema |               Name                |   Type   |  Owner
--------+-----------------------------------+----------+----------
  public | account                           | table    | postgres
  public | account_has_asset                 | table    | postgres
  public | account_has_grantable_permissions | table    | postgres
  public | account_has_roles                 | table    | postgres
  public | account_has_signatory             | table    | postgres
  public | asset                             | table    | postgres
  public | domain                            | table    | postgres
  public | height_by_account_set             | table    | postgres
  public | index_by_creator_height           | table    | postgres
  public | index_by_creator_height_id_seq    | sequence | postgres
  public | peer                              | table    | postgres
  public | position_by_account_asset         | table    | postgres
  public | position_by_hash                  | table    | postgres
  public | role                              | table    | postgres
  public | role_has_permissions              | table    | postgres
  public | signatory                         | table    | postgres
  public | tx_status_by_hash                 | table    | postgres
(17 rows)

postgres=# select * from peer;
                            public_key                            |       address
------------------------------------------------------------------+---------------------
 bddd58404d1315e0eb27902c5d7c8eb0602c16238f005773df406bc191308929 | 127.0.0.1:10001
 28cf79def117456abc5413dc15f7b99b192c6d5a162abdef39f0baf6c7ce0b48 | 192.168.33.21:10001
(2 rows)

La clé publique et l'adresse IP définies par addPeer sont enregistrées dans la table Peer.

Confirmation du résultat de l'exécution (iroha Unit 2)

Ensuite, vérifiez si les informations de bloc ont été synchronisées avec l'unité 2.

(Iroha Unit 2 Iroha Container Operation Console)

root@eaa7050903db:/opt/iroha_data# ls /tmp/block_store/
0000000000000001

Non synchronisé. .. Vérifions le journal de irohad.

Confirmation du résultat de l'exécution (démon iroha)

(Console de confirmation du journal du démon Iroha Unit 1 iroha)

root@c8d233a3c261:/opt/iroha_data# [2019-10-17 00:12:09.459123458][I][Irohad/CommandService/Processor]: handle batch
[2019-10-17 00:12:09.459140102][I][Irohad/CommandService/Processor]: propagating batch to PCS
[2019-10-17 00:12:09.459158309][I][Irohad/PeerCommunicationService]: propagate batch
[2019-10-17 00:12:09.460952243][I][Irohad/Ordering/Service]: onBatches => collection size = 1
[2019-10-17 00:12:10.400058025][W][Irohad/AsyncNetworkClient]: RPC failed: Connect Failed
[2019-10-17 00:12:10.400080412][W][Irohad/AsyncNetworkClient]: RPC failed: Connect Failed
[2019-10-17 00:12:10.400088212][W][Irohad/AsyncNetworkClient]: RPC failed: Connect Failed
[2019-10-17 00:12:10.400095314][W][Irohad/AsyncNetworkClient]: RPC failed: Connect Failed
[2019-10-17 00:12:10.400102280][W][Irohad/AsyncNetworkClient]: RPC failed: Connect Failed

Il semble que la connexion avec l'unité 2 à l'aide de gRPC a échoué.

Probablement, mais je pense que c'est le même événement. https://github.com/hyperledger/iroha/issues/191

C'est géré ici https://jira.hyperledger.org/browse/IR-588

Retour (Supprimer l'homologue)

Puisqu'il ne peut pas être utilisé tel quel, j'ai également préparé un programme pour supprimer Peer.

import java.net.URI;
import java.security.KeyPair;

import org.testcontainers.shaded.org.apache.commons.codec.binary.Hex;

import jp.co.soramitsu.crypto.ed25519.Ed25519Sha3;
import jp.co.soramitsu.iroha.java.IrohaAPI;
import jp.co.soramitsu.iroha.java.Transaction;
import jp.co.soramitsu.iroha.java.TransactionStatusObserver;
import lombok.val;

public class RemovePeer {

    public static void main(String[] args) throws Exception{

        URI uri = new URI(null,null, "192.168.33.20",50051,null,null,null);

        IrohaAPI api = new IrohaAPI(uri);

        byte[] pubByte = Hex.decodeHex("313a07e6384776ed95447710d15e59148473ccfc052a681317a72a69f2a49910");
        byte[] privByte = Hex.decodeHex("f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70");
        
 // ↓ Veuillez définir la clé publique de Peer capturée dans le bloc ↓
        byte[] peerPubKey = Hex.decodeHex("28CF79DEF117456ABC5413DC15F7B99B192C6D5A162ABDEF39F0BAF6C7CE0B48");

        KeyPair adminKeyPair = Ed25519Sha3.keyPairFromBytes(privByte, pubByte);


        val addPeerTx = Transaction.builder("admin@test")
 .removePeer (peerPubKey) // ← Cela vient de changer de addPeer à removePeer
                            .sign(adminKeyPair)
                            .build();

        val observer = TransactionStatusObserver.builder()
            // executed when stateless or stateful validation is failed
            .onTransactionFailed(t -> System.out.println(String.format(
                "transaction %s failed with msg: %s",
                t.getTxHash(),
                t.getErrOrCmdName()
            )))
            // executed when got any exception in handlers or grpc
            .onError(e -> System.out.println("Failed with exception: " + e))
            // executed when we receive "committed" status
            .onTransactionCommitted((t) -> System.out.println("Committed :)"))
            // executed when transfer is complete (failed or succeed) and observable is closed
            .onComplete(() -> System.out.println("Complete"))
            .build();

 // Exécuter la transaction
        api.transaction(addPeerTx).blockingSubscribe(observer);

        api.close();
    }
}

Je le ferai.

transaction 6069fe1e6c2f6b7437ce145e0db552355f3d8631d16b7bc18b53894fcafec2bf failed with msg: Protobuf Transaction: [[Undefined command is found ]]

Complete

Quoi! Une commande non définie est trouvée! Il semble que removePeer n'ait pas encore été implémenté. Quand j'ai vérifié le contenu de Transaction par débogage, cela ressemblait à ceci.

reduced_payload {
  commands {
    remove_peer {
      public_key: "28CF79DEF117456ABC5413DC15F7B99B192C6D5A162ABDEF39F0BAF6C7CE0B48"
    }
  }
  creator_account_id: "admin@test"
  created_time: 1571276110853
  quorum: 1
}

Je continuerai à chercher d'autres moyens et à retracer les informations sur les sites ci-dessus. C'est tout pour cette fois.

Points de préoccupation

Il y a deux points qui m'intéressaient cette fois-ci.

Le premier point est que la transaction n'est pas capturée dans le bloc si la communication entre pairs échoue. Eh bien, je pense que c'est naturel, mais en fonctionnement réel, s'il y a deux pairs, si l'un tombe en panne, la transaction ne sera pas du tout acceptée. À l'avenir, j'essaierai d'augmenter le nombre d'unités à 3 et 4, mais afin de ne pas créer un seul point de défaillance, il semble qu'au moins 3 unités auront besoin de Peer.

Le deuxième point n'est peut-être pas un gros problème, mais il semble que toutes les informations de bloc existantes soient vérifiées au démarrage du démon iroha. (Console de confirmation du journal du démon Iroha Unit 1 iroha)

[2019-10-16 23:41:19.917112613][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 1, hash 9debdb1a70db2cede2222427b849f6bf7ab20845da7c3db1837c0df25ec1c61a
[2019-10-16 23:41:19.930740040][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 2, hash d2d9906eb82dd799e6cb68161208738e8383cae31bdf499b2b5f7f14d55b2ba0
[2019-10-16 23:41:19.950225041][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 3, hash 686b05c2553b70cd26fdb6e9108066a33e2b09653ccb33b3b3c9f6e4f12e72d2
[2019-10-16 23:41:19.952860890][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 4, hash fd8541954c9ab55229e8f6e095a7484ece7d64066e78c775359e0d8736a4ea4b
[2019-10-16 23:41:19.960015934][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 5, hash cc5a4fe828811e217a5de828047b9c0d5939628d809b2265b66db1b73f9d0f98
[2019-10-16 23:41:19.972008320][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 6, hash 4fa8f208d9c85b08edc3504aed35f257de943942f250639111c334724cfe6d26
[2019-10-16 23:41:19.983822479][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 7, hash 471894ae7fa36f09d971be563686b2aa06ff28a9bd9a49d6e802451cb018ac1b
[2019-10-16 23:41:19.985555973][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 8, hash 68ef83c09eb4bc8152dd7feaeb0e10a1fb0c71b63e6c6e66e829fd730a765f18
[2019-10-16 23:41:19.987011731][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 9, hash e5dcd0505aa726d25d318af78ea41126f02c44f3647011582017140e1c7e55e5
[2019-10-16 23:41:19.988539990][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 10, hash c6fb5fff4bf3c440b6846761d50d248beb75199342b8b9431e19c1e2b5e7e303
[2019-10-16 23:41:19.989874002][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 11, hash 278c9c5e5a72b5513d55290f2687c623595b7825b747c525ee00135cccfb1149
[2019-10-16 23:41:19.991317395][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 12, hash d33d2adabf75be7380cc6b35b84bcb4b2055f47a927cf1090c1d49853fee154b
[2019-10-16 23:41:19.992694976][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 13, hash b0d19d57da0f0d0677052409e625adfea8dedbb6297edd49968d5f102de73c27
[2019-10-16 23:41:20.008512960][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 14, hash 337830921603cc703cd8f95a6624b3d2d0fce090d3ddca53c69d9989620f2c44
[2019-10-16 23:41:20.022142829][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 15, hash e602693381ff5ac383a2d62503d94ede87951ffdedefe9b4628a188036fd6c89
[2019-10-16 23:41:20.024153577][I][Irohad/Storage/MutableStorageImpl]: Applying block: height 16, hash d3e5c825cb9b1ca298ccf6b7b7f8a139803e6e1c9850fed65a0241f378f5125e

Il semble qu'il faut environ 0,01 seconde pour un bloc normalement capturé et environ 0,002 seconde pour un bloc rejeté. Bien sûr, la vitesse de traitement changera en fonction des performances du serveur, mais si vous devez redémarrer le démon en fonctionnement réel, ce traitement peut prendre plus de temps que prévu.

AddPeer et removePeer fonctionneront-ils avec la bibliothèque Python? Ensuite, je voudrais enquêter sur ce domaine.

Recommended Posts

Comment ajouter Hyperledger Iroha Peer
Comment ajouter la fonction ActionText
[Rails] Comment ajouter de nouvelles pages
Comment ajouter la fonction de suppression
Comment ajouter un pot local au pom.xml de Maven
[Java] Comment ajouter des données à la liste (add, addAll)
Comment ajouter un nouveau hachage / tableau
Comment ajouter un fichier jar dans ScalaIDE
Comment ajouter des informations sur la version de l'application aux informations Sentry
Comment ajouter un chemin de classe dans Spring Boot
Comment ajouter conditionnellement une classe html.erb dans Rails
Ajouter un fichier au fichier jar
Comment développer OpenSPIFe
Comment appeler AmazonSQSAsync
Comment utiliser Map
Comment écrire des rails
Comment utiliser rbenv
Comment utiliser with_option
Comment utiliser fields_for
Comment utiliser java.util.logging
Comment utiliser la carte
Comment ajouter des caractères à afficher lors de l'utilisation de la méthode link_to
Comment utiliser collection_select
Comment utiliser Twitter4J
Comment utiliser active_hash! !!
Comment installer Docker
Comment utiliser MapStruct
Comment utiliser TreeSet
Comment désinstaller Rails
Comment installer docker-machine
[Comment utiliser l'étiquette]
Comment faire un pot ombré
Comment écrire docker-compose
Comment utiliser l'identité
Comment utiliser le hachage
Comment écrire Mockito
Comment créer docker-compose
Comment installer MySQL
Comment écrire un fichier de migration
Comment construire android-midi-lib
Comment utiliser Dozer.mapper
Comment utiliser Gradle
Comment utiliser org.immutables
Comment utiliser java.util.stream.Collector
Comment utiliser VisualVM
Comment utiliser Map
Comment repousser la barre oblique \
Comment concaténer des chaînes
Comment ajouter des éléments sans spécifier la longueur du tableau