Skip to content

Commit

Permalink
Principal namespaces (#1507)
Browse files Browse the repository at this point in the history
* update pact for pact-4.4

* set up initial gas environment

* wip fix tests

* fix rosetta gas bound

* update pin to latest master

* Fix spcae mistake in ns.pact

* get started on pactinprocapi test

* wip tests to pre/post fork conditions in define-keyset

* all tests pre-post fork

* update pin with latest master

* Remove now nonexistent flag

* initial rewrite

* remove unnecessary flag

* parser fixes

* kludgy first implementation

* WIP repl tests

* Add initial coverage, get code working

* latest pact master

* bless old contract

* add ns-v2.yaml

* hook up repl tests to pact tests for ns (v1 and v2)

* undo checkpointer change

* move stale logic out of contract defn

* Principal namespaces: use hashes, rework upgrade methodology (#1534)

* slp: move files around for better diff, get gas payer working

* don't use registry for principal namespaces

* remove dupe validate

* fix mainnet genesis yaml

* use previous install in repl

* move to hashes of principals

* prefix namespaces with "n"

* move to 160 bit hex namespaces

* use "n_" prefix

* update comment

Co-authored-by: Stuart Popejoy <[email protected]>

* add typecheck for principal type + test

* add (wip) test for failed upgrade + comments

* purge pact history

* add weird test for upgrades

* stuarts comments

Co-authored-by: Jose <[email protected]>
Co-authored-by: Edmund Noble <[email protected]>
Co-authored-by: Edmund Noble <[email protected]>
Co-authored-by: Stuart Popejoy <[email protected]>
Co-authored-by: Stuart Popejoy <[email protected]>
  • Loading branch information
6 people authored Nov 18, 2022
1 parent 87dc1c0 commit b1ebd0b
Show file tree
Hide file tree
Showing 9 changed files with 352 additions and 33 deletions.
1 change: 1 addition & 0 deletions pact/gas-payer/gas-payer-v1.repl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
(env-data {'gas-payer-operate: ["operate"]})
(env-keys ["operate"])

(env-exec-config ['DisablePact44])
(load "gas-payer-v1-reference.pact")

(verify "user.gas-payer-v1-reference")
Expand Down
2 changes: 1 addition & 1 deletion pact/genesis/mainnet/ns.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
codeFile: ../../namespaces/ns.pact
codeFile: ../../namespaces/v1/ns.pact
data:
ns-admin-keyset:
keys:
Expand Down
2 changes: 1 addition & 1 deletion pact/genesis/ns.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
codeFile: ../namespaces/ns.pact
codeFile: ../namespaces/v1/ns.pact
data:
ns-admin-keyset: ["368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca"]
ns-operate-keyset: ["368820f80c324bbc7c2b0610688a7da43e39f91d118732671cd9c7500ff43cca"]
Expand Down
61 changes: 32 additions & 29 deletions pact/namespaces/ns.pact
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@

(define-keyset 'ns-admin-keyset (read-keyset 'ns-admin-keyset))
(define-keyset 'ns-operate-keyset (read-keyset 'ns-genesis-keyset))

(module ns GOVERNANCE
"Administers definition of new namespaces in Chainweb."

Expand Down Expand Up @@ -31,25 +27,48 @@
(enforce (is-charset CHARSET_LATIN1 name)
"Name must be in latin1 charset"))

(defun create-principal-namespace:string
( g:guard
)
" Format principal namespace as Pact hash (BLAKE2b256) of principal \
\ in hex truncated to 160 bits (40 characters), prepended with 'n_'.\
\ Only w: and k: account protocols are supported. "

(let
((ty (typeof-principal (create-principal g))))

;; only w: and k: currently supported
(if (or (= ty "k:") (= ty "w:"))
(+ "n_" (take 40 (int-to-str 16 (str-to-int 64 (hash g)))))
(enforce false
(format "Unsupported guard protocol: {}" [ty]))
))
)

(defun validate:bool
( ns-name:string
ns-admin:guard
)
" Manages namespace install for Chainweb. Requires active row in registry \
" Manages namespace install for Chainweb. \
\ Allows principal namespaces. \
\ Non-principal namespaces require active row in registry \
\ for NS-NAME with guard matching NS-ADMIN."

(validate-name ns-name)
(if (= (create-principal-namespace ns-admin) ns-name)

true ;; allow principal namespaces

(with-default-read registry ns-name
{ 'admin-guard : ns-admin
, 'active : false }
{ 'admin-guard := ag
, 'active := is-active }
(with-default-read registry ns-name ;; otherwise enforce registry
{ 'admin-guard : ns-admin
, 'active : false }
{ 'admin-guard := ag
, 'active := is-active }

(enforce is-active "Inactive or unregistered namespace")
(enforce (= ns-admin ag) "Admin guard must match guard in registry")

true))
true)
))

(defun write-registry:string
( ns-name:string
Expand All @@ -73,20 +92,4 @@
( ns-name:string )
(read registry ns-name))

)

(create-table registry)

(write-registry "kadena"
(keyset-ref-guard 'ns-operate-keyset) true)
(write-registry "user" GUARD_FAILURE true)
(write-registry "free" GUARD_FAILURE true)

(define-namespace "kadena"
(keyset-ref-guard 'ns-operate-keyset)
(keyset-ref-guard 'ns-operate-keyset))

(define-namespace "user" GUARD_SUCCESS GUARD_FAILURE)
(define-namespace "free" GUARD_SUCCESS GUARD_FAILURE)
;;rotate to real operate keyset
(define-keyset 'ns-operate-keyset (read-keyset 'ns-operate-keyset))
)
124 changes: 123 additions & 1 deletion pact/namespaces/ns.repl
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
(env-exec-config ["DisablePact44", "DisablePact45"])
(begin-tx)

(env-data
{ 'ns-admin-keyset: ["admin"]
, 'ns-operate-keyset: ["operate"]
, 'ns-genesis-keyset: { "keys": [], "pred": "="} })

(load "v1/ns.pact")

(commit-tx)
(begin-tx)

;; Test that we can upgrade ns.pact only when appropriate keys
;; are in scope.
(expect-failure
"Cannot upgrade the namespace contract due to governance failure"
"tx failure on upgrade"
(try (enforce false "tx failure on upgrade") (load "ns.pact")))

(env-keys ['admin])
(load "ns.pact")

(commit-tx)
(begin-tx)

(env-namespace-policy false (ns.validate))

(begin-tx)
(namespace 'user)
(env-keys [])

Expand Down Expand Up @@ -67,6 +82,7 @@
(defcap G () (enforce false "disabled"))
(defun foo () 4))
(commit-tx)
(begin-tx)

(expect "kadena.mod2 works" 4 (kadena.mod2.foo))

Expand All @@ -85,3 +101,109 @@
(expect-failure
"must be latin1 charset"
(write-registry "emilyπ" GUARD_SUCCESS true))

(commit-tx)
(begin-tx)

(env-exec-config [])
(env-data
{ 'single :
["70c787fcfe6c6f4ec23d13c2e94682bc90952f7cec06c7dbac1c012b0b6678b9"]
, 'multi : ["a", "b"]
})

(expect
"single principal ns"
"n_c1a583206e24450af26de41110042b019695db8c"
(ns.create-principal-namespace (read-keyset 'single)))

(expect
"multi principal ns"
"n_64bfdef1c668b167c87f7cf329454c572e284664"
(ns.create-principal-namespace (read-keyset 'multi)))

(expect-failure
"Principal of other than admin keyset fails"
"Inactive or unregistered namespace"
(define-namespace
"n_c1a583206e24450af26de41110042b019695db8c"
(read-keyset 'single)
(read-keyset 'multi))
)

(define-namespace
"n_c1a583206e24450af26de41110042b019695db8c"
(read-keyset 'single)
(read-keyset 'single))

(define-namespace
"n_64bfdef1c668b167c87f7cf329454c572e284664"
(read-keyset 'multi)
(read-keyset 'multi))

(commit-tx)

(begin-tx "test rotation")
(env-keys
[ "70c787fcfe6c6f4ec23d13c2e94682bc90952f7cec06c7dbac1c012b0b6678b9" ])
;; rotate to multi/multi
(define-namespace
"n_c1a583206e24450af26de41110042b019695db8c"
(read-keyset 'multi)
(read-keyset 'multi))
;; rotate to multi/single
(env-keys ["a","b"])
(define-namespace
"n_c1a583206e24450af26de41110042b019695db8c"
(read-keyset 'multi)
(read-keyset 'single))
(rollback-tx)


(begin-tx)
(env-exec-config [])
(env-keys
[ "70c787fcfe6c6f4ec23d13c2e94682bc90952f7cec06c7dbac1c012b0b6678b9"
, "a"
, "b"
]
)

(namespace "n_c1a583206e24450af26de41110042b019695db8c")
(module modK G
(defcap G () true)
(defun f () 1))

(namespace "n_64bfdef1c668b167c87f7cf329454c572e284664")
(module modW G
(defcap G () true)
(defun f () 2))

(commit-tx)
(begin-tx)

(expect
"k: principal namespaces work"
1
(n_c1a583206e24450af26de41110042b019695db8c.modK.f))

(expect
"w: principal namespaces work"
2
(n_64bfdef1c668b167c87f7cf329454c572e284664.modW.f))

(commit-tx)
(begin-tx)

(env-data
{ "n_c1a583206e24450af26de41110042b019695db8c.failure": ['k]
})

(namespace "n_c1a583206e24450af26de41110042b019695db8c")
(define-keyset "n_c1a583206e24450af26de41110042b019695db8c.failure")

(expect-failure
"r: principal namespaces do not work"
"Unsupported guard protocol: r:"
(ns.create-principal-namespace
(keyset-ref-guard "n_c1a583206e24450af26de41110042b019695db8c.failure")))
92 changes: 92 additions & 0 deletions pact/namespaces/v1/ns.pact
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@

(define-keyset 'ns-admin-keyset (read-keyset 'ns-admin-keyset))
(define-keyset 'ns-operate-keyset (read-keyset 'ns-genesis-keyset))

(module ns GOVERNANCE
"Administers definition of new namespaces in Chainweb."

(defschema reg-entry
admin-guard:guard
active:bool)

(deftable registry:{reg-entry})

(defcap GOVERNANCE ()
(enforce-keyset 'ns-admin-keyset))

(defcap OPERATE ()
(enforce-keyset 'ns-operate-keyset))

(defconst GUARD_SUCCESS (create-user-guard (success)))
(defconst GUARD_FAILURE (create-user-guard (failure)))

(defun success ()
true)
(defun failure ()
(enforce false "Disabled"))

(defun validate-name (name)
(enforce (!= "" name) "Empty name not allowed")
(enforce (< (length name) 64) "Name must be less than 64 characters long")
(enforce (is-charset CHARSET_LATIN1 name)
"Name must be in latin1 charset"))

(defun validate:bool
( ns-name:string
ns-admin:guard
)
" Manages namespace install for Chainweb. Requires active row in registry \
\ for NS-NAME with guard matching NS-ADMIN."

(validate-name ns-name)

(with-default-read registry ns-name
{ 'admin-guard : ns-admin
, 'active : false }
{ 'admin-guard := ag
, 'active := is-active }

(enforce is-active "Inactive or unregistered namespace")
(enforce (= ns-admin ag) "Admin guard must match guard in registry")

true))

(defun write-registry:string
( ns-name:string
guard:guard
active:bool
)
" Write entry with GUARD and ACTIVE into registry for NAME. \
\ Guarded by operate keyset. "

(with-capability (OPERATE)

(validate-name ns-name)

(write registry ns-name
{ 'admin-guard: guard
, 'active: active })

"Register entry written"))

(defun query:object{reg-entry}
( ns-name:string )
(read registry ns-name))

)

(create-table registry)

(write-registry "kadena"
(keyset-ref-guard 'ns-operate-keyset) true)
(write-registry "user" GUARD_FAILURE true)
(write-registry "free" GUARD_FAILURE true)

(define-namespace "kadena"
(keyset-ref-guard 'ns-operate-keyset)
(keyset-ref-guard 'ns-operate-keyset))

(define-namespace "user" GUARD_SUCCESS GUARD_FAILURE)
(define-namespace "free" GUARD_SUCCESS GUARD_FAILURE)
;;rotate to real operate keyset
(define-keyset 'ns-operate-keyset (read-keyset 'ns-operate-keyset))
Loading

0 comments on commit b1ebd0b

Please sign in to comment.