Exemplo n.º 1
0
def subdomain_record_to_profile(my_rec):
    owner_addr = my_rec.address

    assert isinstance(my_rec.zonefile_str, (str, unicode))

    parsed_zf = bs_zonefile.decode_name_zonefile(my_rec.subdomain_name, my_rec.zonefile_str)
    urls = user_db.user_zonefile_urls(parsed_zf)

    # try to get pubkey from zonefile, or default to ``owner`` pubkey
    user_data_pubkey = None
    try:
        user_data_pubkey = user_db.user_zonefile_data_pubkey(parsed_zf)
        if user_data_pubkey is not None:
            user_data_pubkey = str(user_data_pubkey)
    except ValueError:
        pass # no pubkey defined in zonefile

    try:
        user_profile = storage.get_mutable_data(
            None, user_data_pubkey, blockchain_id=None,
            data_address=owner_addr, owner_address=None,
            urls=urls, drivers=None, decode=True,
        )
    except:
        user_profile = None

    if user_profile is None:
        user_profile = {'error' :
                        'Error fetching the data for subdomain {}'.format(my_rec.get_fqn())}

    data = { 'profile' : user_profile,
             'zonefile' : parsed_zf }
    return data
Exemplo n.º 2
0
    def test_basic_with_multisig(self):
        test_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "parts=0"
        """

        my_keys = [keylib.ECPrivateKey() for _ in range(3)]
        my_pubkeys = [k.public_key().to_hex() for k in my_keys]
        owner_addr = virtualchain.make_multisig_address(my_pubkeys, 3)

        test_zf = test_zf.format(owner_addr)

        domain_name = "bar.id"

        zf_json = zonefile.decode_name_zonefile(domain_name, test_zf)

        self.assertEqual(zf_json['$origin'], domain_name)

        subds = subdomains.parse_zonefile_subdomains(domain_name, zf_json)
        self.assertEqual(len(subds), 1)
        sub = subds[0]
        self.assertEqual(sub.n, 3)
        self.assertEqual(sub.sig, None)

        self.assertEqual(sub.subdomain_name, "foo")
Exemplo n.º 3
0
    def test_basic(self):
        test_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "parts=0"
        """

        fake_privkey_hex = "5512612ed6ef10ea8c5f9839c63f62107c73db7306b98588a46d0cd2c3d15ea5"
        sk = keylib.ECPrivateKey(fake_privkey_hex)
        pk = sk.public_key()

        test_zf = test_zf.format(subdomains.encode_pubkey_entry(pk))

        domain_name = "bar.id"

        zf_json = zonefile.decode_name_zonefile(domain_name, test_zf)

        self.assertEqual(zf_json['$origin'], domain_name)

        subds = subdomains.parse_zonefile_subdomains(domain_name, zf_json)
        self.assertEqual(len(subds), 1)
        sub = subds[0]
        self.assertEqual(sub.n, 3)
        self.assertEqual(sub.sig, None)

        self.assertEqual(sub.subdomain_name, "foo")
Exemplo n.º 4
0
    def test_sigs(self):
        fake_privkey_hex = "5512612ed6ef10ea8c5f9839c63f62107c73db7306b98588a46d0cd2c3d15ea5"
        sk = keylib.ECPrivateKey(fake_privkey_hex)
        pk = sk.public_key()

        for t in ["foo", "bar", "bassoon"]:
            self.assertTrue(
                subdomains.verify(pk.address(), t, subdomains.sign(sk, t)), t)

        subdomain = subdomains.Subdomain("bar.id", "foo",
                                         subdomains.encode_pubkey_entry(sk), 3,
                                         "")

        user_zf = {'$origin': 'foo', '$ttl': 3600, 'txt': [], 'uri': []}

        user_zf['uri'].append(
            zonefile.url_to_uri_record("https://foo_foo.com/profile.json"))
        jsonschema.validate(user_zf, USER_ZONEFILE_SCHEMA)

        subdomain.zonefile_str = blockstack_zones.make_zone_file(user_zf)

        subdomain.add_signature(sk)

        self.assertTrue(subdomain.verify_signature(pk.address()))

        parsed_zf = zonefile.decode_name_zonefile(subdomain.subdomain_name,
                                                  subdomain.zonefile_str)
        urls = user_db.user_zonefile_urls(parsed_zf)

        self.assertEqual(len(urls), 1)
        self.assertIn("https://foo_foo.com/profile.json", urls)

        self.assertRaises(
            NotImplementedError,
            lambda: subdomains.encode_pubkey_entry(fake_privkey_hex))
