def create_context(self, state_hash, base_contexts, inputs, outputs): """Create a ExecutionContext to run a transaction against. Args: state_hash: (str): Merkle root to base state on. base_contexts (list of str): Context ids of contexts that will have their state applied to make this context. inputs (list of str): Addresses that can be read from. outputs (list of str): Addresses that can be written to. Returns: context_id (str): the unique context_id of the session """ for address in inputs: if not self.namespace_is_valid(address): raise CreateContextException( "Address or namespace {} listed in inputs is not " "valid".format(address)) for address in outputs: if not self.namespace_is_valid(address): raise CreateContextException( "Address or namespace {} listed in outputs is not " "valid".format(address)) addresses_to_find = [add for add in inputs if len(add) == 70] address_values, reads = self._find_address_values_in_chain( base_contexts=base_contexts, addresses_to_find=addresses_to_find) context = ExecutionContext( state_hash=state_hash, read_list=inputs, write_list=outputs, base_context_ids=base_contexts) contexts_asked_not_found = [cid for cid in base_contexts if cid not in self._contexts] if contexts_asked_not_found: raise KeyError( "Basing a new context off of context ids {} " "that are not in context manager".format( contexts_asked_not_found)) context.create_initial(address_values) self._contexts[context.session_id] = context if reads: context.create_prefetch(reads) self._address_queue.put_nowait( (context.session_id, state_hash, reads)) return context.session_id