Parse a subdomain record, and verify its signature.
        @domain_name: the stem name
        @rec: the parsed zone file, with 'txt' records

        Returns a Subdomain object on success
        Raises an exception on parse error

def parse_subdomain_record(domain_name, rec, block_height, parent_zonefile_hash, parent_zonefile_index, zonefile_offset, txid, domain_zonefiles_missing, resolver=None):
        """
        Parse a subdomain record, and verify its signature.
        @domain_name: the stem name
        @rec: the parsed zone file, with 'txt' records

        Returns a Subdomain object on success
        Raises an exception on parse error
        """
        # sanity check: need 'txt' record list
        txt_entry = rec['txt']
        if not isinstance(txt_entry, list):
            raise ParseError("Tried to parse a TXT record with only a single <character-string>")
       
        entries = {}    # parts of the subdomain record
        for item in txt_entry:
            # coerce string
            if isinstance(item, unicode):
                item = str(item)

            key, value = item.split('=', 1)
            value = value.replace('\\=', '=')  # escape '='
            
            if key in entries:
                raise ParseError("Duplicate TXT entry '{}'".format(key))

            entries[key] = value

        pubkey = entries[SUBDOMAIN_PUBKEY]
        n = entries[SUBDOMAIN_N]
        if SUBDOMAIN_SIG in entries:
            sig = entries[SUBDOMAIN_SIG]
        else:
            sig = None
        
        try:
            zonefile_parts = int(entries[SUBDOMAIN_ZF_PARTS])
        except ValueError:
            raise ParseError("Not an int (SUBDOMAIN_ZF_PARTS)")
        
        try:
            n = int(n)
        except ValueError:
            raise ParseError("Not an int (SUBDOMAIN_N)")

        b64_zonefile = "".join([entries[SUBDOMAIN_ZF_PIECE % zf_index] for zf_index in range(zonefile_parts)])
        
        is_subdomain, _, _ = is_address_subdomain(rec['name'])
        subd_name = None
        if not is_subdomain:
            # not a fully-qualified subdomain, which means it ends with this domain name
            try:
                assert is_name_valid(str(domain_name)), domain_name
                subd_name = str(rec['name'] + '.' + domain_name)
                assert is_address_subdomain(subd_name)[0], subd_name
            except AssertionError as ae:
                if BLOCKSTACK_DEBUG:
                    log.exception(ae)

                raise ParseError("Invalid names: {}".format(ae))

        else:
            # already fully-qualified
            subd_name = rec['name']
            
        return Subdomain(str(subd_name), str(domain_name), str(pubkey), int(n), base64.b64decode(b64_zonefile), str(sig), block_height, parent_zonefile_hash, parent_zonefile_index, zonefile_offset, txid, domain_zonefiles_missing=domain_zonefiles_missing, resolver=resolver)