github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/sawtooth_validator/consensus/handlers.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  
    17  import logging
    18  
    19  from google.protobuf.message import DecodeError
    20  
    21  from sawtooth_validator.consensus.proxy import UnknownBlock
    22  
    23  from sawtooth_validator.protobuf import consensus_pb2
    24  from sawtooth_validator.protobuf import validator_pb2
    25  
    26  from sawtooth_validator.networking.dispatch import Handler
    27  from sawtooth_validator.networking.dispatch import HandlerResult
    28  from sawtooth_validator.networking.dispatch import HandlerStatus
    29  
    30  from sawtooth_validator.protobuf.consensus_pb2 import ConsensusSettingsEntry
    31  from sawtooth_validator.protobuf.consensus_pb2 import ConsensusStateEntry
    32  
    33  
    34  LOGGER = logging.getLogger(__name__)
    35  
    36  
    37  class BlockEmpty(Exception):
    38      """There are no batches in the block."""
    39  
    40  
    41  class BlockInProgress(Exception):
    42      """There is already a block in progress."""
    43  
    44  
    45  class BlockNotInitialized(Exception):
    46      """There is no block in progress to finalize."""
    47  
    48  
    49  class ConsensusServiceHandler(Handler):
    50      def __init__(
    51          self,
    52          request_class,
    53          request_type,
    54          response_class,
    55          response_type,
    56      ):
    57          self._request_class = request_class
    58          self._request_type = request_type
    59          self._response_class = response_class
    60          self._response_type = response_type
    61  
    62      def handle_request(self, request, response):
    63          raise NotImplementedError()
    64  
    65      @property
    66      def request_class(self):
    67          return self._request_class
    68  
    69      @property
    70      def response_class(self):
    71          return self._response_class
    72  
    73      @property
    74      def response_type(self):
    75          return self._response_type
    76  
    77      @property
    78      def request_type(self):
    79          return self._request_type
    80  
    81      def handle(self, connection_id, message_content):
    82          request = self._request_class()
    83          response = self._response_class()
    84          response.status = response.OK
    85  
    86          try:
    87              request.ParseFromString(message_content)
    88          except DecodeError:
    89              response.status = response.BAD_REQUEST
    90          else:
    91              self.handle_request(request, response)
    92  
    93          return HandlerResult(
    94              status=HandlerStatus.RETURN,
    95              message_out=response,
    96              message_type=self._response_type)
    97  
    98  
    99  class ConsensusRegisterHandler(ConsensusServiceHandler):
   100      def __init__(self, proxy):
   101          super().__init__(
   102              consensus_pb2.ConsensusRegisterRequest,
   103              validator_pb2.Message.CONSENSUS_REGISTER_REQUEST,
   104              consensus_pb2.ConsensusRegisterResponse,
   105              validator_pb2.Message.CONSENSUS_REGISTER_RESPONSE)
   106  
   107          self._proxy = proxy
   108  
   109      def handle_request(self, request, response):
   110          chain_head, peers = self._proxy.register()
   111  
   112          if chain_head is None:
   113              response.status = consensus_pb2.ConsensusRegisterResponse.NOT_READY
   114              return
   115  
   116          response.chain_head.block_id = bytes.fromhex(chain_head.identifier)
   117          response.chain_head.previous_id =\
   118              bytes.fromhex(chain_head.previous_block_id)
   119          response.chain_head.signer_id =\
   120              bytes.fromhex(chain_head.signer_public_key)
   121          response.chain_head.block_num = chain_head.block_num
   122          response.chain_head.payload = chain_head.consensus
   123  
   124          response.peers.extend(peers)
   125  
   126          LOGGER.info(
   127              "Consensus engine registered: %s %s",
   128              request.name,
   129              request.version)
   130  
   131  
   132  class ConsensusSendToHandler(ConsensusServiceHandler):
   133      def __init__(self, proxy):
   134          super().__init__(
   135              consensus_pb2.ConsensusSendToRequest,
   136              validator_pb2.Message.CONSENSUS_SEND_TO_REQUEST,
   137              consensus_pb2.ConsensusSendToResponse,
   138              validator_pb2.Message.CONSENSUS_SEND_TO_RESPONSE)
   139          self._proxy = proxy
   140  
   141      def handle_request(self, request, response):
   142          try:
   143              self._proxy.send_to(
   144                  request.peer_id,
   145                  request.message.SerializeToString())
   146          except Exception:  # pylint: disable=broad-except
   147              LOGGER.exception("ConsensusSendTo")
   148              response.status =\
   149                  consensus_pb2.ConsensusSendToResponse.SERVICE_ERROR
   150  
   151  
   152  class ConsensusBroadcastHandler(ConsensusServiceHandler):
   153      def __init__(self, proxy):
   154          super().__init__(
   155              consensus_pb2.ConsensusBroadcastRequest,
   156              validator_pb2.Message.CONSENSUS_BROADCAST_REQUEST,
   157              consensus_pb2.ConsensusBroadcastResponse,
   158              validator_pb2.Message.CONSENSUS_BROADCAST_RESPONSE)
   159  
   160          self._proxy = proxy
   161  
   162      def handle_request(self, request, response):
   163          try:
   164              self._proxy.broadcast(request.message.SerializeToString())
   165          except Exception:  # pylint: disable=broad-except
   166              LOGGER.exception("ConsensusBroadcast")
   167              response.status =\
   168                  consensus_pb2.ConsensusBroadcastResponse.SERVICE_ERROR
   169  
   170  
   171  class ConsensusInitializeBlockHandler(ConsensusServiceHandler):
   172      def __init__(self, proxy):
   173          super().__init__(
   174              consensus_pb2.ConsensusInitializeBlockRequest,
   175              validator_pb2.Message.CONSENSUS_INITIALIZE_BLOCK_REQUEST,
   176              consensus_pb2.ConsensusInitializeBlockResponse,
   177              validator_pb2.Message.CONSENSUS_INITIALIZE_BLOCK_RESPONSE)
   178  
   179          self._proxy = proxy
   180  
   181      def handle_request(self, request, response):
   182          try:
   183              self._proxy.initialize_block(request.previous_id)
   184          except BlockInProgress:
   185              response.status =\
   186                  consensus_pb2.ConsensusInitializeBlockResponse.INVALID_STATE
   187          except Exception:  # pylint: disable=broad-except
   188              LOGGER.exception("ConsensusInitializeBlock")
   189              response.status =\
   190                  consensus_pb2.ConsensusInitializeBlockResponse.SERVICE_ERROR
   191  
   192  
   193  class ConsensusSummarizeBlockHandler(ConsensusServiceHandler):
   194      def __init__(self, proxy):
   195          super().__init__(
   196              consensus_pb2.ConsensusSummarizeBlockRequest,
   197              validator_pb2.Message.CONSENSUS_SUMMARIZE_BLOCK_REQUEST,
   198              consensus_pb2.ConsensusSummarizeBlockResponse,
   199              validator_pb2.Message.CONSENSUS_SUMMARIZE_BLOCK_RESPONSE)
   200  
   201          self._proxy = proxy
   202  
   203      def handle_request(self, request, response):
   204          try:
   205              summary = self._proxy.summarize_block()
   206              response.summary = summary
   207          except BlockNotInitialized:
   208              response.status =\
   209                  consensus_pb2.ConsensusSummarizeBlockResponse.INVALID_STATE
   210          except BlockEmpty:
   211              response.status =\
   212                  consensus_pb2.ConsensusSummarizeBlockResponse.BLOCK_NOT_READY
   213          except Exception:  # pylint: disable=broad-except
   214              LOGGER.exception("ConsensusSummarizeBlock")
   215              response.status =\
   216                  consensus_pb2.ConsensusSummarizeBlockResponse.SERVICE_ERROR
   217  
   218  
   219  class ConsensusFinalizeBlockHandler(ConsensusServiceHandler):
   220      def __init__(self, proxy):
   221          super().__init__(
   222              consensus_pb2.ConsensusFinalizeBlockRequest,
   223              validator_pb2.Message.CONSENSUS_FINALIZE_BLOCK_REQUEST,
   224              consensus_pb2.ConsensusFinalizeBlockResponse,
   225              validator_pb2.Message.CONSENSUS_FINALIZE_BLOCK_RESPONSE)
   226  
   227          self._proxy = proxy
   228  
   229      def handle_request(self, request, response):
   230          try:
   231              response.block_id = self._proxy.finalize_block(request.data)
   232          except BlockNotInitialized:
   233              response.status =\
   234                  consensus_pb2.ConsensusFinalizeBlockResponse.INVALID_STATE
   235          except BlockEmpty:
   236              response.status =\
   237                  consensus_pb2.ConsensusFinalizeBlockResponse.BLOCK_NOT_READY
   238          except Exception:  # pylint: disable=broad-except
   239              LOGGER.exception("ConsensusFinalizeBlock")
   240              response.status =\
   241                  consensus_pb2.ConsensusFinalizeBlockResponse.SERVICE_ERROR
   242  
   243  
   244  class ConsensusCancelBlockHandler(ConsensusServiceHandler):
   245      def __init__(self, proxy):
   246          super().__init__(
   247              consensus_pb2.ConsensusCancelBlockRequest,
   248              validator_pb2.Message.CONSENSUS_CANCEL_BLOCK_REQUEST,
   249              consensus_pb2.ConsensusCancelBlockResponse,
   250              validator_pb2.Message.CONSENSUS_CANCEL_BLOCK_RESPONSE)
   251  
   252          self._proxy = proxy
   253  
   254      def handle_request(self, request, response):
   255          try:
   256              self._proxy.cancel_block()
   257          except BlockNotInitialized:
   258              response.status =\
   259                  consensus_pb2.ConsensusCancelBlockResponse.INVALID_STATE
   260          except Exception:  # pylint: disable=broad-except
   261              LOGGER.exception("ConsensusCancelBlock")
   262              response.status =\
   263                  consensus_pb2.ConsensusCancelBlockResponse.SERVICE_ERROR
   264  
   265  
   266  class ConsensusCheckBlocksHandler(ConsensusServiceHandler):
   267      def __init__(self, proxy):
   268          super().__init__(
   269              consensus_pb2.ConsensusCheckBlocksRequest,
   270              validator_pb2.Message.CONSENSUS_CHECK_BLOCKS_REQUEST,
   271              consensus_pb2.ConsensusCheckBlocksResponse,
   272              validator_pb2.Message.CONSENSUS_CHECK_BLOCKS_RESPONSE)
   273  
   274          self._proxy = proxy
   275  
   276      def handle_request(self, request, response):
   277          try:
   278              self._proxy.check_blocks(request.block_ids)
   279          except UnknownBlock:
   280              response.status =\
   281                  consensus_pb2.ConsensusCheckBlocksResponse.UNKNOWN_BLOCK
   282          except Exception:  # pylint: disable=broad-except
   283              LOGGER.exception("ConsensusCheckBlocks")
   284              response.status =\
   285                  consensus_pb2.ConsensusCheckBlocksResponse.SERVICE_ERROR
   286  
   287  
   288  class ConsensusCommitBlockHandler(ConsensusServiceHandler):
   289      def __init__(self, proxy):
   290          super().__init__(
   291              consensus_pb2.ConsensusCommitBlockRequest,
   292              validator_pb2.Message.CONSENSUS_COMMIT_BLOCK_REQUEST,
   293              consensus_pb2.ConsensusCommitBlockResponse,
   294              validator_pb2.Message.CONSENSUS_COMMIT_BLOCK_RESPONSE)
   295  
   296          self._proxy = proxy
   297  
   298      def handle_request(self, request, response):
   299          try:
   300              self._proxy.commit_block(request.block_id)
   301          except UnknownBlock:
   302              response.status =\
   303                  consensus_pb2.ConsensusCommitBlockResponse.UNKNOWN_BLOCK
   304          except Exception:  # pylint: disable=broad-except
   305              LOGGER.exception("ConsensusCommitBlock")
   306              response.status =\
   307                  consensus_pb2.ConsensusCommitBlockResponse.SERVICE_ERROR
   308  
   309  
   310  class ConsensusIgnoreBlockHandler(ConsensusServiceHandler):
   311      def __init__(self, proxy):
   312          super().__init__(
   313              consensus_pb2.ConsensusIgnoreBlockRequest,
   314              validator_pb2.Message.CONSENSUS_IGNORE_BLOCK_REQUEST,
   315              consensus_pb2.ConsensusIgnoreBlockResponse,
   316              validator_pb2.Message.CONSENSUS_IGNORE_BLOCK_RESPONSE)
   317  
   318          self._proxy = proxy
   319  
   320      def handle_request(self, request, response):
   321          try:
   322              self._proxy.ignore_block(request.block_id)
   323          except UnknownBlock:
   324              response.status =\
   325                  consensus_pb2.ConsensusIgnoreBlockResponse.UNKNOWN_BLOCK
   326          except Exception:  # pylint: disable=broad-except
   327              LOGGER.exception("ConsensusIgnoreBlock")
   328              response.status =\
   329                  consensus_pb2.ConsensusIgnoreBlockResponse.SERVICE_ERROR
   330  
   331  
   332  class ConsensusFailBlockHandler(ConsensusServiceHandler):
   333      def __init__(self, proxy):
   334          super().__init__(
   335              consensus_pb2.ConsensusFailBlockRequest,
   336              validator_pb2.Message.CONSENSUS_FAIL_BLOCK_REQUEST,
   337              consensus_pb2.ConsensusFailBlockResponse,
   338              validator_pb2.Message.CONSENSUS_FAIL_BLOCK_RESPONSE)
   339  
   340          self._proxy = proxy
   341  
   342      def handle_request(self, request, response):
   343          try:
   344              self._proxy.fail_block(request.block_id)
   345          except UnknownBlock:
   346              response.status =\
   347                  consensus_pb2.ConsensusFailBlockResponse.UNKNOWN_BLOCK
   348          except Exception:  # pylint: disable=broad-except
   349              LOGGER.exception("ConsensusFailBlock")
   350              response.status =\
   351                  consensus_pb2.ConsensusFailBlockResponse.SERVICE_ERROR
   352  
   353  
   354  class ConsensusBlocksGetHandler(ConsensusServiceHandler):
   355      def __init__(self, proxy):
   356          super().__init__(
   357              consensus_pb2.ConsensusBlocksGetRequest,
   358              validator_pb2.Message.CONSENSUS_BLOCKS_GET_REQUEST,
   359              consensus_pb2.ConsensusBlocksGetResponse,
   360              validator_pb2.Message.CONSENSUS_BLOCKS_GET_RESPONSE)
   361  
   362          self._proxy = proxy
   363  
   364      def handle_request(self, request, response):
   365          try:
   366              response.blocks.extend([
   367                  consensus_pb2.ConsensusBlock(
   368                      block_id=bytes.fromhex(block.identifier),
   369                      previous_id=bytes.fromhex(block.previous_block_id),
   370                      signer_id=bytes.fromhex(block.signer_public_key),
   371                      block_num=block.block_num,
   372                      payload=block.consensus)
   373                  for block in self._proxy.blocks_get(request.block_ids)
   374              ])
   375          except UnknownBlock:
   376              response.status =\
   377                  consensus_pb2.ConsensusBlocksGetResponse.UNKNOWN_BLOCK
   378          except Exception:  # pylint: disable=broad-except
   379              LOGGER.exception("ConsensusBlocksGet")
   380              response.status =\
   381                  consensus_pb2.ConsensusBlocksGetResponse.SERVICE_ERROR
   382  
   383  
   384  class ConsensusChainHeadGetHandler(ConsensusServiceHandler):
   385      def __init__(self, proxy):
   386          super().__init__(
   387              consensus_pb2.ConsensusChainHeadGetRequest,
   388              validator_pb2.Message.CONSENSUS_CHAIN_HEAD_GET_REQUEST,
   389              consensus_pb2.ConsensusChainHeadGetResponse,
   390              validator_pb2.Message.CONSENSUS_CHAIN_HEAD_GET_RESPONSE)
   391  
   392          self._proxy = proxy
   393  
   394      def handle_request(self, request, response):
   395          try:
   396              chain_head = self._proxy.chain_head_get()
   397              response.block.block_id = bytes.fromhex(chain_head.identifier)
   398              response.block.previous_id =\
   399                  bytes.fromhex(chain_head.previous_block_id)
   400              response.block.signer_id =\
   401                  bytes.fromhex(chain_head.signer_public_key)
   402              response.block.block_num = chain_head.block_num
   403              response.block.payload = chain_head.consensus
   404          except UnknownBlock:
   405              response.status =\
   406                  consensus_pb2.ConsensusChainHeadGetResponse.NO_CHAIN_HEAD
   407          except Exception:  # pylint: disable=broad-except
   408              LOGGER.exception("ConsensusChainHeadGet")
   409              response.status =\
   410                  consensus_pb2.ConsensusChainHeadGetResponse.SERVICE_ERROR
   411  
   412  
   413  class ConsensusSettingsGetHandler(ConsensusServiceHandler):
   414      def __init__(self, proxy):
   415          super().__init__(
   416              consensus_pb2.ConsensusSettingsGetRequest,
   417              validator_pb2.Message.CONSENSUS_SETTINGS_GET_REQUEST,
   418              consensus_pb2.ConsensusSettingsGetResponse,
   419              validator_pb2.Message.CONSENSUS_SETTINGS_GET_RESPONSE)
   420  
   421          self._proxy = proxy
   422  
   423      def handle_request(self, request, response):
   424          try:
   425              response.entries.extend([
   426                  ConsensusSettingsEntry(
   427                      key=key,
   428                      value=value)
   429                  for key, value in self._proxy.settings_get(
   430                      request.block_id, request.keys)
   431              ])
   432          except UnknownBlock:
   433              response.status = \
   434                  consensus_pb2.ConsensusSettingsGetResponse.UNKNOWN_BLOCK
   435          except Exception:  # pylint: disable=broad-except
   436              LOGGER.exception("ConsensusSettingsGet")
   437              response.status =\
   438                  consensus_pb2.ConsensusSettingsGetResponse.SERVICE_ERROR
   439  
   440  
   441  class ConsensusStateGetHandler(ConsensusServiceHandler):
   442      def __init__(self, proxy):
   443          super().__init__(
   444              consensus_pb2.ConsensusStateGetRequest,
   445              validator_pb2.Message.CONSENSUS_STATE_GET_REQUEST,
   446              consensus_pb2.ConsensusStateGetResponse,
   447              validator_pb2.Message.CONSENSUS_STATE_GET_RESPONSE)
   448  
   449          self._proxy = proxy
   450  
   451      def handle_request(self, request, response):
   452          try:
   453              response.entries.extend([
   454                  ConsensusStateEntry(
   455                      address=address,
   456                      data=data)
   457                  for address, data in self._proxy.state_get(
   458                      request.block_id, request.addresses)
   459              ])
   460          except UnknownBlock:
   461              response.status = \
   462                  consensus_pb2.ConsensusStateGetResponse.UNKNOWN_BLOCK
   463          except Exception:  # pylint: disable=broad-except
   464              LOGGER.exception("ConsensusStateGet")
   465              response.status =\
   466                  consensus_pb2.ConsensusStateGetResponse.SERVICE_ERROR