Exemplo n.º 5
0
def _build_subdomain_db(domain_fqas, zonefiles, subdomain_db=None, txids=None):
    if subdomain_db is None:
        subdomain_db = {}
    if txids is None:
        txids = [None for x in zonefiles]
    for zf, domain_fqa, txid in zip(zonefiles, domain_fqas, txids):
        if isinstance(zf, dict):
            assert "zonefile" not in zf
            zf_json = zf
        else:
            assert isinstance(zf, (str, unicode))
            zf_json = bs_zonefile.decode_name_zonefile(domain_fqa, zf)
            assert "zonefile" not in zf_json

        subdomains = parse_zonefile_subdomains(domain_fqa, zf_json)

        for subdomain in subdomains:
            if txid:
                subdomain.last_txid = txid
            if subdomain.get_fqn() in subdomain_db:
                previous = subdomain_db[subdomain.get_fqn()]
                if _transition_valid(previous, subdomain):
                    subdomain_db[subdomain.get_fqn()] = subdomain
                else:
                    log.warn("Failed subdomain transition for {} on N:{}->{}".
                             format(subdomain.get_fqn(), previous.n,
                                    subdomain.n))
            else:
                if subdomain.n != 0:
                    log.warn("First sight of subdomain {} with N={}".format(
                        subdomain.get_fqn(), subdomain.n))
                    continue
                subdomain_db[subdomain.get_fqn()] = subdomain
    return subdomain_db
