Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: dump witness for bedrock migration #1357

Merged
merged 1 commit into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions l2geth/core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/mantlenetworkio/mantle/l2geth/rlp"
"github.com/mantlenetworkio/mantle/l2geth/rollup/dump"
"github.com/mantlenetworkio/mantle/l2geth/rollup/rcfg"
"github.com/mantlenetworkio/mantle/l2geth/statedumper"
"github.com/mantlenetworkio/mantle/l2geth/trie"
"golang.org/x/crypto/sha3"
)
Expand Down Expand Up @@ -244,6 +245,7 @@ func (s *StateDB) GetBalance(addr common.Address) *big.Int {
if rcfg.UsingBVM {
// Get balance from the bvm_ETH contract.
// NOTE: We may remove this feature in a future release.
statedumper.WriteETH(addr)
bradyjoestar marked this conversation as resolved.
Show resolved Hide resolved
key := GetbvmBalanceKey(addr)
bal := s.GetState(dump.BvmMantleAddress, key)
return bal.Big()
Expand Down Expand Up @@ -373,6 +375,7 @@ func (s *StateDB) HasSuicided(addr common.Address) bool {
// AddBalance adds amount to the account associated with addr.
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
if rcfg.UsingBVM {
statedumper.WriteETH(addr)
// Mutate the storage slot inside of bvm_ETH to change balances.
// Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below
Expand All @@ -393,6 +396,7 @@ func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
// SubBalance subtracts amount from the account associated with addr.
func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
if rcfg.UsingBVM {
statedumper.WriteETH(addr)
// Mutate the storage slot inside of bvm_ETH to change balances.
// Note that we don't need to check for overflows or underflows here because the code that
// uses this codepath already checks for them. You can follow the original codepath below
Expand All @@ -412,6 +416,7 @@ func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {

func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) {
if rcfg.UsingBVM {
statedumper.WriteETH(addr)
// Mutate the storage slot inside of bvm_ETH to change balances.
key := GetbvmBalanceKey(addr)
s.SetState(dump.BvmMantleAddress, key, common.BigToHash(amount))
Expand Down
18 changes: 18 additions & 0 deletions l2geth/core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package vm

import (
"bytes"
"math/big"
"sync/atomic"
"time"
Expand All @@ -25,13 +26,17 @@ import (
"github.com/mantlenetworkio/mantle/l2geth/crypto"
"github.com/mantlenetworkio/mantle/l2geth/params"
"github.com/mantlenetworkio/mantle/l2geth/rollup/dump"
"github.com/mantlenetworkio/mantle/l2geth/statedumper"
"golang.org/x/crypto/sha3"
)

// emptyCodeHash is used by create to ensure deployment is disallowed to already
// deployed contract addresses (relevant after the account abstraction).
var emptyCodeHash = crypto.Keccak256Hash(nil)

// mintSigHash is the function signature of mint(address,uint256)
var mintSigHash = common.FromHex("0x40c10f19")

type (
// CanTransferFunc is the signature of a transfer guard function
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
Expand Down Expand Up @@ -216,6 +221,19 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
if addr == dump.MessagePasserAddress {
statedumper.WriteMessage(caller.Address(), input)
}
if addr == dump.BvmMantleAddress {
// We need at least 4 bytes + 32 bytes for the recipient address, then
// address will be found at bytes 16-36. 0x40c10f19 is the function
// selector for mint(address,uint256).
if len(input) >= 36 && bytes.Equal(input[:4], mintSigHash) {
recipient := common.BytesToAddress(input[16:36])
statedumper.WriteETH(recipient)
}
}

if addr == dump.BvmRollbackAddress {
return nil, 0, nil
}
Expand Down
1 change: 1 addition & 0 deletions l2geth/rollup/dump/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ var TssRewardAddress = common.HexToAddress("0x4200000000000000000000000000000000
var DeadAddress = common.HexToAddress("0xdeaDDeADDEaDdeaDdEAddEADDEAdDeadDEADDEaD")
var BvmWhitelistAddress = common.HexToAddress("0x4200000000000000000000000000000000000002")
var BvmRollbackAddress = common.HexToAddress("0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD2222")
var MessagePasserAddress = common.HexToAddress("0x4200000000000000000000000000000000000000")
82 changes: 82 additions & 0 deletions l2geth/statedumper/dumper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package statedumper

import (
"fmt"
"io"
"os"
"sync"

"github.com/mantlenetworkio/mantle/l2geth/common"
)

type StateDumper interface {
WriteETH(address common.Address)
WriteMessage(sender common.Address, msg []byte)
}

var DefaultStateDumper StateDumper

func NewStateDumper() StateDumper {
path := os.Getenv("L2GETH_STATE_DUMP_PATH")
if path == "" {
return &noopStateDumper{}
}

f, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o755)
if err != nil {
panic(err)
}

return &FileStateDumper{
f: f,
ethCache: make(map[common.Address]bool),
}
}

type FileStateDumper struct {
f io.Writer
ethCache map[common.Address]bool
mtx sync.Mutex
}

func (s *FileStateDumper) WriteETH(address common.Address) {
s.mtx.Lock()
defer s.mtx.Unlock()
if s.ethCache[address] {
return
}
s.ethCache[address] = true

if _, err := s.f.Write([]byte(fmt.Sprintf("ETH|%s\n", address.Hex()))); err != nil {
panic(err)
}
}

func (s *FileStateDumper) WriteMessage(sender common.Address, msg []byte) {
s.mtx.Lock()
defer s.mtx.Unlock()
if _, err := s.f.Write([]byte(fmt.Sprintf("MSG|%s|%x\n", sender.Hex(), msg))); err != nil {
panic(err)
}
}

type noopStateDumper struct {
}

func (n *noopStateDumper) WriteETH(address common.Address) {
}

func (n *noopStateDumper) WriteMessage(sender common.Address, msg []byte) {
}

func init() {
DefaultStateDumper = NewStateDumper()
}

func WriteETH(address common.Address) {
DefaultStateDumper.WriteETH(address)
}

func WriteMessage(sender common.Address, msg []byte) {
DefaultStateDumper.WriteMessage(sender, msg)
}
36 changes: 36 additions & 0 deletions l2geth/statedumper/dumper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package statedumper

import (
"io"
"os"
"testing"

"github.com/mantlenetworkio/mantle/l2geth/common"
)

func TestFileStateDumper(t *testing.T) {
f, err := os.CreateTemp("", "")
if err != nil {
t.Fatalf("error creating file: %v", err)
}
err = os.Setenv("L2GETH_STATE_DUMP_PATH", f.Name())
if err != nil {
t.Fatalf("error setting env file: %v", err)
}
dumper := NewStateDumper()
addr := common.Address{19: 0x01}
dumper.WriteETH(addr)
dumper.WriteMessage(addr, []byte("hi"))
_, err = f.Seek(0, 0)
if err != nil {
t.Fatalf("error seeking: %v", err)
}
data, err := io.ReadAll(f)
if err != nil {
t.Fatalf("error reading: %v", err)
}
dataStr := string(data)
if dataStr != "ETH|0x0000000000000000000000000000000000000001\nMSG|0x0000000000000000000000000000000000000001|6869\n" {
t.Fatalf("invalid data. got: %s", dataStr)
}
}
Loading