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