Skip to content

Commit 06c9f2c

Browse files
authored
Add ETH dump (#1373)
* Add ETH dump * Fix lint
1 parent 9e8c2bf commit 06c9f2c

File tree

4 files changed

+135
-0
lines changed

4 files changed

+135
-0
lines changed

l2geth/core/state/statedb.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/ethereum-optimism/optimism/l2geth/common"
2828
"github.com/ethereum-optimism/optimism/l2geth/core/types"
2929
"github.com/ethereum-optimism/optimism/l2geth/crypto"
30+
"github.com/ethereum-optimism/optimism/l2geth/ethdumper"
3031
"github.com/ethereum-optimism/optimism/l2geth/log"
3132
"github.com/ethereum-optimism/optimism/l2geth/metrics"
3233
"github.com/ethereum-optimism/optimism/l2geth/rlp"
@@ -506,6 +507,7 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
506507
bal := value.Big()
507508
bal = bal.Add(bal, amount)
508509
s.SetState(dump.OvmEthAddress, key, common.BigToHash(bal))
510+
ethdumper.Write(addr)
509511
} else {
510512
stateObject := s.GetOrNewStateObject(addr)
511513
if stateObject != nil {
@@ -536,6 +538,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
536538
bal := value.Big()
537539
bal = bal.Sub(bal, amount)
538540
s.SetState(dump.OvmEthAddress, key, common.BigToHash(bal))
541+
ethdumper.Write(addr)
539542
} else {
540543
stateObject := s.GetOrNewStateObject(addr)
541544
if stateObject != nil {

l2geth/core/vm/evm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/ethereum-optimism/optimism/l2geth/common"
2929
"github.com/ethereum-optimism/optimism/l2geth/common/hexutil"
3030
"github.com/ethereum-optimism/optimism/l2geth/crypto"
31+
"github.com/ethereum-optimism/optimism/l2geth/ethdumper"
3132
"github.com/ethereum-optimism/optimism/l2geth/log"
3233
"github.com/ethereum-optimism/optimism/l2geth/params"
3334
"github.com/ethereum-optimism/optimism/l2geth/rollup/dump"
@@ -594,6 +595,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
594595
if len(input) >= 36 && bytes.Equal(input[:4], mintSigHash) {
595596
recipient := common.BytesToAddress(input[16:36])
596597
statedumper.WriteETH(recipient)
598+
ethdumper.Write(recipient)
597599
}
598600
}
599601

l2geth/ethdumper/dumper.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package ethdumper
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
"os"
7+
"sync"
8+
9+
"github.com/ethereum-optimism/optimism/l2geth/common"
10+
"github.com/ethereum-optimism/optimism/l2geth/log"
11+
)
12+
13+
type EthAddress struct {
14+
Addresses []common.Address `json:"addresses"`
15+
}
16+
17+
type EthDumper interface {
18+
Write(address common.Address)
19+
}
20+
21+
var DefaultEthDumper EthDumper
22+
23+
func NewEthDumper() EthDumper {
24+
path := os.Getenv("L2GETH_ETH_DUMP_PATH")
25+
if path == "" {
26+
return &noopEthDumper{}
27+
}
28+
29+
f, err := os.Open(path)
30+
if err != nil {
31+
panic(err)
32+
}
33+
34+
byteFile, err := io.ReadAll(f)
35+
if err != nil {
36+
panic(err)
37+
}
38+
if len(byteFile) == 0 {
39+
return &FileStateDumper{
40+
ethAddress: EthAddress{},
41+
ethCache: make(map[common.Address]bool),
42+
}
43+
}
44+
ethAddres := EthAddress{}
45+
err = json.Unmarshal(byteFile, &ethAddres)
46+
if err != nil {
47+
panic(err)
48+
}
49+
ethCache := make(map[common.Address]bool)
50+
for _, address := range ethAddres.Addresses {
51+
ethCache[address] = true
52+
}
53+
return &FileStateDumper{
54+
ethAddress: ethAddres,
55+
ethCache: ethCache,
56+
}
57+
}
58+
59+
type FileStateDumper struct {
60+
ethAddress EthAddress
61+
ethCache map[common.Address]bool
62+
mtx sync.Mutex
63+
}
64+
65+
func (s *FileStateDumper) Write(address common.Address) {
66+
s.mtx.Lock()
67+
defer s.mtx.Unlock()
68+
if s.ethCache[address] {
69+
return
70+
}
71+
s.ethCache[address] = true
72+
73+
s.ethAddress.Addresses = append(s.ethAddress.Addresses, address)
74+
75+
log.Info("Found eth address", "address", address, "total", len(s.ethAddress.Addresses))
76+
77+
content, err := json.Marshal(s.ethAddress)
78+
if err != nil {
79+
panic(err)
80+
}
81+
err = os.WriteFile(os.Getenv("L2GETH_ETH_DUMP_PATH"), content, 0644)
82+
if err != nil {
83+
panic(err)
84+
}
85+
}
86+
87+
type noopEthDumper struct {
88+
}
89+
90+
func (n *noopEthDumper) Write(address common.Address) {
91+
}
92+
93+
func init() {
94+
DefaultEthDumper = NewEthDumper()
95+
}
96+
97+
func Write(address common.Address) {
98+
DefaultEthDumper.Write(address)
99+
}

l2geth/ethdumper/dumper_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package ethdumper
2+
3+
import (
4+
"io"
5+
"os"
6+
"testing"
7+
8+
"github.com/ethereum-optimism/optimism/l2geth/common"
9+
)
10+
11+
func TestFileEthDumper(t *testing.T) {
12+
f, err := os.CreateTemp("", "")
13+
if err != nil {
14+
t.Fatalf("error creating file: %v", err)
15+
}
16+
err = os.Setenv("L2GETH_ETH_DUMP_PATH", f.Name())
17+
if err != nil {
18+
t.Fatalf("error setting env file: %v", err)
19+
}
20+
dumper := NewEthDumper()
21+
addr := common.Address{19: 0x01}
22+
dumper.Write(addr)
23+
data, err := io.ReadAll(f)
24+
if err != nil {
25+
t.Fatalf("error reading: %v", err)
26+
}
27+
dataStr := string(data)
28+
if dataStr != `{"addresses":["0x0000000000000000000000000000000000000001"]}` {
29+
t.Fatalf("invalid data. got: %s", dataStr)
30+
}
31+
}

0 commit comments

Comments
 (0)