Skip to content

Commit

Permalink
Unwinds and Tip Sync (#21)
Browse files Browse the repository at this point in the history
* feat(zkevm): add backoff to zkevm sequencer requests

* feat(zkevm): batch sequencer requests

* feat(zkevm): batch seq requests fix

* feat(zkevm): batch seq requests fix

* feat(zkevm): batch seq requests fix

* feat(zkevm): batch seq requests fix

* feat(zkevm): batch seq requests fix

* feat(zkevm): mdbx db for smt - incremental working

* feat(zkevm): wip

* wip

* wip

* wip

* wip

* wip

* wip - failing to unwind some blocks

* wip

* unwinds

* unwinds

* unwinds

* unwinds

* tracer

* update zkevm roots

* coinbase fix

* forkid fix

* foxed prints and error handling, removed smt parallel save

* fixed incremental smt bug and optimized smtCreate for memory

* restored too big jump

* minor code quality fixes

* addded error handling

* returned smt regenerate limit

* minor fixes

---------

Co-authored-by: Valentin Staykov <v.staykov@razorlabs.com>
  • Loading branch information
revitteth and V-Staykov committed Dec 14, 2023
1 parent b937272 commit 20db939
Show file tree
Hide file tree
Showing 33 changed files with 1,829 additions and 773 deletions.
1 change: 0 additions & 1 deletion cmd/erigon-el/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) (
if err != nil {
return nil, err
}

var currentBlock *types.Block

// Check if we have an already initialized chain and fall back to
Expand Down
1 change: 1 addition & 0 deletions cmd/erigon-el/stages/stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ func NewStagedSync(ctx context.Context,
cfg.HistoryV3,
agg,
),
stagedsync.StageRpcRootsCfg(db, controlServer.ChainConfig),
stagedsync.StageHeadersCfg(
db,
controlServer.Hd,
Expand Down
210 changes: 157 additions & 53 deletions cmd/hack/rpc-trace-compare/main.go
Original file line number Diff line number Diff line change
@@ -1,82 +1,110 @@
package main

import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
)

type OpContext struct {
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Depth int `json:"depth"`
Stack []string `json:"stack"`
Refund uint64 `json:"refund"`
}
"gopkg.in/yaml.v2"
)

