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)