Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add juvix dev anoma add-transaction command #3193

Merged
merged 8 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ env:
SKIP: ormolu,format-juvix-files,typecheck-juvix-examples
CAIRO_VM_VERSION: 06e8ddbfa14eef85f56c4d7b7631c17c9b0a248e
RISC0_VM_VERSION: v1.0.1
ANOMA_VERSION: 5adbfa3fe15604e20bc345dab0d74c415956ce15
ANOMA_VERSION: f52cd44235f35a907c22c428ce1fdf3237c97927
JUST_ARGS: runtimeCcArg=$CC runtimeLibtoolArg=$LIBTOOL
STACK_BUILD_ARGS: --pedantic -j4 --ghc-options=-j

Expand Down Expand Up @@ -132,10 +132,11 @@ jobs:
elixir-version: "1.17.3"
otp-version: "27.1"

# Anoma requires a newer version of protoc than is available from apt
- name: Install protoc
run: |
sudo apt install -y protobuf-compiler
protoc --version
curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v29.0/protoc-29.0-linux-x86_64.zip && \
unzip protoc-29.0-linux-x86_64.zip -d $HOME/.local

- name: Cache anoma
id: cache-anoma
Expand Down
28 changes: 19 additions & 9 deletions app/Commands/Dev/Anoma.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,42 @@ module Commands.Dev.Anoma
)
where

import Anoma.Client.Base
import Anoma.Client.Config
import Anoma.Effect.Base
import Commands.Base
import Commands.Dev.Anoma.AddTransaction.Options
import Commands.Dev.Anoma.Base
import Commands.Dev.Anoma.Client
import Commands.Dev.Anoma.Options
import Commands.Dev.Anoma.Prove qualified as Prove
import Commands.Dev.Anoma.Prove.Options
import Commands.Dev.Anoma.Start qualified as Start
import Juvix.Data.CodeAnn
import Juvix.Data.Yaml qualified as Y

