Skip to content

Commit

Permalink
Avoid double jamming prove arguments in Anoma CLI commands (#3298)
Browse files Browse the repository at this point in the history
This PR changes the way program arguments are processed by the `juvix
dev nockma run {with-client, ephemeral-client}` and `juvix dev anoma
prove` CLI commands.

Files provided in `--arg 'bytes:..'` and `--arg 'base64:..'` flags are
now assumed to be jammed and are not jammed again before they are
submitted to the Anoma client.

## Changes in anoma-apps

The Anoma apps in anoma-apps use the `prove` CLI command and so the
signatures of their `main` functions will change:

For example, in
[HelloWorld.juvix](https://github.com/anoma/anoma-apps/blob/6132630209dacb47b8511b2d5b60859af46f2437/HelloWorld/HelloWorld.juvix)
the logic is passed as a jammed noun in an argument to prove.

Previously the argument was jammed again before being sent and so had to
be decoded in the `main` function before being used (the Anoma client
cues (i.e decodes) the argument once before calling the program).

```
main (encodedLogic : Encoded Logic) (message : String) : TransactionRequest
```

After the change in this PR, the logic argument is not jammed again
before being sent to the Anoma client and so the signature of the main
function should be changed to:

```
main (logic : Logic) (message : String) : TransactionRequest
```
  • Loading branch information
paulcadman authored Jan 29, 2025
1 parent 7d1c6a4 commit 27cc711
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 19 deletions.
31 changes: 18 additions & 13 deletions app/Commands/Dev/Anoma/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,31 @@ runNock ::
AppPath File ->
[ProveArg] ->
Sem r Anoma.RunNockmaResult
runNock programFile pargs = do
argsfile <- fromAppPathFile programFile
parsedTerm <- runAppError @JuvixError (Nockma.cueJammedFileOrPretty argsfile)
args <- mapM proveArgToTerm pargs
runNock programAppPath pargs = do
programFile <- fromAppPathFile programAppPath
parsedProgram <- runAppError @JuvixError (Nockma.cueJammedFileOrPretty programFile)
args <- mapM prepareArg pargs
Anoma.runNockma
Anoma.RunNockmaInput
{ _runNockmaProgram = parsedTerm,
{ _runNockmaProgram = parsedProgram,
_runNockmaArgs = args
}

proveArgToTerm :: forall r. (Members '[Error SimpleError, Files, App] r) => ProveArg -> Sem r (Term Natural)
proveArgToTerm = \case
ProveArgNat n -> return (toNock n)
ProveArgBytes n -> fromAppPathFile n >>= readFileBS' >>= fromBytes
prepareArg :: forall r. (Members '[Error SimpleError, Files, App] r) => ProveArg -> Sem r Anoma.RunNockmaArg
prepareArg = \case
ProveArgNat n -> return (Anoma.RunNockmaArgTerm (toNock n))
ProveArgBytes n -> do
bs <- readAppFile n
Anoma.RunNockmaArgJammed <$> fromBytes bs
ProveArgBase64 n -> do
bs <- Base64.decodeLenient <$> (fromAppPathFile n >>= readFileBS')
fromBytes bs
bs <- readAppFile n
Anoma.RunNockmaArgJammed <$> fromBytes (Base64.decodeLenient bs)
where
fromBytes :: ByteString -> Sem r (Term Natural)
fromBytes b = TermAtom <$> asSimpleErrorShow @NockNaturalNaturalError (byteStringToAtom @Natural b)
fromBytes :: ByteString -> Sem r (Atom Natural)
fromBytes b = asSimpleErrorShow @NockNaturalNaturalError (byteStringToAtom @Natural b)

readAppFile :: AppPath File -> Sem r ByteString
readAppFile f = fromAppPathFile f >>= readFileBS'

-- | Calls Anoma.Protobuf.Mempool.AddTransaction
addTransaction ::
Expand Down
4 changes: 2 additions & 2 deletions app/Commands/Dev/Anoma/Prove/Options/ProveArgTag.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ proveArgTagHelp = itemize (tagHelp <$> allElements)
let mvar, explain :: AnsiDoc
(mvar, explain) = first sty $ case t of
ProveArgTagNat -> ("NATURAL", "is passed verbatim as a nockma atom")
ProveArgTagBase64 -> ("FILE", "is a file with a base64 encoded nockma atom")
ProveArgTagBytes -> ("FILE", "is a file with a byte encoded nockma atom")
ProveArgTagBase64 -> ("FILE", "is a file containing a base64 encoded nockma atom that represents a jammed noun")
ProveArgTagBytes -> ("FILE", "is a file containing bytes of a nockma atom that represents a jammed noun")
sty = annotate (bold <> colorDull Blue)
tagvar :: AnsiDoc
tagvar = sty (show t <> ":" <> mvar)
Expand Down
17 changes: 15 additions & 2 deletions src/Anoma/Effect/RunNockma.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@ import Juvix.Prelude
import Juvix.Prelude.Aeson (Value)
import Juvix.Prelude.Aeson qualified as Aeson

-- | An argument to a program sent to the RunNock endpoint
data RunNockmaArg
= -- | An argument that must be jammed before it is sent
RunNockmaArgTerm (Nockma.Term Natural)
| -- | An argument that is already jammed and must not be jammed again before it is sent
RunNockmaArgJammed (Nockma.Atom Natural)

data RunNockmaInput = RunNockmaInput
{ _runNockmaProgram :: Nockma.Term Natural,
_runNockmaArgs :: [Nockma.Term Natural]
_runNockmaArgs :: [RunNockmaArg]
}

data RunNockmaResult = RunNockmaResult
Expand All @@ -33,7 +40,7 @@ runNockma ::
Sem r RunNockmaResult
runNockma i = do
let prog' = encodeJam64 (i ^. runNockmaProgram)
args = map (NockInputJammed . encodeJam64) (i ^. runNockmaArgs)
args = map prepareArgument (i ^. runNockmaArgs)
msg =
RunNock
{ _runNockJammedProgram = prog',
Expand All @@ -54,3 +61,9 @@ runNockma i = do
_runNockmaTraces = traces
}
ResponseError err -> throw (SimpleError (mkAnsiText (err ^. errorError)))
where
prepareArgument :: RunNockmaArg -> NockInput
prepareArgument =
NockInputJammed . \case
RunNockmaArgTerm t -> encodeJam64 t
RunNockmaArgJammed a -> naturalToBase64 (a ^. Nockma.atom)
4 changes: 4 additions & 0 deletions src/Juvix/Compiler/Nockma/Encoding/ByteString.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Data.Bit (Bit)
import Data.Bit qualified as Bit
import Data.Bits
import Data.ByteString qualified as BS
import Data.ByteString.Base64 qualified as Base64
import Data.ByteString.Builder qualified as BS
import Juvix.Compiler.Nockma.Encoding.Base
import Juvix.Compiler.Nockma.Encoding.Effect.BitReader
Expand Down Expand Up @@ -32,6 +33,9 @@ byteStringToNatural = fromInteger . byteStringToIntegerLE
naturalToByteString :: Natural -> ByteString
naturalToByteString = naturalToByteStringLE

naturalToBase64 :: Natural -> Text
naturalToBase64 = decodeUtf8 . Base64.encode . naturalToByteString

byteStringToIntegerLE :: ByteString -> Integer
byteStringToIntegerLE = BS.foldr (\b acc -> acc `shiftL` 8 .|. fromIntegral b) 0

Expand Down
2 changes: 1 addition & 1 deletion test/Anoma/Client/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ proveAndSubmit program proveArgs = do
runNockma
RunNockmaInput
{ _runNockmaProgram = program,
_runNockmaArgs = proveArgs
_runNockmaArgs = map RunNockmaArgTerm proveArgs
}
step "Submitting transaction candidate"
addTransaction
Expand Down
2 changes: 1 addition & 1 deletion test/Anoma/Compilation/Positive.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ mkAnomaNodeTest a@AnomaTest {..} =
let rinput =
RunNockmaInput
{ _runNockmaProgram = program,
_runNockmaArgs = _anomaArgs
_runNockmaArgs = map RunNockmaArgTerm _anomaArgs
}
out <- runNockma rinput
runM
Expand Down

0 comments on commit 27cc711

Please sign in to comment.