Skip to content

Commit f824945

Browse files
lwedge99zfy0701
authored andcommitted
migrate memory compression (OffchainLabs#2)
1 parent f1a73c2 commit f824945

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

eth/tracers/logger/logger.go

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package logger
1818

1919
import (
20+
"bytes"
2021
"encoding/hex"
2122
"encoding/json"
2223
"fmt"
@@ -48,12 +49,13 @@ func (s Storage) Copy() Storage {
4849

4950
// Config are the configuration options for structured logger the EVM
5051
type Config struct {
51-
EnableMemory bool // enable memory capture
52-
DisableStack bool // disable stack capture
53-
DisableStorage bool // disable storage capture
54-
EnableReturnData bool // enable return data capture
55-
Debug bool // print output during capture end
56-
Limit int // maximum length of output, but zero means unlimited
52+
EnableMemory bool // enable memory capture
53+
DisableStack bool // disable stack capture
54+
DisableStorage bool // disable storage capture
55+
EnableReturnData bool // enable return data capture
56+
Debug bool // print output during capture end
57+
Limit int // maximum length of output, but zero means unlimited
58+
MemoryCompressionWindow int
5759
// Chain overrides, can be used to execute a trace using future fork rules
5860
Overrides *params.ChainConfig `json:"overrides,omitempty"`
5961
}
@@ -68,6 +70,7 @@ type StructLog struct {
6870
Gas uint64 `json:"gas"`
6971
GasCost uint64 `json:"gasCost"`
7072
Memory []byte `json:"memory,omitempty"`
73+
Meq *int `json:"meq,omitempty"`
7174
MemorySize int `json:"memSize"`
7275
Stack []uint256.Int `json:"stack"`
7376
ReturnData []byte `json:"returnData,omitempty"`
@@ -116,6 +119,10 @@ type StructLogger struct {
116119
gasLimit uint64
117120
usedGas uint64
118121

122+
prevMem [][]byte
123+
prevMemWindow int
124+
prevMemIdx int
125+
119126
interrupt atomic.Bool // Atomic flag to signal execution interruption
120127
reason error // Textual reason for the interruption
121128
}
@@ -127,6 +134,9 @@ func NewStructLogger(cfg *Config) *StructLogger {
127134
}
128135
if cfg != nil {
129136
logger.cfg = *cfg
137+
logger.prevMemWindow = cfg.MemoryCompressionWindow
138+
logger.prevMemIdx = 0
139+
logger.prevMem = make([][]byte, cfg.MemoryCompressionWindow)
130140
}
131141
return logger
132142
}
@@ -162,9 +172,36 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s
162172
contract := scope.Contract
163173
// Copy a snapshot of the current memory state to a new buffer
164174
var mem []byte
175+
var meq *int
165176
if l.cfg.EnableMemory {
166177
mem = make([]byte, len(memory.Data()))
167178
copy(mem, memory.Data())
179+
180+
foundEq := false
181+
if l.prevMemWindow > 0 {
182+
i := l.prevMemIdx
183+
for dist := 1; dist <= l.prevMemWindow; dist++ {
184+
if i--; i < 0 {
185+
i = l.prevMemWindow - 1
186+
}
187+
if len(l.prevMem[i]) == len(mem) && bytes.Equal(l.prevMem[i], mem) {
188+
foundEq = true
189+
meq = new(int)
190+
*meq = dist
191+
mem = nil
192+
break
193+
}
194+
}
195+
if l.prevMemIdx++; l.prevMemIdx == l.prevMemWindow {
196+
l.prevMemIdx = 0
197+
}
198+
if foundEq {
199+
l.prevMem[l.prevMemIdx] = l.prevMem[i]
200+
} else {
201+
l.prevMem[l.prevMemIdx] = make([]byte, len(mem))
202+
copy(l.prevMem[l.prevMemIdx], mem)
203+
}
204+
}
168205
}
169206
// Copy a snapshot of the current stack state to a new buffer
170207
var stck []uint256.Int
@@ -208,7 +245,7 @@ func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, s
208245
copy(rdata, rData)
209246
}
210247
// create a new snapshot of the EVM.
211-
log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
248+
log := StructLog{pc, op, gas, cost, mem, meq, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err}
212249
l.logs = append(l.logs, log)
213250
}
214251

0 commit comments

Comments
 (0)