github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-supply-chain-master/tests/sawtooth_sc_test/supply_chain_message_factory.py (about) 1 # Copyright 2017 Intel Corporation 2 # Copyright 2018 Cargill Incorporated 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 # ------------------------------------------------------------------------------ 16 17 import logging 18 import time 19 20 from sawtooth_processor_test.message_factory import MessageFactory 21 22 from sawtooth_sc_test.protobuf.payload_pb2 import SCPayload 23 from sawtooth_sc_test.protobuf.payload_pb2 import CreateAgentAction 24 from sawtooth_sc_test.protobuf.payload_pb2 import CreateProposalAction 25 from sawtooth_sc_test.protobuf.payload_pb2 import AnswerProposalAction 26 from sawtooth_sc_test.protobuf.payload_pb2 import CreateRecordAction 27 from sawtooth_sc_test.protobuf.payload_pb2 import \ 28 CreateRecordTypeAction 29 from sawtooth_sc_test.protobuf.payload_pb2 import FinalizeRecordAction 30 from sawtooth_sc_test.protobuf.payload_pb2 import \ 31 UpdatePropertiesAction 32 from sawtooth_sc_test.protobuf.payload_pb2 import RevokeReporterAction 33 34 from sawtooth_sc_test.protobuf.property_pb2 import PropertySchema 35 from sawtooth_sc_test.protobuf.property_pb2 import PropertyValue 36 37 import sawtooth_sc_test.addressing as addressing 38 39 40 LOGGER = logging.getLogger(__name__) 41 LOGGER.setLevel(logging.DEBUG) 42 43 44 class Enum(object): 45 """A simple wrapper class to store an enum name with type information""" 46 def __init__(self, name): 47 self.value = name 48 49 50 class SupplyChainMessageFactory: 51 def __init__(self, signer=None): 52 self._factory = MessageFactory( 53 family_name=addressing.FAMILY_NAME, 54 family_version='1.1', 55 namespace=addressing.NAMESPACE, 56 signer=signer) 57 58 self.public_key = self._factory.get_public_key() 59 self.signer_address = addressing.make_agent_address(self.public_key) 60 61 def create_agent(self, name): 62 payload = _make_sc_payload( 63 action=SCPayload.CREATE_AGENT, 64 create_agent=CreateAgentAction(name=name)) 65 66 return self._create_transaction( 67 payload, 68 [self.signer_address], 69 [self.signer_address], 70 ) 71 72 def create_record_type(self, name, *properties): 73 def make_schema(name, data_type, attrs): 74 if 'struct_properties' in attrs: 75 attrs['struct_properties'] =\ 76 [make_schema(n, dt, a) 77 for n, dt, a in attrs['struct_properties']] 78 return PropertySchema(name=name, data_type=data_type, **attrs) 79 80 payload = _make_sc_payload( 81 action=SCPayload.CREATE_RECORD_TYPE, 82 create_record_type=CreateRecordTypeAction( 83 name=name, 84 properties=[make_schema(n, dt, a) for (n, dt, a) in properties] 85 ) 86 ) 87 88 record_type_address = addressing.make_record_type_address(name) 89 90 return self._create_transaction( 91 payload, 92 inputs=[record_type_address, self.signer_address], 93 outputs=[record_type_address], 94 ) 95 96 def create_record(self, record_id, record_type, properties_dict): 97 payload = _make_sc_payload( 98 action=SCPayload.CREATE_RECORD, 99 create_record=CreateRecordAction( 100 record_id=record_id, 101 record_type=record_type, 102 properties=[ 103 _make_property_value(name, value) 104 for name, value in properties_dict.items() 105 ] 106 ) 107 ) 108 109 record_address = addressing.make_record_address(record_id) 110 record_type_address = addressing.make_record_type_address(record_type) 111 property_address_range = \ 112 addressing.make_property_address_range(record_id) 113 114 inputs = [ 115 record_address, 116 record_type_address, 117 property_address_range, 118 self.signer_address, 119 ] 120 121 return self._create_transaction( 122 payload, 123 inputs=inputs, 124 outputs=[ 125 record_address, 126 property_address_range, 127 ] 128 ) 129 130 def finalize_record(self, record_id): 131 payload = _make_sc_payload( 132 action=SCPayload.FINALIZE_RECORD, 133 finalize_record=FinalizeRecordAction( 134 record_id=record_id)) 135 136 record_address = addressing.make_record_address(record_id) 137 138 return self._create_transaction( 139 payload, 140 [record_address], 141 [record_address] 142 ) 143 144 def update_properties(self, record_id, properties_dict): 145 payload = _make_sc_payload( 146 action=SCPayload.UPDATE_PROPERTIES, 147 update_properties=UpdatePropertiesAction( 148 record_id=record_id, 149 properties=[ 150 _make_property_value(name, value) 151 for name, value in properties_dict.items() 152 ] 153 ) 154 ) 155 156 record_address = addressing.make_record_address(record_id) 157 property_address_range = \ 158 addressing.make_property_address_range(record_id) 159 160 inputs = [ 161 record_address, 162 property_address_range, 163 ] 164 165 return self._create_transaction( 166 payload, 167 inputs=inputs, 168 outputs=[property_address_range] 169 ) 170 171 def create_proposal(self, record_id, receiving_agent, 172 role, properties=None): 173 if properties is None: 174 properties = [] 175 176 payload = _make_sc_payload( 177 action=SCPayload.CREATE_PROPOSAL, 178 create_proposal=CreateProposalAction( 179 record_id=record_id, 180 receiving_agent=receiving_agent, 181 role=role, 182 properties=properties)) 183 184 proposal_address = addressing.make_proposal_address( 185 record_id, 186 receiving_agent) 187 188 receiving_address = addressing.make_agent_address(receiving_agent) 189 190 record_address = addressing.make_record_address(record_id) 191 192 return self._create_transaction( 193 payload, 194 inputs=[ 195 proposal_address, 196 record_address, 197 receiving_address, 198 self.signer_address, 199 ], 200 outputs=[proposal_address], 201 ) 202 203 def answer_proposal(self, record_id, receiving_agent, role, response): 204 payload = _make_sc_payload( 205 action=SCPayload.ANSWER_PROPOSAL, 206 answer_proposal=AnswerProposalAction( 207 record_id=record_id, 208 receiving_agent=receiving_agent, 209 role=role, 210 response=response)) 211 212 proposal_address = addressing.make_proposal_address( 213 record_id, 214 receiving_agent) 215 216 record_address = addressing.make_record_address(record_id) 217 218 property_address_range = addressing.make_property_address_range( 219 record_id) 220 221 return self._create_transaction( 222 payload, 223 inputs=[ 224 proposal_address, 225 record_address, 226 property_address_range, 227 addressing.RECORD_TYPE_ADDRESS_RANGE, 228 ], 229 outputs=[ 230 proposal_address, 231 record_address, 232 property_address_range, 233 ], 234 ) 235 236 def revoke_reporter(self, record_id, reporter_id, properties): 237 payload = _make_sc_payload( 238 action=SCPayload.REVOKE_REPORTER, 239 revoke_reporter=RevokeReporterAction( 240 record_id=record_id, 241 reporter_id=reporter_id, 242 properties=properties)) 243 244 record_address = addressing.make_record_address(record_id) 245 246 proposal_address = addressing.make_proposal_address( 247 record_id, reporter_id) 248 249 property_addresses = [ 250 addressing.make_property_address( 251 record_id, property_name) 252 for property_name in properties 253 ] 254 255 return self._create_transaction( 256 payload, 257 inputs=[ 258 record_address, 259 proposal_address, 260 *property_addresses, 261 ], 262 outputs=[ 263 proposal_address, 264 *property_addresses, 265 ], 266 ) 267 268 def make_empty_payload(self, public_key): 269 address = addressing.make_agent_address(public_key) 270 271 return self._create_transaction( 272 payload=SCPayload().SerializeToString(), 273 inputs=[address], 274 outputs=[address] 275 ) 276 277 def _create_transaction(self, payload, inputs, outputs): 278 return self._factory.create_transaction( 279 payload, inputs, outputs, []) 280 281 def create_batch(self, transaction): 282 return self._factory.create_batch([transaction]) 283 284 285 def _make_sc_payload(**kwargs): 286 return SCPayload( 287 timestamp=round(time.time()), 288 **kwargs 289 ).SerializeToString() 290 291 292 def _make_property_value(name, value): 293 if type(value) == dict: 294 values = [_make_property_value(k, v) for k, v in value.items()] 295 return PropertyValue( 296 name=name, 297 data_type=PropertySchema.STRUCT, 298 struct_values=values) 299 300 property_value = PropertyValue(name=name) 301 302 type_slots = { 303 bool: 'boolean_value', 304 int: 'number_value', 305 str: 'string_value', 306 bytes: 'bytes_value', 307 Enum: 'enum_value', 308 } 309 310 type_tags = { 311 bool: PropertySchema.BOOLEAN, 312 int: PropertySchema.NUMBER, 313 str: PropertySchema.STRING, 314 bytes: PropertySchema.BYTES, 315 Enum: PropertySchema.ENUM, 316 } 317 318 try: 319 value_type = type(value) 320 slot = type_slots[value_type] 321 type_tag = type_tags[value_type] 322 except KeyError: 323 raise Exception('Unsupported type') 324 325 unwrapped_value = getattr(value, 'value', value) 326 setattr(property_value, slot, unwrapped_value) 327 property_value.data_type = type_tag 328 329 return property_value