func (oc *OpContext) cmp(b OpContext) bool {
if oc.Pc != b.Pc ||
oc.Op != b.Op ||
oc.Gas != b.Gas ||
oc.GasCost != b.GasCost ||
oc.Depth != b.Depth ||
oc.Refund != b.Refund ||
len(oc.Stack) != len(b.Stack) {
return false
func main() {
rpcConfig, err := getConf()
if err != nil {
panic(fmt.Sprintf("error RPGCOnfig: %s", err))
}
files, err := os.ReadDir("./traces")
if err != nil {
panic(fmt.Sprintf("error: %s", err))
}

for i, value := range oc.Stack {
value2 := b.Stack[i]
for _, file := range files {
traceFile := file.Name()

if value != value2 {
return false
jsonFile, err := os.Open("./traces/" + traceFile)
if err != nil {
fmt.Println(traceFile)
fmt.Println(err)
}
defer jsonFile.Close()

var localTrace []OpContext
byteValue, _ := ioutil.ReadAll(jsonFile)
err = json.Unmarshal(byteValue, &localTrace)
if err != nil {
fmt.Println(traceFile)

fmt.Println("Error parsing JSON data:", err)
return
}

txHash := traceFile[:len(traceFile)-5]

rpcTrace, err := getRpcTrace(txHash, rpcConfig)
if err != nil {
fmt.Println("Error getting rpcTrace:", err)
return
}

if err := compareTraces(localTrace, rpcTrace); err != nil {
fmt.Println("traces don't match for TX: ", txHash)
fmt.Println(err)
return
}

if err = os.Remove("./traces/" + traceFile); err != nil {
fmt.Println(err)
}
}

return true
fmt.Println("Check finished.")
}

var localTraceFile = "localOpDump.json"
var rpcTraceFile = "rpcOpDump.json"

func main() {
jsonFile, err := os.Open(localTraceFile)
if err != nil {
fmt.Println(err)
func getRpcTrace(txHash string, cfg RpcConfig) ([]OpContext, error) {
fmt.Println(txHash)
payloadbytecode := RequestData{
Method: "debug_traceTransaction",
Params: []string{txHash},
ID: 1,
Jsonrpc: "2.0",
}
defer jsonFile.Close()

var localTrace []OpContext
byteValue, _ := ioutil.ReadAll(jsonFile)
err = json.Unmarshal(byteValue, &localTrace)
jsonPayload, err := json.Marshal(payloadbytecode)
if err != nil {
fmt.Println("Error parsing JSON data:", err)
return
return nil, err
}

jsonFile2, err := os.Open(rpcTraceFile)
req, err := http.NewRequest("POST", cfg.Url, bytes.NewBuffer(jsonPayload))
if err != nil {
fmt.Println(err)
return nil, err
}
defer jsonFile2.Close()

var rpcTrace []OpContext
byteValue2, _ := ioutil.ReadAll(jsonFile2)
err = json.Unmarshal(byteValue2, &rpcTrace)
req.SetBasicAuth(cfg.Username, cfg.Pass)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error parsing JSON data2:", err)
return
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("failed to get rpc: %v", resp.Body)
}
defer resp.Body.Close()

compareTraces(localTrace, rpcTrace)
body, _ := io.ReadAll(resp.Body)
var httpResp HTTPResponse
json.Unmarshal(body, &httpResp)

fmt.Println("Check finished.")
if httpResp.Error.Code != 0 {
return nil, fmt.Errorf("failed to get trace: %v", httpResp.Error)
}
return httpResp.Result.StructLogs, nil
}

func compareTraces(localTrace, rpcTrace []OpContext) {
func compareTraces(localTrace, rpcTrace []OpContext) error {

localTracelen := len(localTrace)
rpcTracelen := len(rpcTrace)
Expand All @@ -86,11 +114,87 @@ func compareTraces(localTrace, rpcTrace []OpContext) {

for i, loc := range localTrace {
roc := rpcTrace[i]
areEqual := loc.cmp(roc)
if err := loc.cmp(roc); err != nil {
if i == len(localTrace)-1 && loc.Op == "RETURN" && roc.Op == "RETURN" && roc.GasCost > 18046744073709548816 {
continue
}
return fmt.Errorf("%v\nLOCAL: %v\nRPC: %v", err, loc, roc)
}
}

if !areEqual {
fmt.Printf("opcodes at index {%d} are not equal.\nLocal:\t%v\nRPC:\t%v\n\n", i, loc, roc)
return
return nil
}

func getConf() (RpcConfig, error) {
yamlFile, err := ioutil.ReadFile("rpcConfig.yaml")
if err != nil {
return RpcConfig{}, err
}

c := RpcConfig{}
err = yaml.Unmarshal(yamlFile, &c)
if err != nil {
return RpcConfig{}, err
}

return c, nil
}

type RpcConfig struct {
Url string `yaml:"url"`
Username string `yaml:"username"`
Pass string `yaml:"pass"`
}

type HTTPResponse struct {
Result HttpResult `json:"result"`
Error HttpError `json:"error"`
}

type HttpError struct {
Code int `json:"code"`
Message string `json:"message"`
}

type HttpResult struct {
StructLogs []OpContext `json:"structLogs"`
}

type RequestData struct {
Method string `json:"method"`
Params []string `json:"params"`
ID int `json:"id"`
Jsonrpc string `json:"jsonrpc"`
}

type OpContext struct {
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Depth int `json:"depth"`
Stack []string `json:"stack"`
Refund uint64 `json:"refund"`
}

func (oc *OpContext) cmp(b OpContext) error {
if oc.Pc != b.Pc ||
oc.Op != b.Op ||
oc.Gas != b.Gas ||
//dump not quite correct here, missing some reasings I guess
// oc.GasCost != b.GasCost ||
oc.Depth != b.Depth ||
oc.Refund != b.Refund ||
len(oc.Stack) != len(b.Stack) {
return fmt.Errorf("general mismatch")
}

for i, value := range oc.Stack {
value2 := b.Stack[i]
if value != value2 {
return fmt.Errorf("mismatch at stack index: %d", i)
}
}

return nil
}
2 changes: 1 addition & 1 deletion cmd/integration/commands/stages.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ func stageRpcRoots(db kv.RwDB, ctx context.Context) error {
}
log.Info("Progress", "rpc_roots", progress)
return nil
}
})
}

func stageSnapshots(db kv.RwDB, ctx context.Context) error {
Expand Down
20 changes: 20 additions & 0 deletions core/state/historyv2read/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,23 @@ func GetAsOf(tx kv.Tx, indexC kv.Cursor, changesC kv.CursorDupSort, storage bool
}
return tx.GetOne(kv.PlainState, key)
}

func GetAsOfNilIfNotExists(tx kv.Tx, indexC kv.Cursor, changesC kv.CursorDupSort, storage bool, key []byte, timestamp uint64) ([]byte, error) {
v, ok, err := historyv2.FindByHistory(indexC, changesC, storage, key, timestamp)
if err != nil {
return nil, err
}
if ok {
//restore codehash
if !storage {
//restore codehash
v, err = RestoreCodeHash(tx, key, v, nil)
if err != nil {
return nil, err
}
}

return v, nil
}
return nil, nil
}
9 changes: 0 additions & 9 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,12 +845,6 @@ func (sdb *IntraBlockState) ScalableSetTxNum() {
sdb.SetState(saddr, &sl0, *txNum)
}

func (s *IntraBlockState) PrintSmtRootHash() {
// print s.smt.LastRoot as hex
rootU256 := uint256.NewInt(0).SetBytes(s.smt.LastRoot().Bytes())
fmt.Println("SMT root: ", rootU256.String())
}

func (sdb *IntraBlockState) ScalableSetSmtRootHash(dbTx kv.RwTx) error {
saddr := libcommon.HexToAddress("0x000000000000000000000000000000005ca1ab1e")
sl0 := libcommon.HexToHash("0x0")
Expand All @@ -865,9 +859,6 @@ func (sdb *IntraBlockState) ScalableSetSmtRootHash(dbTx kv.RwTx) error {
d2 := common.LeftPadBytes(uint256.NewInt(1).Bytes(), 32)
mapKey := keccak256.Hash(d1, d2)
mkh := libcommon.BytesToHash(mapKey)
rootU256 := uint256.NewInt(0).SetBytes(sdb.smt.LastRoot().Bytes())

fmt.Println("Pre SMT root: ", rootU256.String())

rpcHash, err := getDbRoot(dbTx, txNum.Uint64())
if err != nil {
Expand Down
36 changes: 36 additions & 0 deletions core/state/plain_readonly.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,42 @@ func (s *PlainState) ReadAccountData(address libcommon.Address) (*accounts.Accou
return &a, nil
}

func (s *PlainState) ReadAccountDataMaybeNil(address libcommon.Address) (*accounts.Account, error) {
enc, err := historyv2read.GetAsOfNilIfNotExists(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, address[:], s.blockNr)
if err != nil {
return nil, err
}
if len(enc) == 0 {
if s.trace {
fmt.Printf("ReadAccountData [%x] => []\n", address)
}
return nil, nil
}
var a accounts.Account
if err = a.DecodeForStorage(enc); err != nil {
return nil, err
}
//restore codehash
if records, ok := s.systemContractLookup[address]; ok {
p := sort.Search(len(records), func(i int) bool {
return records[i].BlockNumber > s.blockNr
})
a.CodeHash = records[p-1].CodeHash
} else if a.Incarnation > 0 && a.IsEmptyCodeHash() {
if codeHash, err1 := s.tx.GetOne(kv.PlainContractCode, dbutils.PlainGenerateStoragePrefix(address[:], a.Incarnation)); err1 == nil {
if len(codeHash) > 0 {
a.CodeHash = libcommon.BytesToHash(codeHash)
}
} else {
return nil, err1
}
}
if s.trace {
fmt.Printf("ReadAccountData [%x] => [nonce: %d, balance: %d, codeHash: %x]\n", address, a.Nonce, &a.Balance, a.CodeHash)
}
return &a, nil
}

func (s *PlainState) ReadAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash) ([]byte, error) {
compositeKey := dbutils.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes())
enc, err := historyv2read.GetAsOf(s.tx, s.storageHistoryC, s.storageChangesC, true /* storage */, compositeKey, s.blockNr)
Expand Down
4 changes: 3 additions & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
true, /*isTrustedSequencer*/
etherMan, //etherMan ethermanInterface
adapter.NewStateAdapter(), //state stateInterface
client.NewClient("https://rpc.polygon-zkevm.gateway.fm"), //zkEVMClient zkEVMClientInterface
client.NewClient("https://rpc.eu-north-1.gateway.fm/v4/polygon-zkevm/archival/mainnet?apiKey=DkrTDQVU0SkU0WvxyIYc4oxOCyyF9Mzd.9aqlbyImRuJiMlaQ"), //zkEVMClient zkEVMClientInterface
synchronizer.Config{SyncChunkSize: 1000, GenBlockNumber: 16896721},
ctx,
)
Expand All @@ -685,6 +685,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
backend.syncUnwindOrder = stagedsync.DefaultUnwindOrder
backend.syncPruneOrder = stagedsync.DefaultPruneOrder

backend.syncUnwindOrder = stagedsync.ZkUnwindOrder

return backend, nil
}

Expand Down
Loading

0 comments on commit 20db939

Please sign in to comment.