github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/cli/sawtooth_cli/admin_command/genesis.py (about) 1 # Copyright 2017 Intel Corporation 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # ------------------------------------------------------------------------------ 15 import os 16 17 from sawtooth_cli.admin_command.config import get_data_dir 18 from sawtooth_cli.exceptions import CliException 19 20 from sawtooth_cli.protobuf.batch_pb2 import BatchList 21 from sawtooth_cli.protobuf.genesis_pb2 import GenesisData 22 from sawtooth_cli.protobuf.transaction_pb2 import TransactionHeader 23 24 25 def add_genesis_parser(subparsers, parent_parser): 26 """Creates the arg parsers needed for the genesis command. 27 """ 28 parser = subparsers.add_parser( 29 'genesis', 30 help='Creates the genesis.batch file for initializing the validator', 31 description='Generates the genesis.batch file for ' 32 'initializing the validator.', 33 epilog='This command generates a serialized GenesisData protobuf ' 34 'message and stores it in the genesis.batch file. One or more input ' 35 'files (optional) can contain serialized BatchList protobuf messages ' 36 'to add to the GenesisData. The output shows the location of this ' 37 'file. By default, the genesis.batch file is stored in ' 38 '/var/lib/sawtooth. If $SAWTOOTH_HOME is set, the location is ' 39 '$SAWTOOTH_HOME/data/genesis.batch. Use the --output option to change ' 40 'the name of the file.', 41 parents=[parent_parser]) 42 43 parser.add_argument( 44 '-o', '--output', 45 type=str, 46 help='choose the output file for GenesisData') 47 48 parser.add_argument( 49 'input_file', 50 nargs='*', 51 type=str, 52 help='file or files containing batches to add to the resulting ' 53 'GenesisData') 54 55 56 def do_genesis(args, data_dir=None): 57 """Given the command args, take an series of input files containing 58 GenesisData, combine all the batches into one GenesisData, and output the 59 result into a new file. 60 """ 61 62 if data_dir is None: 63 data_dir = get_data_dir() 64 65 if not os.path.exists(data_dir): 66 raise CliException( 67 "Data directory does not exist: {}".format(data_dir)) 68 69 genesis_batches = [] 70 for input_file in args.input_file: 71 print('Processing {}...'.format(input_file)) 72 input_data = BatchList() 73 try: 74 with open(input_file, 'rb') as in_file: 75 input_data.ParseFromString(in_file.read()) 76 except: 77 raise CliException('Unable to read {}'.format(input_file)) 78 79 genesis_batches += input_data.batches 80 81 _validate_depedencies(genesis_batches) 82 if args.output: 83 genesis_file = args.output 84 else: 85 genesis_file = os.path.join(data_dir, 'genesis.batch') 86 87 print('Generating {}'.format(genesis_file)) 88 output_data = GenesisData(batches=genesis_batches) 89 with open(genesis_file, 'wb') as out_file: 90 out_file.write(output_data.SerializeToString()) 91 92 93 def _validate_depedencies(batches): 94 """Validates the transaction dependencies for the transactions contained 95 within the sequence of batches. Given that all the batches are expected to 96 to be executed for the genesis blocks, it is assumed that any dependent 97 transaction will proceed the depending transaction. 98 """ 99 transaction_ids = set() 100 for batch in batches: 101 for txn in batch.transactions: 102 txn_header = TransactionHeader() 103 txn_header.ParseFromString(txn.header) 104 105 if txn_header.dependencies: 106 unsatisfied_deps = [ 107 id for id in txn_header.dependencies 108 if id not in transaction_ids 109 ] 110 if unsatisfied_deps: 111 raise CliException( 112 'Unsatisfied dependency in given transactions:' 113 ' {}'.format(unsatisfied_deps)) 114 115 transaction_ids.add(txn.header_signature)