ERC-2390: Geo-ENS
Simple Summary
GeoENS brings geographic split horizon capabilities to ENS. It's GeoDNS for ENS!
Abstract
This EIP specifies an ENS resolver interface for geographically split horizon DNS. Geographic split horizon DNS returns resource records that are specific to an end user's location. This technique is commonly used by CDNs to direct traffic to content caches nearest users. Geographic split horizon resolution is primarily geared towards ENS resolvers storing DNS resource records EIP-1185, although the technique could be used on other interfaces like IPFS content hash storage EIP-1062.
Motivation
There are many use cases for traditional GeoDNS systems, like Amazon's Route53, in the centralized web. These use cases include proximity-based load balancing and serving content specific to the geographic location of the query. Unfortunately the ENS specification does not provide a mechanism for geo-specific resolution. ENS can respond to queries with IP addresses (as described in EIP-1185) however there is no way to respond to geo-specific queries. This EIP proposes a standard to give the ENS system geo-proximal awareness to serve a similar purpose as GeoDNS.
GeoENS can do more than DNS-based solutions. In addition to geographic split horizon DNS, GeoENS can be used for the following:
- Locating digital resources (like smart contracts) that represent physical objects in the real world.
- Smart contract managing access to a physical object associated with a specific location.
- ENS + IPFS web hosting (as described in EIP-1062) with content translated to the native language of the query source.
- Tokenizing objects with a physical location.
Because of the decentralized nature of ENS, geo-specific resolution is different than traditional GeoDNS. GeoDNS works as follows. DNS queries are identified by their source IP address. This IP is looked up in a database like GeoIP2 from MaxMind which maps the IP address to a location. This method of locating the source of a query is error prone and unreliable. If the GeoIP database is out of date, queried locations can be vastly different than their true location. GeoENS does not rely on a database because the user includes a location in their query.
It follows that queries can be made by users for any location, not just their location. Traditional DNS will only return the resource assigned to a query's provenance. GeoENS does not correlate a query's provinance with a location, allowing the entire globe to be queried from a single location.
An additional shortcoming of traditional DNS is the fact that there is no way to return a list of servers in a certain proximity. This is paramount for uses cases that require discovering the resource with the lowest latency. GeoENS allows a list of resources, like IP addresses, to be gathered within a specific location. Then a client to determine themselves which resource has the lowest latency.
Lastly, publicly facing GeoDNS services do not give fine granularity control over geographic regions for GeoDNS queries. Cloud based DNS services like Amazon's Route 53 only allow specifying geographic regions at the granularity of a State in the United States. GeoENS on the other hand gives 8 characters of geohash resolution which corresponds to +-20 meter accuracy.
Specification
This EIP proposes a new interface to ENS resolvers such that geo-spacial information can be recorded and retrieved from the blockchain. The interface changes are described below for "address resolvers" described in EIP137 however the idea applies to any record described in EIP1185 and EIP1062, namely DNS Resolvers, Text Resolvers, ABI Resolvers, etc.
What is a geohash?
A Geohash is an interleaving of latitude and longitude bits, whose length determines it's precision. Geohashes are typically encoded in base 32 characters.
function setGeoAddr(bytes32 node, string calldata geohash, address addr) external authorised(node)
Sets a resource (contract address, IP, ABI, TEXT, etc.) by node and geohash.
Geohashes must be unique per address and are exactly 8 characters long.
This leads to an accuracy of +-20 meters.
Write default initialized resource value, address(0)
, to remove a resource from the resolver.
function geoAddr(bytes32 node, string calldata geohash) external view returns (address[] memory ret)
Query the resolver contract for a specific node and location. All resources (contract addresses, IP addresses, ABIs, TEXT records, etc.) matching the node and prefix geohash provided are returned. This permits querying by exact geohash of 8 characters to return the content at that location, or querying by geographic bounding box described by a geohash of less than 8 character precision.
Any type of geohash can be used including Z-order Hilbert or the more accurate S2 Geometry library from Google. There are also ways to search the geographic data using geohashes without always ending up with a rectangular query region. Searching circular shaped regions is slightly more complex as it requires multiple queries.
Rationale
The proposed implementation uses a sparse Quadtree trie as an index for resource records as it has low storage overhead and good search performance. The leaf nodes of the tree store resource records while non-leaves represent one geohash character. Each node in the tree at depth d corresponds to a geohash of precision d. The tree has depth 8 because the maximum precision of a geohash is 8 characters. The tree has fanout 32 because the radix of a geohash character is 32. The path to get to a leaf node always has depth 8 and the leaf contains the content (like IP address) of the geohash represented by the path to the leaf. The tree is sparse as 71% of the Earth's surface is covered by water. The tree facilitates common traversal algorithms (DFS, BFS) to return lists of resource records within a geographic bounding box.
Backwards Compatibility
This EIP does not introduce issues with backwards compatibility.
Test Cases
See https://github.com/james-choncholas/resolvers/blob/master/test/TestPublicResolver.js
Implementation
This address resolver, written in Solidity, implements the specifications outlined above.
The same idea presented here can be applied to other resolver interfaces as specified in EIP137.
Note that geohashes are passed and stored using 64 bit unsigned integers.
Using integers instead of strings for geohashes is more performant, especially in the geomap
mapping.
For comparison purposes, see https://github.com/james-choncholas/geoens/tree/master/contracts/StringOwnedGeoENSResolver.sol for the inefficient string implementation.
Security Considerations
This contract has similar functionality to ENS Resolvers - refer there for security considerations. Additionally, this contract has a dimension of data privacy. Users query via the geoAddr function specifying a geohash of less than 8 characters which defines the query region. Users who run light clients leak the query region to their connected full-nodes. Users who rely on nodes run by third parties (like Infura) will also leak the query region. Users who run their own full node or have access to a trusted full node do not leak any location data.
Given the way most location services work, the query region is likely to contain the user's actual location. The difference between API access, light, and full nodes has always had an impact on privacy but now the impact is underscored by the involvement of coarse granularity user location.
Copyright
Copyright and related rights waived via CC0.