Skip to content

Commit

Permalink
feat: add triton-tui, a TUI for debugging programs in Triton assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-ferdinand committed Dec 21, 2023
2 parents 560f255 + 2629d06 commit d0d79bc
Show file tree
Hide file tree
Showing 33 changed files with 4,350 additions and 34 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["triton-vm", "constraint-evaluation-generator"]
members = ["triton-vm", "triton-tui", "constraint-evaluation-generator"]
resolver = "2"

[profile.test]
Expand Down
43 changes: 43 additions & 0 deletions triton-tui/.config/default_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"keybindings": {
"Home": {
"<q>": "Quit",
"<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend",

"<h>": "Mode::Help",
"<m>": "Mode::Memory",

"<c>": "Continue",
"<s>": "Step",
"<n>": "Next",
"<f>": "Finish",
"<u>": "Undo",
"<r>": "Reset",

"<t><a>": "ToggleAll",
"<t><t>": "ToggleTypeHintDisplay",
"<t><c>": "ToggleCallStackDisplay",
"<t><s>": "ToggleSpongeStateDisplay",
"<t><i>": "ToggleInputDisplay"
},
"Help": {
"<q>": "Quit",
"<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend",

"<h>": "HideHelpScreen",
"<m>": "Mode::Memory",
"<esc>": "Mode::Home"
},
"Memory": {
"<q>": "Quit",
"<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend",

"<h>": "Mode::Help",
"<m>": "Mode::Home",
"<esc>": "Mode::Home"
}
}
}
3 changes: 3 additions & 0 deletions triton-tui/.envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export TRITON_TUI_CONFIG=$(pwd)/.config
export TRITON_TUI_DATA=$(pwd)/.data
export TRITON_TUI_LOG_LEVEL=debug
57 changes: 57 additions & 0 deletions triton-tui/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[package]
name = "triton-tui"
description = "A TUI that helps debugging programs written for Triton VM."

version.workspace = true
edition.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true

[dependencies]
arbitrary.workspace = true
better-panic = "0.3"
clap = { version = "4", features = ["derive", "cargo", "wrap_help", "unicode", "string", "unstable-styles"] }
color-eyre = "0.6"
config = "0.13"
crossterm = { version = "0.27", features = ["serde", "event-stream"] }
derive_deref = "1"
directories = "5"
fs-err = "2.0"
futures = "0.3"
human-panic = "1"
itertools.workspace = true
lazy_static.workspace = true
libc = "0.2"
num-traits.workspace = true
ratatui = { version = "0.25", features = ["serde", "macros"] }
serde.workspace = true
serde_json = "1.0"
signal-hook = "0.3"
strip-ansi-escapes = "0.2"
strum.workspace = true
tokio = { version = "1", features = ["full"] }
tokio-util = "0.7"
tracing = "0.1"
tracing-error = "0.2"
tracing-subscriber = { version = "0.3", features = ["env-filter", "serde"] }
triton-vm = { path = "../triton-vm" }
tui-textarea = "0.4"

[dev-dependencies]
assert2.workspace = true
pretty_assertions.workspace = true
proptest.workspace = true
proptest-arbitrary-interop.workspace = true
rexpect = "0.5"
test-strategy.workspace = true

[[bin]]
name = "triton-tui"
path = "src/main.rs"

[[test]]
name = "integration"
path = "tests/tests.rs"
29 changes: 29 additions & 0 deletions triton-tui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Triton TUI

A TUI to run and debug programs written for Triton VM.

<img alt="Example run of Triton TUI" src="./examples/triton-tui.gif" width="800" />

## Getting Started

Triton TUI tries to be helpful 🙂. List possible (and required) arguments with `triton-tui --help`. In the TUI, press `h` to access the help screen.

The [example program](./examples/program.tasm), serving as the tutorial, can be run with

```sh
triton-tui --program examples/program.tasm
```

## Installation

