github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/tests/test_journal/mock.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  
    16  # pylint: disable=arguments-differ
    17  
    18  from concurrent.futures import Executor
    19  
    20  from sawtooth_validator.execution.scheduler import Scheduler
    21  from sawtooth_validator.execution.scheduler import BatchExecutionResult
    22  from sawtooth_validator.execution.scheduler import TxnExecutionResult
    23  
    24  from sawtooth_validator.journal.batch_sender import BatchSender
    25  from sawtooth_validator.journal.block_sender import BlockSender
    26  from sawtooth_validator.journal.batch_injector import BatchInjectorFactory
    27  from sawtooth_validator.journal.batch_injector import BatchInjector
    28  
    29  from sawtooth_validator.protobuf import batch_pb2
    30  from sawtooth_validator.protobuf import block_pb2
    31  from sawtooth_validator.protobuf.setting_pb2 import Setting
    32  
    33  from sawtooth_validator.state.settings_view import SettingsView
    34  
    35  
    36  class SynchronousExecutor(Executor):
    37      def __init__(self):
    38          self._work_queue = []
    39  
    40      def submit(self, job, *args, **kwargs):
    41          self._work_queue.append((job, args, kwargs))
    42  
    43      def process_next(self):
    44          job = self._work_queue.pop()
    45          job[0](*job[1], **job[2])
    46  
    47      def process_all(self):
    48          while self._work_queue:
    49              self.process_next()
    50  
    51  
    52  class MockNetwork(object):
    53      def __init__(self):
    54          self.messages = []
    55  
    56          def nop_callback(msg):
    57              pass
    58  
    59          self.on_batch_received = nop_callback
    60          self.on_block_received = nop_callback
    61          self.on_block_requested = nop_callback
    62  
    63      def send_message(self, message):
    64          self.messages.append(message)
    65  
    66      @property
    67      def has_messages(self):
    68          return len(self.messages) != 0
    69  
    70      def dispatch_messages(self):
    71          while self.has_messages:
    72              self.dispatch_message()
    73  
    74      def dispatch_message(self):
    75          msg = self.messages.pop()
    76          if isinstance(msg, str):
    77              if self.on_block_request is not None:
    78                  self.on_block_request(msg)
    79          elif isinstance(msg, block_pb2.Block):
    80              if self.on_block_received is not None:
    81                  self.on_block_received(msg)
    82          elif isinstance(msg, batch_pb2.Batch):
    83              if self.on_batch_received is not None:
    84                  self.on_batch_received(msg)
    85  
    86      def clear(self):
    87          self.messages = []
    88  
    89  
    90  class MockScheduler(Scheduler):
    91      def __init__(self, batch_execution_result=True):
    92          self.batches = {}
    93          self.batch_execution_result = batch_execution_result
    94  
    95      def add_batch(self, batch, state_hash=None, required=False):
    96          self.batches[batch.header_signature] = batch
    97  
    98      def get_batch_execution_result(self, batch_signature):
    99          result = True
   100          if self.batch_execution_result is None:
   101              batch = self.batches[batch_signature]
   102              for txn in batch.transactions:
   103                  if txn.payload == b'BAD':
   104                      result = False
   105          else:
   106              result = self.batch_execution_result
   107  
   108          return BatchExecutionResult(
   109              is_valid=result,
   110              state_hash='0' * 70)
   111  
   112      def get_transaction_execution_results(self, batch_signature):
   113          txn_execution_results = []
   114          is_valid_always_false = False
   115          if not self.batch_execution_result:
   116              is_valid_always_false = True
   117  
   118          batch = self.batches[batch_signature]
   119          for txn in batch.transactions:
   120              if is_valid_always_false:
   121                  is_valid = False
   122                  context_id = None
   123              else:
   124                  if txn.payload == b'BAD':
   125                      is_valid = False
   126                      context_id = None
   127                  else:
   128                      is_valid = True
   129                      context_id = "test"
   130              txn_execution_results.append(
   131                  TxnExecutionResult(
   132                      signature=txn.header_signature,
   133                      is_valid=is_valid,
   134                      context_id=context_id,
   135                      state_hash=None))
   136          return txn_execution_results
   137  
   138      def set_transaction_execution_result(
   139              self, txn_signature, is_valid, context_id):
   140          raise NotImplementedError()
   141  
   142      def next_transaction(self):
   143          raise NotImplementedError()
   144  
   145      def unschedule_incomplete_batches(self):
   146          pass
   147  
   148      def is_transaction_in_schedule(self, txn_id):
   149          raise NotImplementedError()
   150  
   151      def finalize(self):
   152          pass
   153  
   154      def complete(self, block):
   155          return True
   156  
   157      def __iter__(self):
   158          raise NotImplementedError()
   159  
   160      def get_transaction(self, index):
   161          raise NotImplementedError()
   162  
   163      def count(self):
   164          raise NotImplementedError()
   165  
   166      def cancel(self):
   167          pass
   168  
   169      def is_cancelled(self):
   170          return False
   171  
   172  
   173  class MockTransactionExecutor(object):
   174      def __init__(self, batch_execution_result=True):
   175          self.messages = []
   176          self.batch_execution_result = batch_execution_result
   177  
   178      def create_scheduler(self, first_state_root):
   179          return MockScheduler(self.batch_execution_result)
   180  
   181      def execute(self, scheduler, state_hash=None):
   182          pass
   183  
   184  
   185  class MockBlockSender(BlockSender):
   186      def __init__(self):
   187          self.new_block = None
   188  
   189      def send(self, block, keep_batches=None):
   190          self.new_block = block
   191  
   192  
   193  class MockBatchSender(BatchSender):
   194      def __init__(self):
   195          self.new_batch = None
   196  
   197      def send(self, batch):
   198          self.new_batch = batch
   199  
   200  
   201  class MockStateViewFactory(object):
   202      """The StateViewFactory produces StateViews for a particular merkle root.
   203  
   204      This factory produces read-only views of a merkle tree. For a given
   205      database, these views are considered immutable.
   206      """
   207  
   208      def __init__(self, database=None):
   209          """Initializes the factory with a given database.
   210  
   211          Args:
   212              database (:obj:`Database`): the database containing the merkle
   213                  tree.
   214          """
   215          self._database = database
   216          if self._database is None:
   217              self._database = {}
   218  
   219      def create_view(self, state_root_hash=None):
   220          """Creates a StateView for the given state root hash.
   221  
   222          Returns:
   223              StateView: state view locked to the given root hash.
   224          """
   225          return MockStateView(self._database)
   226  
   227  
   228  class MockStateView(object):
   229      """The StateView provides read-only access to a particular merkle tree
   230      root.
   231  
   232      The StateView is a read-only view of a merkle tree. Access is limited to
   233      available addresses, collections of leaf nodes, and specific leaf nodes.
   234      The view is lock to a single merkle root, effectively making it an
   235      immutable snapshot.
   236      """
   237  
   238      def __init__(self, tree):
   239          """Creates a StateView with a given merkle tree.
   240  
   241          Args:
   242              tree (:obj:`MerkleDatabase`): the merkle tree for this view
   243          """
   244          self._database = tree
   245  
   246      def get(self, address):
   247          """
   248          Returns:
   249              bytes the state entry at the given address
   250          """
   251          return self._database[address]
   252  
   253      def addresses(self):
   254          """
   255          Returns:
   256              list of str: the list of addresses available in this view
   257          """
   258          return []
   259  
   260      def leaves(self, prefix):
   261          """
   262          Args:
   263              prefix (str): an address prefix under which to look for leaves
   264  
   265          Returns:
   266              dict of str,bytes: the state entries at the leaves
   267          """
   268          return []
   269  
   270  
   271  class MockChainIdManager(object):
   272      """Mock for the ChainIdManager, which provides the value of the
   273      block-chain-id stored in the data_dir.
   274      """
   275  
   276      def __init__(self):
   277          self._block_chain_id = None
   278  
   279      def save_block_chain_id(self, block_chain_id):
   280          self._block_chain_id = block_chain_id
   281  
   282      def get_block_chain_id(self):
   283          return self._block_chain_id
   284  
   285  
   286  # pylint: disable=invalid-name
   287  def CreateSetting(key, value):
   288      """
   289      Create a setting object to include in a MockStateFactory.
   290      """
   291      addr = SettingsView.setting_address(key)
   292  
   293      setting = Setting()
   294      setting.entries.add(key=key, value=str(value))
   295      return addr, setting.SerializeToString()
   296  
   297  
   298  class MockPermissionVerifier(object):
   299      def is_batch_signer_authorized(self, batch, state_root=None,
   300                                     from_state=False):
   301          return True
   302  
   303  
   304  class MockBatchInjectorFactory(BatchInjectorFactory):
   305      def __init__(self, batch):
   306          self._batch = batch
   307  
   308      def create_injectors(self, previous_block_id):
   309          return [MockBatchInjector(self._batch)]
   310  
   311  
   312  class MockBatchInjector(BatchInjector):
   313      def __init__(self, batch):
   314          self._batch = batch
   315  
   316      def block_start(self, previous_block_id):
   317          return [self._batch]