Skip to content

Commit

Permalink
Implement change-control for CNS nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Dec 21, 2023
1 parent 7fc2cfc commit 63ba128
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
22 changes: 19 additions & 3 deletions convex-core/src/main/cvx/convex/registry.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@

;; Controllers for each CNS node managed under this actor
;; Default root is controlled by INIT account
;; Checked for permissions:
;; :control - change CNS node ownership
;; :create - create new CNS entry in this node (child path segment as object)
;; :delete - delete CNS entry in this node (child path segment as object)
(def cns-owners
{[] #1})

Expand Down Expand Up @@ -124,22 +128,34 @@
(recur (inc i) (first rec))

;; need to construct a new CNS node
(let [nref [~*address* (slice path 0 (inc i))]]
(let []
(call ref (cns-write pname nref cont nil) )
(recur (inc i) (call ref (cns-read pname)))))
))
)
)
))

(defn change-control
^{:callable? true
:doc {:description "Changes controller for a CNS node."
:examples [{:code "(call *registry* (cns-control 'my.actor trust-monitor-address)"}]
:signature [{:params [name addr]}]}}
[cont]
(let [owners cns-owners
own (get owners *scope*)]
(if
(trust/trusted? own *caller* :control)
(set! cns-owners (assoc owners *scope* cont))
(fail :TRUST "No control right for CNS node"))))


(defn cns-control
^{:callable? true
:doc {:description "Updates a CNS name mapping to set a new controller. May only be performed by a current controller."
:examples [{:code "(call *registry* (cns-control 'my.actor trust-monitor-address)"}]
:signature [{:params [name addr]}]}}
[sym addr]
[sym controller]
(when-not (symbol? sym)
(fail :ARGUMENT "CNS names must be a valid symbol"))
(let [path (split (name sym) \.)
Expand All @@ -148,7 +164,7 @@
(fail :STATE "CNS record does not exist"))
(when (not (trust/trusted? (second record) *caller* :control))
(fail :TRUST "Caller is not trusted with transferring control for that CNS record"))
(set-in! cns-database [path 1] addr)))
(set-in! cns-database [path 1] controller)))

(defn cns-resolve
^{:callable? true
Expand Down
1 change: 0 additions & 1 deletion convex-core/src/main/cvx/convex/trust.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@
:examples [{:code "(set-control my-asset *address*)"}]
:signature [{:params [path controller]}]}}
[path controller]
(or (callable? controller) (fail :ARGUMENT "Invalid controller (must be callable)"))
(call path (change-control controller))
:OK)

Expand Down
8 changes: 8 additions & 0 deletions convex-core/src/test/java/convex/lib/CNSTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package convex.lib;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;

import convex.core.data.AVector;
import convex.core.data.Address;
import convex.core.init.Init;
import convex.core.lang.ACVMTest;
Expand Down Expand Up @@ -44,6 +46,9 @@ public class CNSTest extends ACVMTest {
Context ictx=context().forkWithAddress(Init.INIT_ADDRESS);
ictx=(step(ictx,"(*registry*/create 'foo #17)"));
assertNotError(ictx);
ictx=step(ictx,"(def ref [*registry* [\"foo\"]])");
AVector<?> ref=ictx.getResult();
assertNotNull(ref);

// System.out.println(eval(ictx,"*registry*/cns-database"));

Expand All @@ -55,7 +60,10 @@ public class CNSTest extends ACVMTest {
// HERO still shouldn't be able to update a top level CNS entry
ictx=ictx.forkWithAddress(HERO);
assertTrustError(step(ictx,"(*registry*/create 'foo *address* *address* {})"));
assertTrustError(step(ictx,"(trust/change-control "+ref+" *address*)"));

ictx=ictx.forkWithAddress(Init.INIT_ADDRESS);
ictx=(step(ictx,"(trust/change-control ref "+HERO+")"));
}

}

0 comments on commit 63ba128

Please sign in to comment.