-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Start a minimal CNS implementation. (#66)
Start an implementation of a minimal CNS. This PR adds a very minimal CNS root canister with basic tests. --------- Co-authored-by: Nathan Mc Grath <[email protected]>
- Loading branch information
1 parent
0b1f707
commit 20efb14
Showing
6 changed files
with
183 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,3 +63,9 @@ node_modules/ | |
## generate output | ||
out | ||
dist | ||
|
||
## dfx | ||
.dfx/ | ||
|
||
## IDEs | ||
.idea/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"dfx": "0.24.2", | ||
"canisters": { | ||
"cns_root": { | ||
"main": "minimal_cns/src/backend/cns_root.mo", | ||
"type": "motoko" | ||
}, | ||
"cns_root_test": { | ||
"main": "minimal_cns/src/backend/cns_root.test.mo", | ||
"type": "motoko" | ||
}, | ||
"name_registry": { | ||
"main": "canisters/name-registry/src/main.rs", | ||
"type": "rust", | ||
"candid": "canisters/name-registry/spec.did", | ||
"package": "cns-domain-registry" | ||
} | ||
}, | ||
"output_env_file": ".env", | ||
"version": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# A Minimal CNS (WIP) | ||
|
||
This folder contains an experimental implementation of a "minimal" MVP CNS. | ||
While it uses [the full CNS API](../canisters/name-registry/spec.did), it implements | ||
only a small part of the API, necessary to support basic CNS use cases. | ||
Currently, the following components are being worked on: | ||
- A minimal [CNS root canister](./src/backend/cns_root.mo), that supports only the `lookup`-operation | ||
for a single TLD (`.icp`), returning an NC-entry for that TLD, and otherwise returns unsupported/error | ||
(in particular, it does not support registration of new TLD operators yet). Having such a CNS root | ||
initially is to ensure that the client libraries’ flows are correct from the very beginning, | ||
i.e. they won’t change once we add other TLDs. | ||
|
||
|
||
## Test instuctions | ||
|
||
``` | ||
dfx start --clean --background | ||
dfx canister create name_registry | ||
dfx canister create cns_root | ||
dfx canister create cns_root_test | ||
dfx deploy cns_root | ||
dfx deploy cns_root_test | ||
dfx canister call cns_root_test runTests "()" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import NameRegistry "canister:name_registry"; | ||
import Text "mo:base/Text"; | ||
|
||
shared actor class () { | ||
let icpTld = ".icp"; | ||
let icpTldCanisterId = "qoctq-giaaa-aaaaa-aaaea-cai"; | ||
|
||
public shared func lookup(domain : Text, recordType : Text) : async NameRegistry.DomainLookup { | ||
var answers : [NameRegistry.DomainRecord] = []; | ||
var authorities : [NameRegistry.DomainRecord] = []; | ||
|
||
if (Text.endsWith(Text.toLowercase(domain), #text icpTld)) { | ||
switch (Text.toUppercase(recordType)) { | ||
case ("NC") { | ||
answers := [{ | ||
name = ".icp."; | ||
record_type = "NC"; | ||
ttl = 3600; | ||
data = icpTldCanisterId; | ||
}]; | ||
}; | ||
case _ { | ||
authorities := [{ | ||
name = ".icp."; | ||
record_type = "NC"; | ||
ttl = 3600; | ||
data = icpTldCanisterId; | ||
}]; | ||
}; | ||
}; | ||
}; | ||
|
||
{ | ||
answers = answers; | ||
additionals = []; | ||
authorities = authorities; | ||
}; | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import CnsRoot "canister:cns_root"; | ||
|
||
actor { | ||
public func runTests() : async () { | ||
await shouldGetIcpTldOperatorForNcIcpLookups(); | ||
await shouldGetIcpTldOperatorForOtherIcpLookups(); | ||
await shouldNotGetOtherTldOperator(); | ||
}; | ||
|
||
let icpTldCanisterId = "qoctq-giaaa-aaaaa-aaaea-cai"; | ||
|
||
func shouldGetIcpTldOperatorForNcIcpLookups() : async () { | ||
for ( | ||
(domain, recordType) in [ | ||
(".icp", "NC"), | ||
("example.icp", "NC"), | ||
("another.ICP", "nc"), | ||
("one.more.Icp", "Nc"), | ||
].vals() | ||
) { | ||
let response = await CnsRoot.lookup(domain, recordType); | ||
assert (response.answers.size() == 1); | ||
assert (response.additionals.size() == 0); | ||
assert (response.authorities.size() == 0); | ||
let domainRecord = response.answers[0]; | ||
assert (domainRecord.name == ".icp."); | ||
assert (domainRecord.record_type == "NC"); | ||
assert (domainRecord.ttl == 3600); | ||
assert (domainRecord.data == icpTldCanisterId); | ||
}; | ||
}; | ||
|
||
func shouldGetIcpTldOperatorForOtherIcpLookups() : async () { | ||
for ( | ||
(domain, recordType) in [ | ||
(".icp", "CID"), | ||
("example.icp", "Cid"), | ||
("another.ICP", "cid"), | ||
("one.more.Icp", "CId"), | ||
("another.example.icp", "NS"), | ||
("yet.another.one.icp", "WeirdReordType"), | ||
].vals() | ||
) { | ||
let response = await CnsRoot.lookup(domain, recordType); | ||
assert (response.answers.size() == 0); | ||
assert (response.additionals.size() == 0); | ||
assert (response.authorities.size() == 1); | ||
let domainRecord = response.authorities[0]; | ||
assert (domainRecord.name == ".icp."); | ||
assert (domainRecord.record_type == "NC"); | ||
assert (domainRecord.ttl == 3600); | ||
assert (domainRecord.data == icpTldCanisterId); | ||
}; | ||
}; | ||
|
||
func shouldNotGetOtherTldOperator() : async () { | ||
for ( | ||
(domain, recordType) in [ | ||
(".fun", "NC"), | ||
("example.com", "NC"), | ||
("another.dfn", "NS"), | ||
("", "NC"), | ||
("one.more.dfn", "CID"), | ||
].vals() | ||
) { | ||
let response = await CnsRoot.lookup(domain, recordType); | ||
assert (response.answers.size() == 0); | ||
assert (response.additionals.size() == 0); | ||
assert (response.authorities.size() == 0); | ||
}; | ||
}; | ||
|
||
}; |