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