github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/sawtooth_validator/consensus/proxy.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  
    17  class UnknownBlock(Exception):
    18      """The given block could not be found."""
    19  
    20  
    21  class ConsensusProxy:
    22      """Receives requests from the consensus engine handlers and delegates them
    23      to the appropriate components."""
    24  
    25      def __init__(self, block_cache, block_publisher,
    26                   chain_controller, gossip, identity_signer,
    27                   settings_view_factory, state_view_factory):
    28          self._block_cache = block_cache
    29          self._chain_controller = chain_controller
    30          self._block_publisher = block_publisher
    31          self._gossip = gossip
    32          self._identity_signer = identity_signer
    33          self._public_key = self._identity_signer.get_public_key().as_bytes()
    34          self._settings_view_factory = settings_view_factory
    35          self._state_view_factory = state_view_factory
    36  
    37      def register(self):
    38          chain_head = self._chain_controller.chain_head
    39  
    40          # not implemented
    41          peers = []
    42  
    43          return chain_head, peers
    44  
    45      # Using network service
    46      def send_to(self, peer_id, message):
    47          self._gossip.send_consensus_message(
    48              peer_id=peer_id.hex(),
    49              message=message,
    50              public_key=self._public_key)
    51  
    52      def broadcast(self, message):
    53          self._gossip.broadcast_consensus_message(
    54              message=message,
    55              public_key=self._public_key)
    56  
    57      # Using block publisher
    58      def initialize_block(self, previous_id):
    59          if previous_id:
    60              try:
    61                  previous_block = self._block_cache[previous_id.hex()]
    62              except KeyError:
    63                  raise UnknownBlock()
    64              self._block_publisher.initialize_block(previous_block)
    65          else:
    66              self._block_publisher.initialize_block(
    67                  self._chain_controller.chain_head)
    68  
    69      def summarize_block(self):
    70          return self._block_publisher.summarize_block()
    71  
    72      def finalize_block(self, consensus_data):
    73          result = self._block_publisher.finalize_block(
    74              consensus=consensus_data)
    75          return bytes.fromhex(
    76              self._block_publisher.publish_block(
    77                  result.block, result.injected_batches))
    78  
    79      def cancel_block(self):
    80          self._block_publisher.cancel_block()
    81  
    82      # Using chain controller
    83      def check_blocks(self, block_ids):
    84          try:
    85              blocks = [
    86                  self._block_cache[block_id.hex()]
    87                  for block_id in block_ids
    88              ]
    89          except KeyError as key_error:
    90              raise UnknownBlock(key_error.args[0])
    91  
    92          self._chain_controller.submit_blocks_for_verification(blocks)
    93  
    94      def commit_block(self, block_id):
    95          try:
    96              block = self._block_cache[block_id.hex()]
    97          except KeyError as key_error:
    98              raise UnknownBlock(key_error.args[0])
    99          self._chain_controller.commit_block(block)
   100  
   101      def ignore_block(self, block_id):
   102          try:
   103              block = self._block_cache[block_id.hex()]
   104          except KeyError:
   105              raise UnknownBlock()
   106          self._chain_controller.ignore_block(block)
   107  
   108      def fail_block(self, block_id):
   109          try:
   110              block = self._block_cache[block_id.hex()]
   111          except KeyError:
   112              raise UnknownBlock()
   113          self._chain_controller.fail_block(block)
   114  
   115      # Using blockstore and state database
   116      def blocks_get(self, block_ids):
   117          '''Returns a list of blocks.'''
   118          return self._get_blocks(block_ids)
   119  
   120      def chain_head_get(self):
   121          '''Returns the chain head.'''
   122  
   123          chain_head = self._chain_controller.chain_head
   124  
   125          if chain_head is None:
   126              raise UnknownBlock()
   127  
   128          return chain_head
   129  
   130      def settings_get(self, block_id, settings):
   131          '''Returns a list of key/value pairs (str, str).'''
   132          settings_view = \
   133              self._get_blocks([block_id])[0].get_settings_view(
   134                  self._settings_view_factory)
   135  
   136          return _map_with_none(settings_view.get_setting, settings)
   137  
   138      def state_get(self, block_id, addresses):
   139          '''Returns a list of address/data pairs (str, bytes)'''
   140          state_view = \
   141              self._get_blocks([block_id])[0].get_state_view(
   142                  self._state_view_factory)
   143  
   144          return _map_with_none(state_view.get, addresses)
   145  
   146      def _get_blocks(self, block_ids):
   147          try:
   148              return [
   149                  self._block_cache[block_id.hex()]
   150                  for block_id in block_ids
   151              ]
   152          except KeyError:
   153              raise UnknownBlock()
   154  
   155  
   156  def _map_with_none(function, keys):
   157      result = []
   158  
   159      for key in keys:
   160          try:
   161              value = function(key)
   162          except KeyError:
   163              value = None
   164  
   165          result.append((key, value))
   166  
   167      return result