def _build_subdomain_db(domain_fqas, zonefiles, subdomain_db = None, txids = None):
    if subdomain_db is None:
        subdomain_db = {}
    if txids is None:
        txids = [None for x in zonefiles]
    for zf, domain_fqa, txid in zip(zonefiles, domain_fqas, txids):
        if isinstance(zf, dict):
            assert "zonefile" not in zf
            zf_json = zf
        else:
            assert isinstance(zf, (str, unicode)) 
            zf_json = bs_zonefile.decode_name_zonefile(domain_fqa, zf)
            assert "zonefile" not in zf_json

        subdomains = parse_zonefile_subdomains(domain_fqa, zf_json)

        for subdomain in subdomains:
            if txid:
                subdomain.last_txid = txid
            if subdomain.get_fqn() in subdomain_db:
                previous = subdomain_db[subdomain.get_fqn()]
                if _transition_valid(previous, subdomain):
                    subdomain_db[subdomain.get_fqn()] = subdomain
                else:
                    log.warn("Failed subdomain transition for {} on N:{}->{}".format(
                        subdomain.get_fqn(), previous.n, subdomain.n))
            else:
                if subdomain.n != 0:
                    log.warn("First sight of subdomain {} with N={}".format(
                        subdomain.get_fqn(), subdomain.n))
                    continue
                subdomain_db[subdomain.get_fqn()] = subdomain
    return subdomain_db
    def test_sigs(self):
        fake_privkey_hex = "5512612ed6ef10ea8c5f9839c63f62107c73db7306b98588a46d0cd2c3d15ea5"
        sk = keylib.ECPrivateKey(fake_privkey_hex)
        pk = sk.public_key()

        for t in ["foo", "bar", "bassoon"]:
            self.assertTrue(subdomains.verify(pk.address(), t,
                                              subdomains.sign(sk, t)), t)

        subdomain = subdomains.Subdomain("bar.id", "foo", subdomains.encode_pubkey_entry(sk), 3, "")

        user_zf = {
            '$origin': 'foo',
            '$ttl': 3600,
            'txt' : [], 'uri' : []
        }

        user_zf['uri'].append(zonefile.url_to_uri_record("https://foo_foo.com/profile.json"))
        jsonschema.validate(user_zf, USER_ZONEFILE_SCHEMA)

        subdomain.zonefile_str = blockstack_zones.make_zone_file(user_zf)

        subdomain.add_signature(sk)

        self.assertTrue(subdomain.verify_signature(pk.address()))

        parsed_zf = zonefile.decode_name_zonefile(subdomain.subdomain_name, subdomain.zonefile_str)
        urls = user_db.user_zonefile_urls(parsed_zf)

        self.assertEqual(len(urls), 1)
        self.assertIn("https://foo_foo.com/profile.json", urls)

        self.assertRaises( NotImplementedError, lambda : subdomains.encode_pubkey_entry( fake_privkey_hex ) )
    def test_basic_with_multisig(self):
        test_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "parts=0"
        """

        my_keys = [ keylib.ECPrivateKey() for _ in range(3) ]
        my_pubkeys = [ k.public_key().to_hex() for k in my_keys ]
        owner_addr = virtualchain.make_multisig_address(my_pubkeys, 3)

        test_zf = test_zf.format(owner_addr)

        domain_name = "bar.id"

        zf_json = zonefile.decode_name_zonefile(domain_name, test_zf)

        self.assertEqual(zf_json['$origin'], domain_name)

        subds = subdomains.parse_zonefile_subdomains(domain_name, zf_json)
        self.assertEqual(len(subds), 1)
        sub = subds[0]
        self.assertEqual(sub.n, 3)
        self.assertEqual(sub.sig, None)

        self.assertEqual(sub.subdomain_name, "foo")
    def test_basic(self):
        test_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "parts=0"
        """


        fake_privkey_hex = "5512612ed6ef10ea8c5f9839c63f62107c73db7306b98588a46d0cd2c3d15ea5"
        sk = keylib.ECPrivateKey(fake_privkey_hex)
        pk = sk.public_key()
        
        test_zf = test_zf.format(subdomains.encode_pubkey_entry(pk))

        domain_name = "bar.id"

        zf_json = zonefile.decode_name_zonefile(domain_name, test_zf)

        self.assertEqual(zf_json['$origin'], domain_name)

        subds = subdomains.parse_zonefile_subdomains(domain_name, zf_json)
        self.assertEqual(len(subds), 1)
        sub = subds[0]
        self.assertEqual(sub.n, 3)
        self.assertEqual(sub.sig, None)

        self.assertEqual(sub.subdomain_name, "foo")
Exemplo n.º 10
0
 def test_large_zonefile(self):
     empty_zf = """$ORIGIN registrar.id
     $TTL 3600
     pubkey TXT "pubkey:data:0"
     registrar URI 10 1 "bsreg://foo.com:8234"
     """
     domain_name = "registrar.id"
     zf_js = zonefile.decode_name_zonefile(domain_name, empty_zf)
 def test_large_zonefile(self):
     empty_zf = """$ORIGIN registrar.id
     $TTL 3600
     pubkey TXT "pubkey:data:0"
     registrar URI 10 1 "bsreg://foo.com:8234"
     """
     domain_name = "registrar.id"
     zf_js = zonefile.decode_name_zonefile(domain_name, empty_zf)
    def test_parse_errs(self):
        zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT should_not_parse
        """
        domain_name = "bar.id"
        zf_json = zonefile.decode_name_zonefile(domain_name, zf)
        self.assertEqual(len(subdomains.parse_zonefile_subdomains(domain_name, zf_json)), 0)

        zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "should_not_parse"
        """
        zf_json = zonefile.decode_name_zonefile(domain_name, zf)
        self.assertEqual(len(subdomains.parse_zonefile_subdomains(domain_name, zf_json)), 0)
