Skip to content

Commit

Permalink
Merge pull request #187 from Consensys/80-organisation-of-lt-binary-t…
Browse files Browse the repository at this point in the history
…race-format

feat: Support `lt` Binary Trace Format
  • Loading branch information
DavePearce authored Jun 26, 2024
2 parents 1ded643 + ce414d7 commit c00e1cc
Show file tree
Hide file tree
Showing 11 changed files with 660 additions and 130 deletions.
15 changes: 7 additions & 8 deletions pkg/cmd/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ var checkCmd = &cobra.Command{
Traces can be given either as JSON or binary lt files.
Constraints can be given either as lisp or bin files.`,
Run: func(cmd *cobra.Command, args []string) {
var trace *trace.ArrayTrace
var hirSchema *hir.Schema
var cfg checkConfig

Expand All @@ -37,7 +36,7 @@ var checkCmd = &cobra.Command{
// TODO: support true ranges
cfg.padding.Left = cfg.padding.Right
// Parse trace
trace = readTraceFile(args[0])
trace := readTraceFile(args[0])
// Parse constraints
hirSchema = readSchemaFile(args[1])
// Go!
Expand Down Expand Up @@ -71,7 +70,7 @@ type checkConfig struct {

// Check a given trace is consistently accepted (or rejected) at the different
// IR levels.
func checkTraceWithLowering(tr *trace.ArrayTrace, schema *hir.Schema, cfg checkConfig) {
func checkTraceWithLowering(tr trace.Trace, schema *hir.Schema, cfg checkConfig) {
if !cfg.hir && !cfg.mir && !cfg.air {
// Process together
checkTraceWithLoweringDefault(tr, schema, cfg)
Expand All @@ -91,7 +90,7 @@ func checkTraceWithLowering(tr *trace.ArrayTrace, schema *hir.Schema, cfg checkC
}
}

func checkTraceWithLoweringHir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg checkConfig) {
func checkTraceWithLoweringHir(tr trace.Trace, hirSchema *hir.Schema, cfg checkConfig) {
trHIR, errHIR := checkTrace(tr, hirSchema, cfg)
//
if errHIR != nil {
Expand All @@ -100,7 +99,7 @@ func checkTraceWithLoweringHir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg
}
}

func checkTraceWithLoweringMir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg checkConfig) {
func checkTraceWithLoweringMir(tr trace.Trace, hirSchema *hir.Schema, cfg checkConfig) {
// Lower HIR => MIR
mirSchema := hirSchema.LowerToMir()
// Check trace
Expand All @@ -112,7 +111,7 @@ func checkTraceWithLoweringMir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg
}
}

func checkTraceWithLoweringAir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg checkConfig) {
func checkTraceWithLoweringAir(tr trace.Trace, hirSchema *hir.Schema, cfg checkConfig) {
// Lower HIR => MIR
mirSchema := hirSchema.LowerToMir()
// Lower MIR => AIR
Expand All @@ -127,7 +126,7 @@ func checkTraceWithLoweringAir(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg

// The default check allows one to compare all levels against each other and
// look for any discrepenacies.
func checkTraceWithLoweringDefault(tr *trace.ArrayTrace, hirSchema *hir.Schema, cfg checkConfig) {
func checkTraceWithLoweringDefault(tr trace.Trace, hirSchema *hir.Schema, cfg checkConfig) {
// Lower HIR => MIR
mirSchema := hirSchema.LowerToMir()
// Lower MIR => AIR
Expand All @@ -154,7 +153,7 @@ func checkTraceWithLoweringDefault(tr *trace.ArrayTrace, hirSchema *hir.Schema,
}
}

func checkTrace(tr *trace.ArrayTrace, schema sc.Schema, cfg checkConfig) (trace.Trace, error) {
func checkTrace(tr trace.Trace, schema sc.Schema, cfg checkConfig) (trace.Trace, error) {
if cfg.expand {
// Clone to prevent interefence with subsequent checks
tr = tr.Clone()
Expand Down
79 changes: 79 additions & 0 deletions pkg/cmd/trace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package cmd

import (
"fmt"
"os"
"strings"

"github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/util"
"github.com/spf13/cobra"
)

// traceCmd represents the trace command for manipulating traces.
var traceCmd = &cobra.Command{
Use: "trace [flags] trace_file",
Short: "Operate on a trace file.",
Long: `Operate on a trace file, such as converting
it from one format (e.g. lt) to another (e.g. json),
or filtering out modules, or listing columns, etc.`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) != 1 {
fmt.Println(cmd.UsageString())
os.Exit(1)
}
// Parse trace
trace := readTraceFile(args[0])
list := getFlag(cmd, "list")
filter := getString(cmd, "filter")
output := getString(cmd, "out")
//
if filter != "" {
trace = filterColumns(trace, filter)
}
if list {
listColumns(trace)
}
//
if output != "" {
writeTraceFile(output, trace)
}
},
}

// Construct a new trace containing only those columns from the original who
// name begins with the given prefix.
func filterColumns(tr trace.Trace, prefix string) trace.Trace {
ntr := trace.EmptyArrayTrace()
//
for i := uint(0); i < tr.Width(); i++ {
ith := tr.ColumnByIndex(i)
if strings.HasPrefix(ith.Name(), prefix) {
ntr.Add(ith)
}
}
// Done
return ntr
}

func listColumns(tr trace.Trace) {
tbl := util.NewTablePrinter(3, tr.Width())

for i := uint(0); i < tr.Width(); i++ {
ith := tr.ColumnByIndex(i)
elems := fmt.Sprintf("%d rows", ith.Height())
bytes := fmt.Sprintf("%d bytes", ith.Width()*ith.Height())
tbl.SetRow(i, ith.Name(), elems, bytes)
}

//
tbl.SetMaxWidth(64)
tbl.Print()
}

func init() {
rootCmd.AddCommand(traceCmd)
traceCmd.Flags().BoolP("list", "l", false, "detail the columns in the trace file")
traceCmd.Flags().StringP("out", "o", "", "Specify output file to write trace")
traceCmd.Flags().StringP("filter", "f", "", "Filter columns beginning with prefix")
}
53 changes: 50 additions & 3 deletions pkg/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/consensys/go-corset/pkg/hir"
"github.com/consensys/go-corset/pkg/sexp"
"github.com/consensys/go-corset/pkg/trace"
"github.com/consensys/go-corset/pkg/trace/json"
"github.com/consensys/go-corset/pkg/trace/lt"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -46,9 +48,51 @@ func getUint(cmd *cobra.Command, flag string) uint {
return r
}

// Get an expected string, or panic if an error arises.
func getString(cmd *cobra.Command, flag string) string {
r, err := cmd.Flags().GetString(flag)
if err != nil {
fmt.Println(err)
os.Exit(4)
}

return r
}

// Write a given trace file to disk
func writeTraceFile(filename string, tr trace.Trace) {
var err error

var bytes []byte
// Check file extension
ext := path.Ext(filename)
//
switch ext {
case ".json":
js := json.ToJsonString(tr)
//
if err = os.WriteFile(filename, []byte(js), 0644); err == nil {
return
}
case ".lt":
bytes, err = lt.ToBytes(tr)
//
if err == nil {
if err = os.WriteFile(filename, bytes, 0644); err == nil {
return
}
}
default:
err = fmt.Errorf("Unknown trace file format: %s", ext)
}
// Handle error
fmt.Println(err)
os.Exit(4)
}

// Parse a trace file using a parser based on the extension of the filename.
func readTraceFile(filename string) *trace.ArrayTrace {
var tr *trace.ArrayTrace
func readTraceFile(filename string) trace.Trace {
var tr trace.Trace
// Read data file
bytes, err := os.ReadFile(filename)
// Check success
Expand All @@ -63,7 +107,10 @@ func readTraceFile(filename string) *trace.ArrayTrace {
return tr
}
case ".lt":
panic("Support for lt trace files not implemented (yet).")
tr, err = lt.FromBytes(bytes)
if err == nil {
return tr
}
default:
err = fmt.Errorf("Unknown trace file format: %s", ext)
}
Expand Down
Loading

0 comments on commit c00e1cc

Please sign in to comment.