Skip to content

Commit

Permalink
break aprt create_channel into smaller func
Browse files Browse the repository at this point in the history
Signed-off-by: YoungHypo <haiboyang@smail.nju.edu.cn>
  • Loading branch information
YoungHypo committed Nov 25, 2024
1 parent 0fa36fe commit 289a7e0
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 142 deletions.
27 changes: 13 additions & 14 deletions src/api-engine/api/lib/configtxgen/configtx.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ def create(self, name, consensus, orderers, peers, orderer_cfg=None, application
Consenters = []

for orderer in orderers:
OrdererMSP = orderer["name"].capitalize() + "Orderer"
OrdererOrg = dict(Name=orderer["name"].split(".")[0].capitalize() + "Orderer",
ID='{}MSP'.format(OrdererMSP),
OrdererMSP = "OrdererMSP"
OrdererOrg = dict(Name="Orderer",
ID= OrdererMSP,
MSPDir='{}/{}/crypto-config/ordererOrganizations/{}/msp'.format(self.filepath, orderer["name"], orderer['name'].split(".", 1)[1]),
Policies=dict(Readers=dict(Type="Signature", Rule="OR('{}MSP.member')".format(OrdererMSP)),
Writers=dict(Type="Signature", Rule="OR('{}MSP.member')".format(OrdererMSP)),
Admins=dict(Type="Signature", Rule="OR('{}MSP.admin')".format(OrdererMSP)))
Policies=dict(Readers=dict(Type="Signature", Rule="OR('{}.member')".format(OrdererMSP)),
Writers=dict(Type="Signature", Rule="OR('{}.member')".format(OrdererMSP)),
Admins=dict(Type="Signature", Rule="OR('{}.admin')".format(OrdererMSP)))
)
for host in orderer['hosts']:
OrdererAddress.append('{}.{}:{}'.format(host['name'], orderer['name'].split(".", 1)[1], 7050))
Expand All @@ -74,15 +74,14 @@ def create(self, name, consensus, orderers, peers, orderer_cfg=None, application
PeerOrganizations = []

for peer in peers:
PeerMSP = peer["name"].capitalize()
PeerOrganizations.append(dict(Name=peer["name"].split(".")[0].capitalize(),
ID='{}MSP'.format(PeerMSP),
PeerMSP = peer['name'].split(".", 1)[0].capitalize() + "MSP"
PeerOrganizations.append(dict(Name=peer['name'].split(".", 1)[0].capitalize(),
ID=PeerMSP,
MSPDir='{}/{}/crypto-config/peerOrganizations/{}/msp'.format(self.filepath, peer['name'], peer['name']),
# AnchorPeers=[{'Port': peer["hosts"][0]["port"], 'Host': '{}.{}'.format(peer["hosts"][0]["name"],peer["name"])}],
Policies=dict(Readers=dict(Type="Signature", Rule="OR('{}MSP.member')".format(PeerMSP)),
Writers=dict(Type="Signature", Rule="OR('{}MSP.member')".format(PeerMSP)),
Admins=dict(Type="Signature", Rule="OR('{}MSP.admin')".format(PeerMSP)),
Endorsement=dict(Type="Signature", Rule="OR('{}MSP.member')".format(PeerMSP)))
Policies=dict(Readers=dict(Type="Signature", Rule="OR('{}.admin', '{}.peer', '{}.client')".format(PeerMSP, PeerMSP, PeerMSP)),
Writers=dict(Type="Signature", Rule="OR('{}.admin', '{}.client')".format(PeerMSP, PeerMSP)),
Admins=dict(Type="Signature", Rule="OR('{}.admin')".format(PeerMSP)),
Endorsement=dict(Type="Signature", Rule="OR('{}.peer')".format(PeerMSP)))
))
Organizations = OrdererOrganizations + PeerOrganizations
Capabilities = dict(
Expand Down
10 changes: 7 additions & 3 deletions src/api-engine/api/lib/configtxgen/configtxgen.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#
# SPDX-License-Identifier: Apache-2.0
#
from subprocess import call
from api.config import CELLO_HOME, FABRIC_TOOL, FABRIC_VERSION

import subprocess
import logging
LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -42,9 +42,13 @@ def genesis(self, profile="", channelid="", outputblock="genesis.block"):
"-channelID", "{}".format(channelid)
]

LOG.info("Running command: " + " ".join(command))
LOG.info(" ".join(command))

call(command)
subprocess.run(command, check=True)

except subprocess.CalledProcessError as e:
err_msg = "configtxgen genesis fail! "
raise Exception(err_msg+str(e))

except Exception as e:
err_msg = "configtxgen genesis fail! "
Expand Down
101 changes: 73 additions & 28 deletions src/api-engine/api/lib/peer/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import json
import subprocess
import time
from api.lib.peer.command import Command
from api.config import FABRIC_TOOL, FABRIC_VERSION
import logging
Expand All @@ -20,23 +21,39 @@ def __init__(self, version=FABRIC_VERSION, peer=FABRIC_TOOL, **kwargs):

def create(self, channel, orderer_admin_url, block_path, time_out="90s"):
try:
res = 0x100
command = ""
command = []

if os.getenv("CORE_PEER_TLS_ENABLED") == "false" or os.getenv("CORE_PEER_TLS_ENABLED") is None:
command = "{} channel join --channelID {} --config-block {} -o {}".format(self.osnadmin, channel, block_path, orderer_admin_url)
command = [
self.osnadmin,
"channel", "join",
"--channelID", channel,
"--config-block", block_path,
"-o", orderer_admin_url,
]
else:
ORDERER_CA = os.getenv("ORDERER_CA")
ORDERER_ADMIN_TLS_SIGN_CERT = os.getenv("ORDERER_ADMIN_TLS_SIGN_CERT")
ORDERER_ADMIN_TLS_PRIVATE_KEY = os.getenv("ORDERER_ADMIN_TLS_PRIVATE_KEY")
command = "{} channel join --channelID {} --config-block {} -o {} --ca-file {} --client-cert {} --client-key {}".format(self.osnadmin, channel, block_path, orderer_admin_url, ORDERER_CA, ORDERER_ADMIN_TLS_SIGN_CERT, ORDERER_ADMIN_TLS_PRIVATE_KEY)

LOG.info(f"{command}")
res = os.system(command)

# The return value of os.system is not the result of executing the program. It is a 16 bit number,
# and its high bit is the return code
res = res >> 8
command = [
self.osnadmin,
"channel", "join",
"--channelID", channel,
"--config-block", block_path,
"-o", orderer_admin_url,
"--ca-file", ORDERER_CA,
"--client-cert", ORDERER_ADMIN_TLS_SIGN_CERT,
"--client-key", ORDERER_ADMIN_TLS_PRIVATE_KEY
]

LOG.info(" ".join(command))

res = subprocess.run(command, check=True)

except subprocess.CalledProcessError as e:
err_msg = "create channel failed for {}!".format(e)
raise Exception(err_msg+str(e))

except Exception as e:
err_msg = "create channel failed for {}!".format(e)
raise Exception(err_msg)
Expand Down Expand Up @@ -78,30 +95,58 @@ def update(self, channel, channel_tx, orderer_url):
res = res >> 8
return res

def fetch(self, block_path, channel, orderer_general_url):
def fetch(self, block_path, channel, orderer_general_url, max_retries=5, retry_interval=1):
"""
Fetch a specified block, writing it to a file e.g. <channelID>.block.
params:
option: block option newest|oldest|config|(block number).
channel: channel id.
"""
try:
res = 0x100
command = ""
if os.getenv("CORE_PEER_TLS_ENABLED") == "false" or os.getenv("CORE_PEER_TLS_ENABLED") is None:
command = "{} channel fetch config {} -o {} -c {}".format(self.peer, block_path, orderer_general_url, channel)
else:
ORDERER_CA = os.getenv("ORDERER_CA")
orderer_address = orderer_general_url.split(":")[0]
command = "{} channel fetch config {} -o {} --ordererTLSHostnameOverride {} -c {} --tls --cafile {}".format(self.peer, block_path, orderer_general_url, orderer_address, channel, ORDERER_CA)
res = 0
command = []
if os.getenv("CORE_PEER_TLS_ENABLED") == "false" or os.getenv("CORE_PEER_TLS_ENABLED") is None:
command = [
self.peer,
"channel", "fetch",
"config", block_path,
"-o", orderer_general_url,
"-c", channel
]
else:
ORDERER_CA = os.getenv("ORDERER_CA")
orderer_address = orderer_general_url.split(":")[0]
command = [
self.peer,
"channel", "fetch",
"config", block_path,
"-o", orderer_general_url,
"--ordererTLSHostnameOverride", orderer_address,
"-c", channel,
"--tls",
"--cafile", ORDERER_CA
]

LOG.info(" ".join(command))

# Retry fetching the block up to max_retries times
for attempt in range(1, max_retries+1):
try:
LOG.debug("Attempt %d/%d to fetch block", attempt, max_retries)

res = subprocess.run(command, check=True)

LOG.info("Successfully fetched block")
break

except subprocess.CalledProcessError as e:
LOG.debug(f"Attempt {attempt}/{max_retries} failed")

if attempt <= max_retries:
time.sleep(retry_interval)
else:
LOG.error(f"Failed to fetch block after {max_retries} attempts")
raise e

LOG.info(f"{command}")
res = os.system(command)

res = res >> 8
except Exception as e:
err_msg = "fetch a specified block failed {}!".format(e)
raise Exception(err_msg)
return res

def signconfigtx(self, channel_tx):
Expand Down
3 changes: 2 additions & 1 deletion src/api-engine/api/lib/pki/cryptogen/cryptocfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def create(self, peernum, orderernum) -> None:
else:
template = dict(Count=orderernum)
org.append(dict(Domain=self.name.split(".", 1)[1],
Name=self.name.split(".")[0].capitalize() + item,
Name=item,
CA=ca,
Specs=specs,
EnableNodeOUs=self.enablenodeous,
Expand Down Expand Up @@ -89,6 +89,7 @@ def update(self, org_info: any) -> None:
orgs = network['OrdererOrgs']

for org in orgs:
# org["Template"]["Count"] += 1
specs = org["Specs"]
for host in org_info["Specs"]:
specs.append(dict(Hostname=host))
Expand Down
71 changes: 32 additions & 39 deletions src/api-engine/api/lib/pki/cryptogen/cryptogen.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,65 @@
#
# SPDX-License-Identifier: Apache-2.0
#
from subprocess import call
from api.config import CELLO_HOME, FABRIC_TOOL, FABRIC_VERSION

import subprocess
import logging
LOG = logging.getLogger(__name__)


class CryptoGen:
"""Class represents crypto-config tool."""
class ConfigTxGen:
"""Class represents cryptotxgen."""

def __init__(self, name, filepath=CELLO_HOME, cryptogen=FABRIC_TOOL, version=FABRIC_VERSION):
def __init__(self, network, filepath=CELLO_HOME, configtxgen=FABRIC_TOOL, version=FABRIC_VERSION):
"""init CryptoGen
param:
name: organization's name
cryptogen: tool path
network: network's name
configtxgen: tool path
version: version
filepath: cello's working directory
return:
"""
self.cryptogen = cryptogen + "/cryptogen"
self.network = network
self.configtxgen = configtxgen + "/configtxgen"
self.filepath = filepath
self.version = version
self.name = name

def generate(self, output="crypto-config", config="crypto-config.yaml"):
"""Generate key material
def genesis(self, profile="", channelid="", outputblock="genesis.block"):
"""generate gensis
param:
output: The output directory in which to place artifacts
config: The configuration template to use
profile: profile
channelid: channelid
outputblock: outputblock
return:
"""
try:
command = [
self.cryptogen,
"generate",
"--output={}/{}/{}".format(self.filepath, self.name, output),
"--config={}/{}/{}".format(self.filepath, self.name, config)
self.configtxgen,
"-configPath", "{}/{}/".format(self.filepath, self.network),
"-profile", "{}".format(profile),
"-outputBlock", "{}/{}/{}".format(self.filepath, self.network, outputblock),
"-channelID", "{}".format(channelid)
]

LOG.info("Running command: " + " ".join(command))
LOG.info(" ".join(command))

call(command)
subprocess.run(command, check=True)

except subprocess.CalledProcessError as e:
err_msg = "configtxgen genesis fail! "
raise Exception(err_msg+str(e))

except Exception as e:
err_msg = "cryptogen generate fail for {}!".format(e)
raise Exception(err_msg)
err_msg = "configtxgen genesis fail! "
raise Exception(err_msg + str(e))

def extend(self, input="crypto-config", config="crypto-config.yaml"):
"""Extend existing network
def anchorpeer(self, profile, channelid, outputblock):
"""set anchorpeer
param:
input: The input directory in which existing network place
config: The configuration template to use
profile: profile
channelid: channelid
outputblock: outputblock
return:
"""
try:
command = [
self.cryptogen,
"extend",
"--input={}/{}/{}".format(self.filepath, self.name, input),
"--config={}/{}/{}".format(self.filepath, self.name, config)
]

LOG.info("Running command: " + " ".join(command))

call(command)

except Exception as e:
err_msg = "cryptogen extend fail for {}!".format(e)
raise Exception(err_msg)
pass
Loading

0 comments on commit 289a7e0

Please sign in to comment.