kadena-io/pact

dynamic module ref bug

Opened this issue · 1 comments

Executing a stored module will result in a dynamic reference error, see below for an example:

(begin-tx "register interface")
(interface foo
  (defun bar:string(x:string)))
(commit-tx)

(begin-tx "register baz")
(module baz G
  (implements foo)
  (defcap G() true)
  (defun bar:string(x:string)
    (format "Hello {}" [x])))
(commit-tx)

(begin-tx "referencing module")
(module main G
  (defcap G() true)
  (defschema module-schema
    impl:module{foo})
  (deftable module-table:{module-schema})
  (defun register(h:string m:module{foo})
    (insert module-table h
      { 'impl: m }))
  (defun test (h:string x:string)
    (with-read module-table h
      { 'impl := impl }
      (impl::bar x)))
)
(create-table module-table)
(commit-tx)

will result in:

Error: resolveRef: dynamic ref not found: impl::bar

By annotating the type using a let, we can work around this issue:

  (defun test(h:string x:string)
    (with-read module-table h
      { 'impl := impl }
      (let ((mr:module{foo} impl)) (mr::bar x))))

Thank you @EnoF for bringing this up!

@rsoeldner @EnoF
Let me teach you a feature of Pact ;-) : bindings can be typed

You just need to write, and it works:

(defun test (h:string x:string)
    (with-read module-table h
      { 'impl := impl:module{foo} }
      (impl::bar x)))