-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENS - Stop inferring .eth TLD #1205
ENS - Stop inferring .eth TLD #1205
Conversation
2d8da1c
to
ec37813
Compare
ec37813
to
fce2e20
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we update the use of RECOGNIZED_TLDS
to be overridable?
Something like
# constants.py
DEFAULT_RECOGNIZED_TLDS = [...]
# ens/utils.py
def get_recognized_tlds():
if 'ENS_RECOGNIZED_TLDS' in os.environ:
return set(os.environ['ENS_RECOGNIZED_TLDS'].split(':'))
else:
return DEFAULT_RECOGNIZED_TLDS
Note that the code to pull the data from os.environ
should be beefed up to have some better error handling and normalization so that it's a bit more forgiving about how they are formatted.
ens/utils.py
Outdated
label = normalize_name(label) | ||
pieces = label.split('.') | ||
if pieces[-1] not in recognized_tlds: | ||
pieces.append(default_tld) | ||
raise InvalidTLD( | ||
f"Label does not have a recognized TLD. TLD must match one of: {recognized_tlds}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be good to include both the label
and the pieces[-1]
in this message.
4750485
to
11d06e2
Compare
ens/utils.py
Outdated
override_tlds = os.environ['ENS_RECOGNIZED_TLDS'].split(':') | ||
return set(DEFAULT_RECOGNIZED_TLDS + override_tlds) | ||
else: | ||
return DEFAULT_RECOGNIZED_TLDS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pipermerriam How about this? I wasn't sure how much checking of the env variable to do. (eg. even if it's an empty string, everything should still work fine - and the user should be able to tell where they went wrong via the error msg). I went for also including the default TLDs even if the user sets the env variable, not sure if this should be avoided or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things
- Maybe validate that all of the names are valid. I.E. I think it would be invalid to provide
thing.something
as a TLD since it has a.
in it. - Can ENS actually work without any defined TLDs? If so, throwing an error if the specified TLD list is empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pipermerriam Just saw this on the ens docs
Can I register a TLD of my own in the ENS?
No, TLDs are restricted to only .eth (on mainnet), or .eth and .test (on Ropsten), plus any special purpose TLDs such as those required to permit reverse lookups. There are no immediate plans to invite proposals for additional TLDs. In large part this is to reduce the risk of a namespace collision with the IANA DNS namespace.
Do we still want to allow users to set their own tlds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want to allow users to set their own tlds?
For private networks I guess yes. Also for ENS team to test new TLDs. (I know Nick has used the library at least once, and requested changes) Also, that doc looks out of date. There is at least .xyz
and I think another available now.
ens/utils.py
Outdated
def get_recognized_tlds(): | ||
if 'ENS_RECOGNIZED_TLDS' in os.environ: | ||
override_tlds = os.environ['ENS_RECOGNIZED_TLDS'].split(':') | ||
return set(DEFAULT_RECOGNIZED_TLDS + override_tlds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm, I'm not sure these should be combined. If the user supplies their own it would be up to them to ensure they included all desired TLDs
Actually... it's not clear to me why we need any hard-coding of TLDs. They are resolved like any other name (looked up as a subdomain of the root), so they will just work like any other name that can't be found. The only reason that we kept that list before was so that we could do something like "laptop.jasoncarver" getting resolved to "laptop.jasoncarver.eth", since In fact, I think one of the key benefits of removing the "guessing" of the TLDs is that we get to remove any logic that treats the TLDs as special, simplifying several places in the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I read through, I'm even more convinced that the win of dropping the guess_tld
option is that we stop treating TLDs as special, and we get to delete code. 🎉
tests/ens/test_setup_name.py
Outdated
@@ -127,7 +130,7 @@ def test_setup_name_unowned_exception(ens): | |||
|
|||
def test_setup_name_unauthorized(ens, TEST_ADDRESS): | |||
with pytest.raises(UnauthorizedError): | |||
ens.setup_name('root-owned-tld', TEST_ADDRESS) | |||
ens.setup_name('root-owned-tld.eth', TEST_ADDRESS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test was originally attempting to set up a TLD, which would require owning the root. (Hence the name root-owned-tld
)
Since the address sending the transaction doesn't own the root, it's supposed to fail.
tests/ens/test_setup_name.py
Outdated
'lots.of.subdomains.tester', | ||
), | ||
) | ||
def test_cannot_setup_name_with_missing_or_invalid_tld(ens, name): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I think this whole test can go away if we stop treating TLDs special.
tests/ens/test_setup_address.py
Outdated
'lots.of.subdomains.tester', | ||
), | ||
) | ||
def test_set_address_raises_exception_with_invalid_or_missing_tld(ens, name, TEST_ADDRESS): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test goes away, too.
ens/utils.py
Outdated
return '.'.join(pieces) | ||
|
||
|
||
def dot_eth_name(label): | ||
return label_to_name(label, 'eth', RECOGNIZED_TLDS) | ||
recognized_tlds = get_recognized_tlds() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think dot_eth_name
should exist anymore. Looks like it can be replaced by normalize_name
everywhere. Then this and label_to_name
can be dropped entirely.
ens/exceptions.py
Outdated
@@ -77,3 +77,10 @@ class UnderfundedBid(ValueError): | |||
as your intent to bid. | |||
''' | |||
pass | |||
|
|||
|
|||
class InvalidTLD(ValueError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we stop treating TLDs special, we can drop this exception.
ens/constants.py
Outdated
@@ -9,6 +9,6 @@ | |||
|
|||
MIN_ETH_LABEL_LENGTH = 7 | |||
|
|||
RECOGNIZED_TLDS = ['eth', 'reverse', 'test', 'luxe', 'xyz'] | |||
DEFAULT_RECOGNIZED_TLDS = ['eth', 'reverse', 'test', 'luxe', 'xyz'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be dropped
docs/ens_overview.rst
Outdated
|
||
assert ns.address('jasoncarver') == eth_address | ||
# ens.py only support names using one of these recognized TLDs | ||
# ['eth', 'reverse', 'test', 'luxe', 'xyz'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be dropped
e15dac3
to
9659998
Compare
9659998
to
1ab9472
Compare
Thanks @carver & @pipermerriam for the review, made the changes. Ping for a final 👀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, yay for delete-heavy PRs!
Just the one missing assertion caught my attention. Some naming suggestions, if you like.
ens/utils.py
Outdated
@@ -200,7 +185,7 @@ def dot_eth_namehash(name): | |||
:rtype: bytes | |||
:raises InvalidName: if ``name`` has invalid syntax | |||
''' | |||
expanded_name = dot_eth_name(name) | |||
expanded_name = normalize_name(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of dot_eth_namehash
should also probably change (since it doesn't append dot_eth
anymore). Maybe raw_name_to_hash
?
The other similar method, name_to_hash
, could be changed to normal_name_to_hash
to help distinguish.
namehash = Web3.toBytes(hexstr=namehash_hex) | ||
normal_name = ens.nameprep(full_name) | ||
if ens.nameprep(name) == normal_name: | ||
assert is_same_address(ens.address(name, guess_tld=False), TEST_ADDRESS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just this assertion should stay in, omitting guess_tld
of course.
|
||
ens.setup_address(name, TEST_ADDRESS) | ||
assert is_same_address(ens.address(name), TEST_ADDRESS) | ||
|
||
# check that .eth is only appended if guess_tld is True | ||
namehash = Web3.toBytes(hexstr=namehash_hex) | ||
normal_name = ens.nameprep(full_name) | ||
if ens.nameprep(name) == normal_name: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can either drop this if
test, or have an else: assert False, "all names must be full names"
below.
What was wrong?
From Planned v5 changes
Related to Issue #722
How was it fixed?
label_to_name()
util to raise anInvalidTLD
exception if label was missing a TLD or used an unsupported TLDguess_TLD
inens.address()
Cute Animal Picture