DANGER!!!
Aliases are insecure as anyone can associate anything with any name
Whether you are developing a service or have already made it for your users, it can be cumbersome to change service_id
and host node addresses in your application manually each time you redeploy it. The global nature of Kademlia/DHT rushes to the rescue!
What you can do is to assign your application (or service) a discoverable name – an alias. An alias is a string associated with a service provider, which is a pair of PeerId
and service_id
. You can think of the "service's provider" as the location of the service.
Assigning aliases
For example, your service with its service_id
equal to uuid-1234
is provided by the node 123DYourNode
. You can give your service the alias good_name
. In this case, it will be stored in DHT as good_name = (123DYourNode, uuid-1234)
, so anyone on the network can resolve this alias and call your service directly. This is similar to how DNS CNAME works.
All it takes is a few lines of AIR, utilizing the flexibility of Aquamarine and Kademlia/DHT.
(seq
; gather list of peers in the neighborhood of hash(good_name)
(call "12DNode" ("neighborhood" "") ["good_name"] neighbors)
; iterate by node
(fold neighbors n
(seq
; put alias to each node's storage
(call n ("add_provider" "") ["good_name" provider])
(next n)
)
)
)
Here is how this flow can be visualised.


Storing alias to nodes in the neighborhood of hash(good_name)
Resolving aliases
You can use the following script to resolve an alias and get all service providers to select the ones that meet your needs.
(seq
(seq
; gather list of peers in the neighborhood of hash(good_name)
(call relay ("neighborhood" "") ["good_name"] neighbors)
(fold neighbors n
(seq
; gather service's providers into array
(call n ("get_providers" "") ["good_name"] providers[])
(next n)
)
)
)
; send array of providers to client (yourself)
(seq
(call relay ("identity" "") [])
(call client ("identity" "") [providers])
)
)
Here is how you can think of this flow.


Gathering service's providers from Kademlia/DHT
If you do not need to apply any selection logic, you can avoid a few extra hops and call the service right after the first service provider is identified (see the example below).
(seq
(seq
; gather list of peers in the neighborhood of hash(good_name)
(call relay ("neighborhood" "") ["good_name"] neighbors)
(fold neighbors n
(seq
; gather service's providers into array
(call n ("get_providers" "") ["good_name"] providers[])
(next n)
)
)
)
; call service immediately after collecting providers
(call (providers.$[0].peer_id providers.$[0].service_id) "function" [arg] output)
)
Updated about a month ago