fabric-samples/test-network/scripts/add_new_orderer_to_config.py
arkadipiven eb16caf3d5 Fix test-network to work with BFT consensus.
Added a new option for creating channel:
Running ./network.sh createChannel -bft will initiate a channel running BFT orderers.
Using ./network.sh up -bft will initiate dockers for bft environment.
Added option for 4 orderers.

Add add_new_orderer_to_config.py which is referenced in the fabric official docs.

Signed-off-by: Arkadi Piven <arkadi.piven@ibm.com>
Signed-off-by: arkadipiven <arkadi7770@gmail.com>
2023-08-22 10:54:41 -04:00

98 lines
3.9 KiB
Python

# This is a sample Python script.
# Press ⌃R to execute it or replace it with your code.
# Press Double ⇧ to search everywhere for classes, files, tool windows, actions, and settings.
import argparse
import base64
import copy
import json
import math
from typing import Any
def parse_args():
parser = argparse.ArgumentParser(
prog='Config Update',
description='What the program does',
epilog='Text at the bottom of help')
parser.add_argument('config_path', type=str)
parser.add_argument('updated_config_path', type=str)
parser.add_argument('-a', '--address', type=str, required=True)
parser.add_argument('-i', '--identity', type=str, required=True)
parser.add_argument('-s', '--server-cert', type=str, required=True)
parser.add_argument('-c', '--client-cert', type=str, required=True)
return parser.parse_args()
def _pem_file_to_base64(path: str) -> str:
with open(path, 'rb') as binary_file:
binary_file_data = binary_file.read()
base64_encoded_data = base64.b64encode(binary_file_data)
return base64_encoded_data.decode('utf-8')
def _log_update(name: str, old: Any, new: Any) -> None:
print('=' * 50)
print(f'Updating {name}:')
print(f'{old}')
print(">" * 25)
print(f'{new}')
print('=' * 50)
def _calculate_bft_quorum(n: int) -> int:
f = int((n - 1) / 3)
return int(math.ceil((n + f + 1) / 2))
def update_config(config_path: str, updated_config_path: str, address: str, identity_pem_path: str, server_pem_path: str, client_pem_path: str):
with open(config_path, 'r') as f:
config = json.load(f)
identity = _pem_file_to_base64(identity_pem_path)
client_cert = _pem_file_to_base64(client_pem_path)
server_cert = _pem_file_to_base64(server_pem_path)
host, port = address.split(':')
addresses = config['channel_group']['groups']['Orderer']['groups']['OrdererOrg']['values']['Endpoints']['value']['addresses']
addresses_before_update = copy.deepcopy(addresses)
original_orderers_count = len(addresses_before_update)
addresses.append(f'{addresses[0].split(":")[0]}:{port}')
new_orderers_count = len(addresses)
_log_update('addresses', addresses_before_update, addresses)
identities = config['channel_group']['groups']['Orderer']['policies']['BlockValidation']['policy']['value']['identities']
identities_before_update = copy.deepcopy(identities)
new_identity = copy.deepcopy(identities[0])
new_identity['principal']['id_bytes'] = identity
identities.append(new_identity)
_log_update('block validation identities', identities_before_update, identities)
rule = config['channel_group']['groups']['Orderer']['policies']['BlockValidation']['policy']['value'][
'rule']
rule_before_update = copy.deepcopy(rule)
rule['n_out_of']['n'] = _calculate_bft_quorum(new_orderers_count)
rule['n_out_of']['rules'].append({'signed_by': new_orderers_count - 1})
_log_update('block validation rules', rule_before_update, rule)
consenter_mapping = config['channel_group']['groups']['Orderer']['values']['Orderers']['value']['consenter_mapping']
consenter_mapping_before_update = copy.deepcopy(consenter_mapping)
consenter_mapping.append({
'client_tls_cert': client_cert,
'host': host,
'id': new_orderers_count,
'identity': identity,
'msp_id': consenter_mapping[0]['msp_id'],
'port': port,
'server_tls_cert': server_cert
})
_log_update('consenter_mapping', consenter_mapping_before_update, consenter_mapping)
with open(updated_config_path, 'w') as f:
json.dump(config, f)
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
args = parse_args()
update_config(args.config_path, args.updated_config_path, args.address, args.identity, args.server_cert, args.client_cert)
# See PyCharm help at https://www.jetbrains.com/help/pycharm/