Exemplo n.º 13
0
    def test_parse_errs(self):
        zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT should_not_parse
        """
        domain_name = "bar.id"
        zf_json = zonefile.decode_name_zonefile(domain_name, zf)
        self.assertEqual(
            len(subdomains.parse_zonefile_subdomains(domain_name, zf_json)), 0)

        zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=3" "should_not_parse"
        """
        zf_json = zonefile.decode_name_zonefile(domain_name, zf)
        self.assertEqual(
            len(subdomains.parse_zonefile_subdomains(domain_name, zf_json)), 0)
Exemplo n.º 14
0
    def test_db_builder_bad_transitions(self):
        history = [
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=0" "parts=0"
""",
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
bar TXT "owner={}" "seqn=0" "parts=0"
""",
        ]

        foo_bar_sk = keylib.ECPrivateKey()
        bar_bar_sk = keylib.ECPrivateKey()

        history[0] = history[0].format(
            subdomains.encode_pubkey_entry(foo_bar_sk))
        history[1] = history[1].format(
            subdomains.encode_pubkey_entry(bar_bar_sk))

        domain_name = "bar.id"

        empty_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
"""

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        # bad transition n=0 -> n=0
        sub1 = subdomains.Subdomain("foo", domain_name,
                                    subdomains.encode_pubkey_entry(foo_bar_sk),
                                    0, "")

        subdomain_util._extend_with_subdomain(zf_json, sub1)

        history.append(blockstack_zones.make_zone_file(zf_json))

        # bad transition bad sig.
        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        sub2 = subdomains.Subdomain("foo", domain_name,
                                    subdomains.encode_pubkey_entry(bar_bar_sk),
                                    1, "")
        subdomain_util._extend_with_subdomain(zf_json, sub2)
        history.append(blockstack_zones.make_zone_file(zf_json))

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(1)], history[:1])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertNotIn("bar.bar.id", subdomain_db)

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(2)], history[:2])
        self.assertIn("bar.bar.id", subdomain_db)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        # handle repeated zonefile

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)
        subdomains._build_subdomain_db(["bar.id" for x in range(3)],
                                       history[:3],
                                       subdomain_db=subdomain_db)
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)
Exemplo n.º 15
0
    def test_db_builder(self):
        history = [
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=0" "parts=0"
""",
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
bar TXT "owner={}" "seqn=0" "parts=0"
""",
        ]

        foo_bar_sk = keylib.ECPrivateKey()
        bar_bar_sk = keylib.ECPrivateKey()

        history[0] = history[0].format(
            subdomains.encode_pubkey_entry(foo_bar_sk))
        history[1] = history[1].format(
            subdomains.encode_pubkey_entry(bar_bar_sk))

        domain_name = "bar.id"

        empty_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
"""

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        sub1 = subdomains.Subdomain(domain_name, "foo",
                                    subdomains.encode_pubkey_entry(foo_bar_sk),
                                    1, "")
        sub2 = subdomains.Subdomain(domain_name, "bar",
                                    subdomains.encode_pubkey_entry(bar_bar_sk),
                                    1, "")
        sub1.add_signature(foo_bar_sk)
        sub2.add_signature(bar_bar_sk)

        subdomain_util._extend_with_subdomain(zf_json, sub2)

        history.append(blockstack_zones.make_zone_file(zf_json))

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        subdomain_util._extend_with_subdomain(zf_json, sub1)

        history.append(blockstack_zones.make_zone_file(zf_json))

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(1)], history[:1])
        self.assertIn("foo.bar.id", subdomain_db,
                      "Contents actually: {}".format(subdomain_db.keys()))
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertNotIn("bar.bar.id", subdomain_db)

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(2)], history[:2])
        self.assertIn("bar.bar.id", subdomain_db)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 1)

        subdomain_db = subdomains._build_subdomain_db(
            ["bar.id" for x in range(len(history))], history)
        self.assertEqual(subdomain_db["foo.bar.id"].n, 1)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 1)
    def test_db_builder_bad_transitions(self):
        history = [
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=0" "parts=0"
""",
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
bar TXT "owner={}" "seqn=0" "parts=0"
""",
]

        foo_bar_sk = keylib.ECPrivateKey()
        bar_bar_sk = keylib.ECPrivateKey()

        history[0] = history[0].format(subdomains.encode_pubkey_entry(foo_bar_sk))
        history[1] = history[1].format(subdomains.encode_pubkey_entry(bar_bar_sk))

        domain_name = "bar.id"

        empty_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