runCommand :: forall r. (Members AppEffects r) => AnomaCommand -> Sem r ()
runCommand =
runAppError @SimpleError . \case
runCommand :: forall r. (Members AppEffects r) => AnomaCommandGlobal -> Sem r ()
runCommand g =
runAppError @SimpleError $ case (g ^. anomaCommandGlobalCommand) of
AnomaCommandStart opts -> Start.runCommand opts
AnomaCommandStatus -> checkRunning >>= renderStdOutLn . ppCodeAnn
AnomaCommandStop -> checkRunning >>= stopClient >> removeConfig
AnomaCommandProve opts -> do
host <- getHostConfig (opts ^. proveClientInfo)
runAnomaWithClient host (Prove.runCommand opts)
AnomaCommandProve opts ->
runAnomaWithHostConfig
(Prove.runCommand opts)
AnomaCommandAddTransaction opts ->
runAnomaWithHostConfig
(addTransaction (opts ^. addTransactionFile))
where
runAnomaWithHostConfig :: (Members (Error SimpleError ': AppEffects) x) => Sem (Anoma ': x) () -> Sem x ()
runAnomaWithHostConfig eff = do
host <- getHostConfig
runAnomaWithClient host eff

checkRunning :: (Members (Error SimpleError ': AppEffects) x) => Sem x ClientConfig
checkRunning = fromMaybeM (logInfo "The Anoma client is not running" >> exitFailure) checkClientRunning

getHostConfig :: (Members (Error SimpleError ': AppEffects) x) => Maybe (AppPath File) -> Sem x AnomaClientInfo
getHostConfig = \case
getHostConfig :: (Members (Error SimpleError ': AppEffects) x) => Sem x AnomaClientInfo
getHostConfig = case g ^. anomaCommandGlobalClientConfig of
Just p -> fromAppFile p >>= readClientInfo
Nothing -> (^. clientConfigHost) <$> checkRunning

Expand Down
15 changes: 15 additions & 0 deletions app/Commands/Dev/Anoma/AddTransaction/Options.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Commands.Dev.Anoma.AddTransaction.Options where

import CommonOptions

newtype AddTransactionOptions = AddTransactionOptions
{ _addTransactionFile :: AppPath File
}
deriving stock (Data)

makeLenses ''AddTransactionOptions

parseAddTransactionOptions :: Parser AddTransactionOptions
parseAddTransactionOptions = do
_addTransactionFile <- parseInputFile FileExtNockma
pure AddTransactionOptions {..}
47 changes: 38 additions & 9 deletions app/Commands/Dev/Anoma/Base.hs
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
module Commands.Dev.Anoma.Base where

import Anoma.Effect
import Anoma.Effect (Anoma)
import Anoma.Effect qualified as Anoma
import Commands.Base hiding (Atom)
import Juvix.Compiler.Nockma.Pretty
import Juvix.Compiler.Nockma.Translation.FromSource qualified as Nockma

cellOrFail ::
forall x r a.
(Member App r, Subset x r) =>
Term Natural ->
(Term Natural -> Sem x a) ->
Sem r a
cellOrFail term f = case term of
TermAtom {} -> exitFailMsg "Expected nockma input to be a cell"
t@(TermCell {}) -> inject (f t)

-- | Calls Anoma.Protobuf.NockService.Prove
runNock :: forall r. (Members '[Error SimpleError, Anoma] r, Members AppEffects r) => AppPath File -> Maybe (AppPath File) -> Sem r RunNockmaResult
runNock ::
forall r.
(Members '[Error SimpleError, Anoma] r, Members AppEffects r) =>
AppPath File ->
Maybe (AppPath File) ->
Sem r Anoma.RunNockmaResult
runNock programFile margsFile = do
afile <- fromAppPathFile programFile
argsFile <- mapM fromAppPathFile margsFile
parsedArgs <- runAppError @JuvixError (mapM Nockma.cueJammedFileOrPretty argsFile)
parsedTerm <- runAppError @JuvixError (Nockma.cueJammedFileOrPretty afile)
case parsedTerm of
TermAtom {} -> exitFailMsg "Expected nockma input to be a cell"
t@(TermCell {}) -> go t (maybe [] unfoldList parsedArgs)
cellOrFail parsedTerm (go (maybe [] unfoldList parsedArgs))
where
go :: Term Natural -> [Term Natural] -> Sem r RunNockmaResult
go t args =
runNockma
RunNockmaInput
go :: [Term Natural] -> Term Natural -> Sem r Anoma.RunNockmaResult
go args t =
Anoma.runNockma
Anoma.RunNockmaInput
{ _runNockmaProgram = t,
_runNockmaArgs = args
}

-- | Calls Anoma.Protobuf.Mempool.AddTransaction
addTransaction ::
forall r.
(Members '[Error SimpleError, Anoma] r, Members AppEffects r) =>
AppPath File ->
Sem r ()
addTransaction programFile = do
afile <- fromAppPathFile programFile
parsedTerm <- runAppError @JuvixError (Nockma.cueJammedFileOrPretty afile)
cellOrFail parsedTerm $ \t ->
Anoma.addTransaction
Anoma.AddTransactionInput
{ _addTransactionInputCandidate = t
}
63 changes: 39 additions & 24 deletions app/Commands/Dev/Anoma/Options.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module Commands.Dev.Anoma.Options where

import Commands.Dev.Anoma.AddTransaction.Options
import Commands.Dev.Anoma.Prove.Options
import Commands.Dev.Anoma.Start.Options
import CommonOptions
Expand All @@ -9,18 +10,30 @@ data AnomaCommand
| AnomaCommandStatus
| AnomaCommandStop
| AnomaCommandProve ProveOptions
| AnomaCommandAddTransaction AddTransactionOptions
deriving stock (Data)

parseAnomaCommand :: Parser AnomaCommand
data AnomaCommandGlobal = AnomaCommandGlobal
{ _anomaCommandGlobalClientConfig :: Maybe (AppPath File),
_anomaCommandGlobalCommand :: AnomaCommand
}
deriving stock (Data)

makeLenses ''AnomaCommandGlobal

parseAnomaCommand :: Parser AnomaCommandGlobal
parseAnomaCommand =
hsubparser
( mconcat
[ commandStart,
commandStatus,
commandStop,
commandProve
]
)
AnomaCommandGlobal
<$> optional anomaClientConfigOpt
<*> hsubparser
( mconcat
[ commandStart,
commandStatus,
commandStop,
commandProve,
commandAddTransaction
]
)
where
commandStart :: Mod CommandFields AnomaCommand
commandStart = command "start" runInfo
Expand Down Expand Up @@ -59,22 +72,24 @@ parseAnomaCommand =
( headerDoc
( Just
( vsep
[ "The prove command submits a Nockma program to the Anoma.Protobuf.NockService.Prove gRPC endpoint.",
"",
"By default, the gRPC request is made to the client that is started by juvix dev anoma start.",
"Use the -c/--config option to use a different Anoma client.",
"The config file format is:",
"",
"url: <ANOMA_CLIENT_URL>",
"port: <ANOMA_CLIENT_GRPC_PORT>",
"nodeid: <ANOMA_CLIENT_NODE_ID>",
"",
"The gRPC response (a Nockma program) is saved to a file named <input>.proved.nockma, where <input> is the base name of the input file.",
"Use the -o/--output option to specify a custom output filename.",
"",
"If the program generates traces, they will be written to standard output."
]
( [ "The prove command submits a Nockma program to the Anoma.Protobuf.NockService.Prove gRPC endpoint.",
"",
"The gRPC response (a Nockma program) is saved to a file named <input>.proved.nockma, where <input> is the base name of the input file.",
"Use the -o/--output option to specify a custom output filename.",
"",
"If the program generates traces, they will be written to standard output."
]
)
)
)
<> progDesc "Submit a Nockma program to Anoma.Protobuf.NockService.Prove"
)

commandAddTransaction :: Mod CommandFields AnomaCommand
commandAddTransaction = command "add-transaction" runInfo
where
runInfo :: ParserInfo AnomaCommand
runInfo =
info
(AnomaCommandAddTransaction <$> parseAddTransactionOptions)
(progDesc "Submit a Nockma transaction candidate to Anoma.Protobuf.Mempool.AddTransaction")
2 changes: 0 additions & 2 deletions app/Commands/Dev/Anoma/Prove/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import CommonOptions
data ProveOptions = ProveOptions
{ _proveFile :: AppPath File,
_proveArgs :: Maybe (AppPath File),
_proveClientInfo :: Maybe (AppPath File),
_proveOutputFile :: Maybe (AppPath File)
}
deriving stock (Data)
Expand All @@ -16,6 +15,5 @@ parseProveOptions :: Parser ProveOptions
parseProveOptions = do
_proveFile <- parseInputFile FileExtNockma
_proveArgs <- optional anomaArgsOpt
_proveClientInfo <- optional anomaClientConfigOpt
_proveOutputFile <- optional parseGenericOutputFile
pure ProveOptions {..}
28 changes: 23 additions & 5 deletions app/Commands/Dev/Options.hs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ data DevCommand
| JuvixDevRepl ReplOptions
| MigrateJuvixYaml MigrateJuvixYamlOptions
| Nockma NockmaCommand
| Anoma AnomaCommand
| Anoma AnomaCommandGlobal
deriving stock (Data)

parseDevCommand :: Parser DevCommand
Expand Down Expand Up @@ -212,7 +212,25 @@ commandNockma =

commandAnoma :: Mod CommandFields DevCommand
commandAnoma =
command "anoma" $
info
(Anoma <$> parseAnomaCommand)
(progDesc "Subcommands related to the Anoma client")
let descr :: (IsString a) => a
descr = "Subcommands related to the Anoma client"
in command "anoma" $
info
(Anoma <$> parseAnomaCommand)
( headerDoc
( Just
( vsep
[ descr,
"",
"By default, the gRPC request is made to the client that is started by juvix dev anoma start.",
"Use the -c/--config option to use a different Anoma client.",
"The config file format is:",
"",
"url: <ANOMA_CLIENT_URL>",
"port: <ANOMA_CLIENT_GRPC_PORT>",
"nodeid: <ANOMA_CLIENT_NODE_ID>"
]
)
)
<> progDesc descr
)
1 change: 1 addition & 0 deletions include/anoma/start.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(
Logger.configure(level: :none)
eclient = Anoma.Client.Examples.EClient.create_example_client
IO.puts("#{eclient.client.grpc_port} #{eclient.node.node_id}")
)
2 changes: 2 additions & 0 deletions src/Anoma/Effect.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
module Anoma.Effect
( module Anoma.Effect.Base,
module Anoma.Effect.RunNockma,
module Anoma.Effect.AddTransaction,
)
where

import Anoma.Effect.AddTransaction
import Anoma.Effect.Base
import Anoma.Effect.RunNockma
34 changes: 34 additions & 0 deletions src/Anoma/Effect/AddTransaction.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Anoma.Effect.AddTransaction
( module Anoma.Effect.AddTransaction,
module Anoma.Rpc.AddTransaction,
)
where

import Anoma.Effect.Base
import Anoma.Rpc.AddTransaction
import Juvix.Compiler.Nockma.Encoding
import Juvix.Compiler.Nockma.Language qualified as Nockma
import Juvix.Prelude
import Juvix.Prelude.Aeson qualified as Aeson

newtype AddTransactionInput = AddTransactionInput
{ _addTransactionInputCandidate :: Nockma.Term Natural
}

makeLenses ''AddTransactionInput

addTransaction ::
forall r.
(Members '[Anoma, Error SimpleError, Logger] r) =>
AddTransactionInput ->
Sem r ()
addTransaction i = do
nodeInfo <- getNodeInfo
let msg =
AddTransaction
{ _addTransactionNodeInfo = nodeInfo,
_addTransactionTransaction = encodeJam64 (i ^. addTransactionInputCandidate)
}
logMessageValue "Request payload" msg
-- addTransaction always returns an empty response
void (anomaRpc addTransactionGrpcUrl (Aeson.toJSON msg))
Loading
Loading