Skip to content

Commit d31f8ca

Browse files
authored
fix: conflicting values in source map (#1153)
* fix: trace printing Trace printing was adding lots of awkward newlines when filtering was active. * fix: legacy reader and writer This puts through two separate fixes for the legacy reader and the legacy writer. The latter was a simple issue whereby an incorrect number of bytes were being written for variable sized word.BigEndian values. The legacy reader issue was, unfortunatly, more fundamental and related to the change in representation of the lt.TraceFile. Specifically, how it is now organised by module. The implementation attempted to read and organise at the same time, but was completely broken. Now, the original code is retained for reading with organisation occuring after the fact.
1 parent d04c566 commit d31f8ca

File tree

3 files changed

+104
-77
lines changed

3 files changed

+104
-77
lines changed

pkg/cmd/trace.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,16 @@ func printTraceFileHeader(header *lt.Header) {
294294
}
295295

296296
func printTrace(start uint, max_width uint, tf lt.TraceFile) {
297-
for i, module := range tf.Modules {
298-
if i != 0 {
299-
fmt.Println()
300-
}
301-
//
297+
var first = true
298+
299+
for _, module := range tf.Modules {
302300
if len(module.Columns) > 0 {
301+
if !first {
302+
fmt.Println()
303+
}
304+
//
305+
first = false
306+
//
303307
if module.Name != "" {
304308
fmt.Printf("%s:\n", module.Name)
305309
}

pkg/trace/lt/legacy_reader.go

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"encoding/binary"
1818
"strings"
1919

20+
"github.com/consensys/go-corset/pkg/util"
2021
"github.com/consensys/go-corset/pkg/util/collection/array"
2122
"github.com/consensys/go-corset/pkg/util/collection/pool"
2223
"github.com/consensys/go-corset/pkg/util/word"
@@ -27,97 +28,107 @@ import (
2728
// in some way. The input represents the original legacy format of trace files
2829
// (i.e. without any additional header information prepended, etc).
2930
func FromBytesLegacy(data []byte) (WordHeap, []Module[word.BigEndian], error) {
31+
var modules []Module[word.BigEndian]
32+
// Read out all column data
33+
heap, columns, error := readLegacyBytes(data)
34+
// Post process into structured form
35+
if error == nil {
36+
modules = groupLegacyColumns(columns)
37+
}
38+
//
39+
return heap, modules, error
40+
}
41+
42+
type legacyHeader struct {
43+
name string
44+
length uint
45+
width uint
46+
}
47+
48+
func groupLegacyColumns(columns []Column[word.BigEndian]) []Module[word.BigEndian] {
49+
var (
50+
modules []Module[word.BigEndian]
51+
modmap map[string]int = make(map[string]int)
52+
)
53+
// Process each column one by one
54+
for _, column := range columns {
55+
mod, col := splitQualifiedColumnName(column.Name)
56+
// Check whether module already allocated
57+
index, ok := modmap[mod]
58+
//
59+
if !ok {
60+
index = len(modules)
61+
modules = append(modules, Module[word.BigEndian]{mod, nil})
62+
modmap[mod] = index
63+
}
64+
// Update column name
65+
column.Name = col
66+
// Group it
67+
modules[index].Columns = append(modules[index].Columns, column)
68+
}
69+
//
70+
return modules
71+
}
72+
73+
func readLegacyBytes(data []byte) (WordHeap, []Column[word.BigEndian], error) {
3074
var (
3175
buf = bytes.NewReader(data)
3276
heap = pool.NewSharedHeap[word.BigEndian]()
3377
builder = array.NewDynamicBuilder(heap)
34-
names []string
35-
headers [][]legacyColumnHeader
36-
modmap map[string]uint = make(map[string]uint)
3778
)
3879
// Read Number of BytesColumns
3980
var ncols uint32
4081
if err := binary.Read(buf, binary.BigEndian, &ncols); err != nil {
4182
return WordHeap{}, nil, err
4283
}
84+
// Construct empty environment
85+
headers := make([]legacyHeader, ncols)
86+
columns := make([]Column[word.BigEndian], ncols)
4387
// Read column headers
4488
for i := uint32(0); i < ncols; i++ {
45-
var header, err = readLegacyColumnHeader(buf)
89+
header, err := readLegacyColumnHeader(buf)
4690
// Read column
4791
if err != nil {
4892
// Handle error
4993
return WordHeap{}, nil, err
5094
}
51-
// Split out module and column name
52-
mod, col := splitQualifiedColumnName(header.name)
53-
// Lookup module index
54-
index, ok := modmap[mod]
55-
// Check whether exists
56-
if !ok {
57-
index = uint(len(headers))
58-
modmap[mod] = index
59-
//
60-
headers = append(headers, nil)
61-
names = append(names, mod)
62-
}
63-
// Reset header name
64-
header.name = col
6595
// Assign header
66-
headers[index] = append(headers[index], header)
96+
headers[i] = header
6797
}
6898
// Determine byte slices
6999
offset := uint(len(data) - buf.Len())
70-
c := make(chan legacyResult, ncols)
71-
modules := make([]Module[word.BigEndian], len(headers))
100+
c := make(chan util.Pair[uint, array.MutArray[word.BigEndian]], ncols)
72101
// Dispatch go-routines
73-
for i, ith := range headers {
74-
modules[i] = Module[word.BigEndian]{
75-
Name: names[i],
76-
Columns: make([]Column[word.BigEndian], len(ith)),
77-
}
78-
//
79-
for j, jth := range ith {
80-
// Calculate length (in bytes) of this column
81-
nbytes := jth.width * jth.length
82-
// Dispatch go-routine
83-
go func(mid, cid int, offset uint, header legacyColumnHeader) {
84-
// Read column data
85-
elements := readColumnData(header, data[offset:offset+nbytes], builder)
86-
// Package result
87-
c <- legacyResult{mid, cid, elements}
88-
}(i, j, offset, jth)
89-
// Update byte offset
90-
offset += nbytes
91-
}
102+
for i := uint(0); i < uint(ncols); i++ {
103+
ith := headers[i]
104+
// Calculate length (in bytes) of this column
105+
nbytes := ith.width * ith.length
106+
// Dispatch go-routine
107+
go func(i uint, offset uint) {
108+
// Read column data
109+
elements := readColumnData(ith, data[offset:offset+nbytes], builder)
110+
// Package result
111+
c <- util.NewPair(i, elements)
112+
}(i, offset)
113+
// Update byte offset
114+
offset += nbytes
92115
}
93116
// Collect results
94-
for range ncols {
117+
for i := uint(0); i < uint(ncols); i++ {
95118
// Read packaged result from channel
96119
res := <-c
97-
// Determine column name
98-
name := headers[res.module][res.column].name
120+
// Split qualified column name
121+
name := headers[res.Left].name
99122
// Construct appropriate slice
100-
modules[res.module].Columns[res.column] = Column[word.BigEndian]{Name: name, Data: res.data}
123+
columns[res.Left] = Column[word.BigEndian]{Name: name, Data: res.Right}
101124
}
102125
// Done
103-
return *heap.Localise(), modules, nil
104-
}
105-
106-
type legacyResult struct {
107-
module int
108-
column int
109-
data array.MutArray[word.BigEndian]
110-
}
111-
112-
type legacyColumnHeader struct {
113-
name string
114-
length uint
115-
width uint
126+
return *heap.Localise(), columns, nil
116127
}
117128

118129
// Read the meta-data for a specific column in this trace file.
119-
func readLegacyColumnHeader(buf *bytes.Reader) (legacyColumnHeader, error) {
120-
var header legacyColumnHeader
130+
func readLegacyColumnHeader(buf *bytes.Reader) (legacyHeader, error) {
131+
var header legacyHeader
121132
// Qualified column name length
122133
var nameLen uint16
123134
// Read column name length
@@ -149,7 +160,7 @@ func readLegacyColumnHeader(buf *bytes.Reader) (legacyColumnHeader, error) {
149160
return header, nil
150161
}
151162

152-
func readColumnData(header legacyColumnHeader, bytes []byte, heap ArrayBuilder) array.MutArray[word.BigEndian] {
163+
func readColumnData(header legacyHeader, bytes []byte, heap ArrayBuilder) array.MutArray[word.BigEndian] {
153164
// Handle special cases
154165
switch header.width {
155166
case 1:
@@ -180,7 +191,7 @@ func areAllBits(bytes []byte) bool {
180191
return true
181192
}
182193

183-
func readBitColumnData(header legacyColumnHeader, bytes []byte) array.MutArray[word.BigEndian] {
194+
func readBitColumnData(header legacyHeader, bytes []byte) array.MutArray[word.BigEndian] {
184195
arr := array.NewBitArray[word.BigEndian](header.length)
185196
//
186197
for i := uint(0); i < header.length; i++ {
@@ -208,7 +219,7 @@ func readByteColumnData(length uint, bytes []byte, start, stride uint) array.Mut
208219
return &arr
209220
}
210221

211-
func readWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray[word.BigEndian] {
222+
func readWordColumnData(header legacyHeader, bytes []byte) array.MutArray[word.BigEndian] {
212223
var (
213224
arr = array.NewSmallArray[uint16, word.BigEndian](header.length, header.width*8)
214225
offset = uint(0)
@@ -238,7 +249,7 @@ func readWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray[
238249
return &arr
239250
}
240251

241-
func readDWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray[word.BigEndian] {
252+
func readDWordColumnData(header legacyHeader, bytes []byte) array.MutArray[word.BigEndian] {
242253
var (
243254
arr = array.NewSmallArray[uint32, word.BigEndian](header.length, header.width*8)
244255
offset = uint(0)
@@ -260,7 +271,7 @@ func readDWordColumnData(header legacyColumnHeader, bytes []byte) array.MutArray
260271
return &arr
261272
}
262273

263-
func readQWordColumnData(header legacyColumnHeader, bytes []byte, builder ArrayBuilder) array.MutArray[word.BigEndian] {
274+
func readQWordColumnData(header legacyHeader, bytes []byte, builder ArrayBuilder) array.MutArray[word.BigEndian] {
264275
var (
265276
arr = builder.NewArray(header.length, header.width*8)
266277
offset = uint(0)
@@ -277,7 +288,7 @@ func readQWordColumnData(header legacyColumnHeader, bytes []byte, builder ArrayB
277288
}
278289

279290
// Read column data which is has arbitrary width
280-
func readArbitraryColumnData(header legacyColumnHeader, bytes []byte, builder ArrayBuilder,
291+
func readArbitraryColumnData(header legacyHeader, bytes []byte, builder ArrayBuilder,
281292
) array.MutArray[word.BigEndian] {
282293
var (
283294
arr = builder.NewArray(header.length, header.width*8)

pkg/trace/lt/legacy_writer.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func WriteBytes(modules []Module[word.BigEndian], buf io.Writer) error {
8787
// Write column data information
8888
for _, ith := range modules {
8989
for _, jth := range ith.Columns {
90-
if err := writeArrayBytes(buf, jth.Data); err != nil {
90+
if err := writeArrayBytes(buf, jth.Data, jth.Data.BitWidth()); err != nil {
9191
return err
9292
}
9393
}
@@ -96,13 +96,25 @@ func WriteBytes(modules []Module[word.BigEndian], buf io.Writer) error {
9696
return nil
9797
}
9898

99-
func writeArrayBytes(w io.Writer, data array.Array[word.BigEndian]) error {
99+
func writeArrayBytes(w io.Writer, data array.Array[word.BigEndian], bitwidth uint) error {
100+
var (
101+
bytewidth = word.ByteWidth(bitwidth)
102+
padding = make([]byte, bytewidth)
103+
)
104+
//
100105
for i := range data.Len() {
101-
ith := data.Get(i)
102-
// Read exactly 32 bytes
103-
bytes := ith.Bytes()
104-
// Write them out
105-
if _, err := w.Write(bytes[:]); err != nil {
106+
var (
107+
ith = data.Get(i)
108+
bytes = ith.Bytes()
109+
// Determine padding bytes required
110+
n = bytewidth - uint(len(bytes))
111+
)
112+
// Write most significant (i.e. padding) bytes
113+
if _, err := w.Write(padding[0:n]); err != nil {
114+
return err
115+
}
116+
// Write least significant (i.e. content) bytes
117+
if _, err := w.Write(bytes); err != nil {
106118
return err
107119
}
108120
}

0 commit comments

Comments
 (0)