"""

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        # bad transition n=0 -> n=0
        sub1 = subdomains.Subdomain("foo", domain_name, subdomains.encode_pubkey_entry(foo_bar_sk), 0, "")

        subdomain_util._extend_with_subdomain(zf_json, sub1)

        history.append(blockstack_zones.make_zone_file(zf_json))

        # bad transition bad sig.
        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        sub2 = subdomains.Subdomain("foo", domain_name, subdomains.encode_pubkey_entry(bar_bar_sk), 1, "")
        subdomain_util._extend_with_subdomain(zf_json, sub2)
        history.append(blockstack_zones.make_zone_file(zf_json))

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(1)], history[:1])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertNotIn("bar.bar.id", subdomain_db)

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(2)], history[:2])
        self.assertIn("bar.bar.id", subdomain_db)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        # handle repeated zonefile

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)
        subdomains._build_subdomain_db(["bar.id" for x in range(3)], history[:3], subdomain_db = subdomain_db)
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)        
    def test_db_builder(self):
        history = [
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
foo TXT "owner={}" "seqn=0" "parts=0"
""",
            """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
bar TXT "owner={}" "seqn=0" "parts=0"
""",
]

        foo_bar_sk = keylib.ECPrivateKey()
        bar_bar_sk = keylib.ECPrivateKey()

        history[0] = history[0].format(subdomains.encode_pubkey_entry(foo_bar_sk))
        history[1] = history[1].format(subdomains.encode_pubkey_entry(bar_bar_sk))

        domain_name = "bar.id"

        empty_zf = """$ORIGIN bar.id
$TTL 3600
pubkey TXT "pubkey:data:0"
registrar URI 10 1 "bsreg://foo.com:8234"
"""

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        self.assertEqual(zf_json['$origin'], domain_name)

        sub1 = subdomains.Subdomain(domain_name, "foo", subdomains.encode_pubkey_entry(foo_bar_sk), 1, "")
        sub2 = subdomains.Subdomain(domain_name, "bar", subdomains.encode_pubkey_entry(bar_bar_sk), 1, "")
        sub1.add_signature(foo_bar_sk)
        sub2.add_signature(bar_bar_sk)

        subdomain_util._extend_with_subdomain(zf_json, sub2)

        history.append(blockstack_zones.make_zone_file(zf_json))

        zf_json = zonefile.decode_name_zonefile(domain_name, empty_zf)
        subdomain_util._extend_with_subdomain(zf_json, sub1)

        history.append(blockstack_zones.make_zone_file(zf_json))

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(1)], history[:1])
        self.assertIn("foo.bar.id", subdomain_db, "Contents actually: {}".format(subdomain_db.keys()))
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertNotIn("bar.bar.id", subdomain_db)

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(2)], history[:2])
        self.assertIn("bar.bar.id", subdomain_db)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 0)

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(3)], history[:3])
        self.assertEqual(subdomain_db["foo.bar.id"].n, 0)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 1)

        subdomain_db = subdomains._build_subdomain_db(["bar.id" for x in range(len(history))], history)
        self.assertEqual(subdomain_db["foo.bar.id"].n, 1)
        self.assertEqual(subdomain_db["bar.bar.id"].n, 1)