github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/integration/sawtooth_integration/tests/test_state_verifier.py (about)

     1  # Copyright 2018 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  
    16  import logging
    17  import hashlib
    18  import unittest
    19  import os
    20  import shutil
    21  import tempfile
    22  import cbor
    23  
    24  from sawtooth_signing import create_context
    25  from sawtooth_signing import CryptoFactory
    26  
    27  from sawtooth_validator.database.dict_database import DictDatabase
    28  from sawtooth_validator.database.native_lmdb import NativeLmdbDatabase
    29  from sawtooth_validator.state.merkle import MerkleDatabase
    30  from sawtooth_validator.journal.block_store import BlockStore
    31  from sawtooth_validator.journal.block_wrapper import BlockWrapper
    32  from sawtooth_validator.journal.block_wrapper import NULL_BLOCK_IDENTIFIER
    33  
    34  from sawtooth_validator.protobuf.block_pb2 import Block
    35  from sawtooth_validator.protobuf.block_pb2 import BlockHeader
    36  from sawtooth_validator.protobuf.batch_pb2 import Batch
    37  from sawtooth_validator.protobuf.batch_pb2 import BatchHeader
    38  from sawtooth_validator.protobuf.transaction_pb2 import Transaction
    39  from sawtooth_validator.protobuf.transaction_pb2 import TransactionHeader
    40  
    41  from sawtooth_validator.server.state_verifier import verify_state
    42  
    43  
    44  LOGGER = logging.getLogger(__name__)
    45  
    46  
    47  def get_signer():
    48      context = create_context('secp256k1')
    49      private_key = context.new_random_private_key()
    50      crypto_factory = CryptoFactory(context)
    51      return crypto_factory.new_signer(private_key)
    52  
    53  
    54  def populate_blockstore(blockstore, signer, state_roots):
    55      txns = [
    56          create_intkey_transaction("set", str(i), 0, [], signer)
    57          for i, _ in enumerate(state_roots)
    58      ]
    59      batches = [
    60          create_batch([txn], signer)
    61          for txn in txns
    62      ]
    63      blocks = []
    64  
    65      for i, batch in enumerate(batches):
    66          if not blocks:
    67              previous_block_id = NULL_BLOCK_IDENTIFIER
    68          else:
    69              previous_block_id = blocks[-1].header_signature
    70          block = create_block(
    71              batch=batch,
    72              block_num=i,
    73              previous_block_id=previous_block_id,
    74              state_root_hash=state_roots[i],
    75              signer=signer)
    76          blocks.append(block)
    77  
    78      for block in blocks:
    79          blockstore[block.header_signature] = block
    80  
    81  
    82  def make_intkey_address(name):
    83      return INTKEY_ADDRESS_PREFIX + hashlib.sha512(
    84          name.encode('utf-8')).hexdigest()[-64:]
    85  
    86  
    87  INTKEY_ADDRESS_PREFIX = hashlib.sha512(
    88      'intkey'.encode('utf-8')).hexdigest()[0:6]
    89  
    90  
    91  class IntKeyPayload(object):
    92      def __init__(self, verb, name, value):
    93          self._verb = verb
    94          self._name = name
    95          self._value = value
    96  
    97          self._cbor = None
    98          self._sha512 = None
    99  
   100      def to_hash(self):
   101          return {
   102              'Verb': self._verb,
   103              'Name': self._name,
   104              'Value': self._value
   105          }
   106  
   107      def to_cbor(self):
   108          if self._cbor is None:
   109              self._cbor = cbor.dumps(self.to_hash(), sort_keys=True)
   110          return self._cbor
   111  
   112      def sha512(self):
   113          if self._sha512 is None:
   114              self._sha512 = hashlib.sha512(self.to_cbor()).hexdigest()
   115          return self._sha512
   116  
   117  
   118  def create_intkey_transaction(verb, name, value, deps, signer):
   119      payload = IntKeyPayload(
   120          verb=verb, name=name, value=value)
   121  
   122      # The prefix should eventually be looked up from the
   123      # validator's namespace registry.
   124      addr = make_intkey_address(name)
   125  
   126      header = TransactionHeader(
   127          signer_public_key=signer.get_public_key().as_hex(),
   128          family_name='intkey',
   129          family_version='1.0',
   130          inputs=[addr],
   131          outputs=[addr],
   132          dependencies=deps,
   133          payload_sha512=payload.sha512(),
   134          batcher_public_key=signer.get_public_key().as_hex())
   135  
   136      header_bytes = header.SerializeToString()
   137  
   138      signature = signer.sign(header_bytes)
   139  
   140      transaction = Transaction(
   141          header=header_bytes,
   142          payload=payload.to_cbor(),
   143          header_signature=signature)
   144  
   145      return transaction
   146  
   147  
   148  def create_batch(transactions, signer):
   149      transaction_signatures = [t.header_signature for t in transactions]
   150  
   151      header = BatchHeader(
   152          signer_public_key=signer.get_public_key().as_hex(),
   153          transaction_ids=transaction_signatures)
   154  
   155      header_bytes = header.SerializeToString()
   156  
   157      signature = signer.sign(header_bytes)
   158  
   159      batch = Batch(
   160          header=header_bytes,
   161          transactions=transactions,
   162          header_signature=signature)
   163  
   164      return batch
   165  
   166  
   167  def create_block(batch, block_num, previous_block_id, state_root_hash, signer):
   168      header = BlockHeader(
   169          block_num=block_num,
   170          previous_block_id=previous_block_id,
   171          state_root_hash=state_root_hash,
   172          signer_public_key=signer.get_public_key().as_hex(),
   173      ).SerializeToString()
   174  
   175      block = Block(
   176          header=header,
   177          batches=[batch],
   178          header_signature=signer.sign(header))
   179  
   180      block_wrapper = BlockWrapper(block)
   181      return block_wrapper
   182  
   183  
   184  class TestStateVerifier(unittest.TestCase):
   185      def __init__(self, test_name):
   186          super().__init__(test_name)
   187          self._temp_dir = None
   188  
   189      def setUp(self):
   190          self._temp_dir = tempfile.mkdtemp()
   191  
   192      def tearDown(self):
   193          shutil.rmtree(self._temp_dir)
   194  
   195      def test_state_verifier(self):
   196          blockstore = BlockStore(DictDatabase(
   197              indexes=BlockStore.create_index_configuration()))
   198          global_state_db = NativeLmdbDatabase(
   199              os.path.join(self._temp_dir, 'test_state_verifier.lmdb'),
   200              indexes=MerkleDatabase.create_index_configuration())
   201  
   202          precalculated_state_roots = [
   203              "e35490eac6f77453675c3399da7efe451e791272bbc8cf1b032c75030fb455c3",
   204              "3a369eb951171895c00ba2ffd04bfa1ef98d6ee651f96a65ae3280cf8d67d5e7",
   205              "797e70e29915c9129f950b2084ed0e3c09246bd1e6c232571456f51ca85df340",
   206          ]
   207  
   208          signer = get_signer()
   209          populate_blockstore(blockstore, signer, precalculated_state_roots)
   210  
   211          verify_state(
   212              global_state_db,
   213              blockstore,
   214              "tcp://eth0:4004",
   215              "serial")
   216  
   217          # There is a bug in the shutdown code for some component this depends
   218          # on, which causes it to occassionally hang during shutdown. Just kill
   219          # the process for now.
   220          # pylint: disable=protected-access
   221          os._exit(0)