def _get_fees(self, is_committed=False, with_proof=False):
     fees = {}
     proof = None
     try:
         if with_proof:
             proof, serz = self.state.generate_state_proof(
                 self.fees_state_key, serialize=True, get_value=True)
             if serz:
                 serz = rlp_decode(serz)[0]
             root_hash = self.state.committedHeadHash if is_committed else self.state.headHash
             encoded_root_hash = state_roots_serializer.serialize(
                 bytes(root_hash))
             multi_sig = self.bls_store.get(encoded_root_hash)
             if multi_sig:
                 encoded_proof = proof_nodes_serializer.serialize(proof)
                 proof = {
                     MULTI_SIGNATURE: multi_sig.as_dict(),
                     ROOT_HASH: encoded_root_hash,
                     PROOF_NODES: encoded_proof
                 }
             else:
                 proof = {}
         else:
             serz = self.state.get(self.fees_state_key,
                                   isCommitted=is_committed)
         if serz:
             fees = self.state_serializer.deserialize(serz)
     except KeyError:
         pass
     if with_proof:
         return fees, proof
     return fees
Exemple #2
0
    def make_proof(self, path, head_hash=None):
        '''
        Creates a state proof for the given path in state trie.
        Returns None if there is no BLS multi-signature for the given state (it can
        be the case for txns added before multi-signature support).

        :param path: the path generate a state proof for
        :return: a state proof or None
        '''
        root_hash = head_hash if head_hash else self.state.committedHeadHash
        encoded_root_hash = state_roots_serializer.serialize(bytes(root_hash))

        multi_sig = self.bls_store.get(encoded_root_hash)
        if not multi_sig:
            return None

        proof = self.state.generate_state_proof(key=path,
                                                root=self.state.get_head_by_hash(
                                                    root_hash),
                                                serialize=True)
        encoded_proof = proof_nodes_serializer.serialize(proof)
        return {
            ROOT_HASH: encoded_root_hash,
            MULTI_SIGNATURE: multi_sig.as_dict(),
            PROOF_NODES: encoded_proof
        }
Exemple #3
0
    def get_value_from_state(self,
                             path,
                             head_hash=None,
                             with_proof=False,
                             multi_sig=None):
        '''
        Get a value (and proof optionally)for the given path in state trie.
        Does not return the proof is there is no aggregate signature for it.
        :param path: the path generate a state proof for
        :param head_hash: the root to create the proof against
        :param get_value: whether to return the value
        :return: a state proof or None
        '''
        root_hash = head_hash if head_hash else self.state.committedHeadHash
        encoded_root_hash = state_roots_serializer.serialize(bytes(root_hash))

        if not with_proof:
            return self.state.get_for_root_hash(root_hash, path), None

        if not multi_sig:
            # Just return the value and not proof
            try:
                return self.state.get_for_root_hash(root_hash, path), None
            except KeyError:
                return None, None
        else:
            try:
                proof, value = self.state.generate_state_proof(
                    key=path,
                    root=self.state.get_head_by_hash(root_hash),
                    serialize=True,
                    get_value=True)
                value = self.state.get_decoded(value) if value else value
                encoded_proof = proof_nodes_serializer.serialize(proof)
                proof = {
                    ROOT_HASH: encoded_root_hash,
                    MULTI_SIGNATURE: multi_sig.as_dict(),
                    PROOF_NODES: encoded_proof
                }
                return value, proof
            except KeyError:
                return None, None
    def get_all_utxo(self, request: Request):
        address = request.operation[ADDRESS]
        encoded_root_hash = state_roots_serializer.serialize(
            bytes(self.state.committedHeadHash))
        proof, rv = self.state.generate_state_proof_for_keys_with_prefix(
            address, serialize=True, get_value=True)
        multi_sig = self.bls_store.get(encoded_root_hash)
        if multi_sig:
            encoded_proof = proof_nodes_serializer.serialize(proof)
            proof = {
                MULTI_SIGNATURE: multi_sig.as_dict(),
                ROOT_HASH: encoded_root_hash,
                PROOF_NODES: encoded_proof
            }
        else:
            proof = {}

        # The outputs need to be returned in sorted order since each node's reply should be same.
        # Since no of outputs can be large, a concious choice to not use `operator.attrgetter` on an
        # already constructed list was made
        outputs = SortedItems()
        for k, v in rv.items():
            addr, seq_no = self.parse_state_key(k.decode())
            amount = rlp_decode(v)[0]
            if not amount:
                continue
            outputs.add(Output(addr, int(seq_no), int(amount)))

        result = {
            f.IDENTIFIER.nm: request.identifier,
            f.REQ_ID.nm: request.reqId,
            OUTPUTS: outputs.sorted_list
        }
        if proof:
            result[STATE_PROOF] = proof

        result.update(request.operation)
        return result