github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/sawtooth_validator/journal/chain.py (about)

     1  # Copyright 2017-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  from abc import ABCMeta
    16  from abc import abstractmethod
    17  import ctypes
    18  from enum import IntEnum
    19  
    20  from sawtooth_validator.ffi import PY_LIBRARY
    21  from sawtooth_validator.ffi import LIBRARY
    22  from sawtooth_validator.ffi import CommonErrorCode
    23  from sawtooth_validator.ffi import OwnedPointer
    24  
    25  
    26  class ChainObserver(object, metaclass=ABCMeta):
    27      @abstractmethod
    28      def chain_update(self, block, receipts):
    29          """This method is called by the ChainController on block boundaries.
    30  
    31          Args:
    32              block (:obj:`BlockWrapper`): The block that was just committed.
    33              receipts (dict of {str: receipt}): Map of transaction signatures to
    34                  transaction receipts for all transactions in the block."""
    35          raise NotImplementedError()
    36  
    37  
    38  class ChainController(OwnedPointer):
    39      def __init__(
    40          self,
    41          block_store,
    42          block_cache,
    43          block_validator,
    44          state_database,
    45          chain_head_lock,
    46          state_pruning_block_depth=1000,
    47          data_dir=None,
    48          observers=None
    49      ):
    50          super(ChainController, self).__init__('chain_controller_drop')
    51  
    52          if data_dir is None:
    53              data_dir = ''
    54  
    55          if observers is None:
    56              observers = []
    57  
    58          _pylibexec(
    59              'chain_controller_new',
    60              ctypes.py_object(block_store),
    61              ctypes.py_object(block_cache),
    62              ctypes.py_object(block_validator),
    63              state_database.pointer,
    64              chain_head_lock.pointer,
    65              ctypes.py_object(observers),
    66              ctypes.c_long(state_pruning_block_depth),
    67              ctypes.c_char_p(data_dir.encode()),
    68              ctypes.byref(self.pointer))
    69  
    70      def start(self):
    71          _libexec('chain_controller_start', self.pointer)
    72  
    73      def stop(self):
    74          _libexec('chain_controller_stop', self.pointer)
    75  
    76      def has_block(self, block_id):
    77          result = ctypes.c_bool()
    78  
    79          _libexec('chain_controller_has_block',
    80                   self.pointer, ctypes.c_char_p(block_id.encode()),
    81                   ctypes.byref(result))
    82          return result.value
    83  
    84      def queue_block(self, block):
    85          _pylibexec('chain_controller_queue_block', self.pointer,
    86                     ctypes.py_object(block))
    87  
    88      def on_block_received(self, block_wrapper):
    89          """This is exposed for unit tests, and should not be called directly.
    90          """
    91          _pylibexec('chain_controller_on_block_received', self.pointer,
    92                     ctypes.py_object(block_wrapper))
    93  
    94      @property
    95      def chain_head(self):
    96          result = ctypes.py_object()
    97  
    98          _pylibexec('chain_controller_chain_head',
    99                     self.pointer,
   100                     ctypes.byref(result))
   101  
   102          return result.value
   103  
   104  
   105  class ValidationResponseSender(OwnedPointer):
   106      def __init__(self, sender_ptr):
   107          super(ValidationResponseSender, self).__init__(
   108              'sender_drop', initialized_ptr=sender_ptr)
   109  
   110      def send(self, can_commit, result):
   111          _pylibexec('sender_send', self.pointer,
   112                     ctypes.py_object((can_commit, result)))
   113  
   114  
   115  def _libexec(name, *args):
   116      return _exec(LIBRARY, name, *args)
   117  
   118  
   119  def _pylibexec(name, *args):
   120      return _exec(PY_LIBRARY, name, *args)
   121  
   122  
   123  def _exec(library, name, *args):
   124      res = library.call(name, *args)
   125      if res == ErrorCode.Success:
   126          return
   127      elif res == ErrorCode.NullPointerProvided:
   128          raise ValueError("Provided null pointer(s)")
   129      elif res == ErrorCode.InvalidDataDir:
   130          raise ValueError("Invalid data dir")
   131      elif res == ErrorCode.InvalidPythonObject:
   132          raise ValueError("Invalid python object submitted")
   133      elif res == ErrorCode.InvalidBlockId:
   134          raise ValueError("Invalid block id provided.")
   135      else:
   136          raise TypeError("Unknown error occurred: {}".format(res.error))
   137  
   138  
   139  class ErrorCode(IntEnum):
   140      Success = CommonErrorCode.Success
   141      NullPointerProvided = CommonErrorCode.NullPointerProvided
   142      InvalidDataDir = 0x02
   143      InvalidPythonObject = 0x03
   144      InvalidBlockId = 0x04