Skip to content

Commit

Permalink
Serious refactoring + improvements + adding new examples for Iroha 1 (#…
Browse files Browse the repository at this point in the history
…107)

* Update README

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Update README

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Refactoring in tls-example.py

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* A little refactoring of batch-example.py

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Small refactoring of blocks-query.py

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Small refactoring of infinite-blocks-stream.py

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Added sample how to use ordering of result transactions

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Refacroting in query_transactions.py

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Renamed file with convention used in other files

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Added examples in comments

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Some refactoring in examples + added docstring in each file

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* chmod +x

Signed-off-by: G.Bazior <bazior@agh.edu.pl>

* Updated iroha version from 1.4 -> 1.5

Signed-off-by: G.Bazior <bazior@agh.edu.pl>
  • Loading branch information
baziorek authored Aug 8, 2022
1 parent 30b76e9 commit bfd9bf2
Show file tree
Hide file tree
Showing 12 changed files with 915 additions and 359 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

This is a source repository for HL Iroha Python library.

Currently, latest HL Iroha rc5 release (`hyperledger/iroha:latest` Docker image) is supported.
Currently, latest [HL Iroha release 1.5](https://github.com/hyperledger/iroha/releases) is supported. It can be ussed with one of official docker images:
- `hyperledger/iroha:latest`
- `hyperledger/iroha-burrow:latest` with Hyperledger-Burrow support (smart contracts).

The library works in Python 3 environment (Python 2 is not supported now).
The library works in Python 3 environment (Python 2 is not supported).

### Installation

Expand Down Expand Up @@ -45,3 +47,5 @@ Please explore [examples](examples) directory for more usage examples.
All the library methods have docstrings in its source [iroha.py](iroha/iroha.py).

*The links above are broken outside the [hyperledger/iroha-python](https://github.com/hyperledger/iroha-python) GitHub repository.*

If you are interested in different HL Iroha client libraries you can check our [Wiki](https://wiki.hyperledger.org/display/iroha/Hyperledger+Iroha).
121 changes: 121 additions & 0 deletions examples/add-syncing-peer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
"""
This example demonstrates how to add new peer, when new peer is syncing node.
Details about how to add new peer to the network are here:
https://iroha.readthedocs.io/en/develop/maintenance/add_peer.html
"""

import os
import sys
from functools import wraps
from iroha import primitive_pb2, IrohaCrypto, binascii, IrohaGrpc, Iroha
import grpc # grpc.RpcError
import inspect # inspect.stack(0)
from utilities.errorCodes2Hr import get_proper_functions_for_commands


if sys.version_info[0] < 3:
raise Exception('Python 3 or a more recent version is required.')


ADMIN_ACCOUNT_ID = os.getenv('ADMIN_ACCOUNT_ID', 'admin@test')
ADMIN_PRIVATE_KEY = os.getenv(
'ADMIN_PRIVATE_KEY', 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70')

iroha_admin = Iroha(ADMIN_ACCOUNT_ID)


IROHA_HOST_ADDR = os.getenv('IROHA_HOST_ADDR', 'localhost')
IROHA_PORT = os.getenv('IROHA_PORT', '50051')

NEW_PEER_PUBLIC_KEY = os.getenv(
'NEW_PEER_PUBLIC_KEY', 'edfa0f05d019c0a0dd6ca491e0c2e78d1ef4148ffa10ffc72f48a0fd6af08e5b')
NEW_PEER_ADDRESS = os.getenv('NEW_PEER_ADDRESS', 'localhost')
NEW_PEER_IROHA_PORT = os.getenv('NEW_PEER_IROHA_PORT', '50050')
NEW_PEER_FULL_ADDRESS = f'{NEW_PEER_ADDRESS}:{NEW_PEER_IROHA_PORT}'

net = IrohaGrpc(f'{IROHA_HOST_ADDR}:{IROHA_PORT}')
net_new_peer = IrohaGrpc(NEW_PEER_FULL_ADDRESS)


def trace(func):
"""
A decorator for tracing methods' begin/end execution points
"""
@wraps(func)
def tracer(*args, **kwargs):
name = func.__name__
stack_size = int(len(inspect.stack(0)) / 2) # @wraps(func) is also increasing the size
indent = stack_size*'\t'
print(f'{indent}> Entering "{name}": args: {args}')
result = func(*args, **kwargs)
print(f'{indent}< Leaving "{name}"')
return result

return tracer


@trace
def add_peers(iroha_connection, peer_address: str, peer_public_key: str):
peer = primitive_pb2.Peer(address=peer_address, peer_key=peer_public_key, syncing_peer=True)
tx = iroha_connection.transaction([
iroha_connection.command('AddPeer', peer=peer)
])
IrohaCrypto.sign_transaction(tx, ADMIN_PRIVATE_KEY)
send_transaction_and_print_status(tx)


@trace
def send_transaction_and_print_status(transaction):
hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction))
creator_id = transaction.payload.reduced_payload.creator_account_id
commands = get_commands_from_tx(transaction)
print(f'Transaction "{commands}",'
f' hash = {hex_hash}, creator = {creator_id}')
net.send_tx(transaction)
for i, status in enumerate(net.tx_status_stream(transaction)):
status_name, status_code, error_code = status
print(f"{i}: status_name={status_name}, status_code={status_code}, "
f"error_code={error_code}")
if status_name in ('STATEFUL_VALIDATION_FAILED', 'STATELESS_VALIDATION_FAILED', 'REJECTED'):
error_code_hr = get_proper_functions_for_commands(commands)(error_code)
raise RuntimeError(f"{status_name} failed on tx: "
f"{transaction} due to reason {error_code}: "
f"{error_code_hr}")


def get_commands_from_tx(transaction):
commands_from_tx = []
for command in transaction.payload.reduced_payload.__getattribute__("commands"):
listed_fields = command.ListFields()
commands_from_tx.append(listed_fields[0][0].name)
return commands_from_tx


@trace
def print_peers(text: str, net_to_query: IrohaGrpc):
print('-------', text, '-------')
query = iroha_admin.query('GetPeers')
IrohaCrypto.sign_query(query, ADMIN_PRIVATE_KEY)
response = net_to_query.send_query(query)
peers_response = response.peers_response.peers
for i, p in enumerate(peers_response):
print(i, p)


if __name__ == '__main__':
try:
print(f'!!!New peer in address {NEW_PEER_FULL_ADDRESS} should work now! '
f'It not the script {sys.argv[0]} would fail!!!')
print_peers('Peers before adding new one', net)
add_peers(iroha_connection=iroha_admin, peer_address=NEW_PEER_FULL_ADDRESS,
peer_public_key=NEW_PEER_PUBLIC_KEY)
print_peers('Peers after adding the new one - query to old peer', net)
print_peers('Peers after adding the new one - query to new peer', net_new_peer)
except grpc.RpcError as rpc_error:
if rpc_error.code() == grpc.StatusCode.UNAVAILABLE:
print(f'[E] Iroha is not running in address: '
f'{IROHA_HOST_ADDR}:{IROHA_PORT}!')
else:
print(e)
except RuntimeError as e:
print(e)
Loading

0 comments on commit bfd9bf2

Please sign in to comment.