Through [crates.io](https://crates.io/crates/triton-tui):

```sh
cargo install triton-tui
```

Locally:

```sh
cargo install --path .
```
62 changes: 62 additions & 0 deletions triton-tui/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
fn main() {
let git_dir = maybe_get_git_dir();
trigger_rebuild_if_head_or_some_relevant_ref_changes(git_dir);

let git_output = std::process::Command::new("git")
.args(["describe", "--always", "--tags", "--long", "--dirty"])
.output()
.ok();
let git_info = git_output
.as_ref()
.and_then(|output| std::str::from_utf8(&output.stdout).ok().map(str::trim));
let cargo_pkg_version = env!("CARGO_PKG_VERSION");

// Default git_describe to cargo_pkg_version
let mut git_describe = String::from(cargo_pkg_version);

if let Some(git_info) = git_info {
// If the `git_info` contains `CARGO_PKG_VERSION`, we simply use `git_info` as it is.
// Otherwise, prepend `CARGO_PKG_VERSION` to `git_info`.
if git_info.contains(cargo_pkg_version) {
// Remove the 'g' before the commit sha
let git_info = &git_info.replace('g', "");
git_describe = git_info.to_string();
} else {
git_describe = format!("v{cargo_pkg_version}-{git_info}");
}
}

println!("cargo:rustc-env=TRITON_TUI_GIT_INFO={git_describe}");
}

fn maybe_get_git_dir() -> Option<String> {
let git_output = std::process::Command::new("git")
.args(["rev-parse", "--git-dir"])
.output()
.ok();
git_output.as_ref().and_then(|output| {
std::str::from_utf8(&output.stdout)
.ok()
.and_then(|s| s.strip_suffix('\n').or_else(|| s.strip_suffix("\r\n")))
.map(str::to_string)
})
}

fn trigger_rebuild_if_head_or_some_relevant_ref_changes(git_dir: Option<String>) {
if let Some(git_dir) = git_dir {
let git_path = std::path::Path::new(&git_dir);
let refs_path = git_path.join("refs");
if git_path.join("HEAD").exists() {
println!("cargo:rerun-if-changed={git_dir}/HEAD");
}
if git_path.join("packed-refs").exists() {
println!("cargo:rerun-if-changed={git_dir}/packed-refs");
}
if refs_path.join("heads").exists() {
println!("cargo:rerun-if-changed={git_dir}/refs/heads");
}
if refs_path.join("tags").exists() {
println!("cargo:rerun-if-changed={git_dir}/refs/tags");
}
}
}
5 changes: 5 additions & 0 deletions triton-tui/examples/non_determinism.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"individual_tokens" : [497, 598, 699],
"digests" : [[3, 4, 5, 6, 7], [4, 5, 6, 7, 8]],
"ram" : {"5": 50, "6": 60, "7": 70}
}
52 changes: 52 additions & 0 deletions triton-tui/examples/program.tasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Demonstrates use and functionality of the Triton VM TUI.
//!
//! Serves as the tutorial: execution intentionally fails at first, hopefully
//! encouraging you to play around. :) The inline comments should make matters trivial.
//!
//! Press `h` in Triton VM TUI to show the help screen.

// Let's start!
push 3
hint loop_counter = stack[0] // Current stack can be annotated to help debugging.
break

call my_loop
hint numbers: array = stack[1..4] // Annotations also work with ranges.

call check_result
call write_to_memory
call read_from_secret_input
call sponge_instructions
halt

my_loop:
dup 0 push 0 eq skiz return
read_io 3 // call with `--input ./public_input.txt`
mul mul
break
dup 0 write_io 1
swap 1 push -1 add recurse

check_result: // Try enabling
// pop 1 // <- this line for
assert // <- this assertion to work.
return // Hot reload & reset of the VM is `r`.

write_to_memory:
push 42
write_mem 2 // You can inspect memory with `m`.
pop 1
return

read_from_secret_input:
divine 3 // flag `--non-determinism ./non_determinism.json`
mul mul
swap 5
divine_sibling pop 5
divine_sibling hash
return

sponge_instructions:
sponge_init // Show the Sponge state with `t,s`.
sponge_squeeze
return
3 changes: 3 additions & 0 deletions triton-tui/examples/public_input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
2 3 5
17 19 42
1 1 1
Binary file added triton-tui/examples/triton-tui.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions triton-tui/examples/triton-tui.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Output triton-tui.gif

Set Shell zsh
Set Width 2000
Set Height 1000

Sleep 1s
Hide
Type "triton-tui -p ./program.tasm -i public_input.txt -n non_determinism.json"
Show
Sleep 1s
Enter
Sleep 3s

Type "c"
Sleep 2s
Type "c"
Sleep 2s
Type "c"
Sleep 2s
Type "ti"
Type "tc"
Sleep 2s
Type "ff"
Sleep 3s

Type "m"
Sleep 3s
Enter
Type "30"
Enter
Sleep 3s

Hide
Type "q"
Ctrl+D
Loading

0 comments on commit d0d79bc

Please sign in to comment.