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

refactor(interhashes): code quality #1519

Open
wants to merge 47 commits into
base: zkevm
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
98769df
feat: add witness cache stage
V-Staykov Nov 14, 2024
ea85cc5
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 14, 2024
4f4ac74
fix: merge problems
V-Staykov Nov 14, 2024
9b77d8e
fix: merge problems
V-Staykov Nov 14, 2024
fdcef77
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 15, 2024
a225571
fix: tests
V-Staykov Nov 15, 2024
5e1befa
fix: unwinds
V-Staykov Nov 15, 2024
e01398a
refactor: remove unused function
V-Staykov Nov 15, 2024
40c661c
fix: add witness cache table in erigon-lib
V-Staykov Nov 15, 2024
b70c4f9
feat: add merge witnesses and tests
V-Staykov Nov 15, 2024
ef0e5b9
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 15, 2024
596e0ef
feat: batch witness get from db
V-Staykov Nov 18, 2024
72bd73f
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 18, 2024
91c857b
fix: minor refactoring and flag fixes
V-Staykov Nov 21, 2024
fb1f864
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 21, 2024
f5b01af
fix: unwindzksmt argument
V-Staykov Nov 21, 2024
eb5641c
refactor: prints and add test
V-Staykov Nov 21, 2024
7d77dfa
fix: tests
V-Staykov Nov 25, 2024
866f8f7
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 25, 2024
806ae0a
fix: merge build
V-Staykov Nov 25, 2024
0218d53
fix: add tests and fix witness parsing bugs
V-Staykov Nov 26, 2024
51762d0
feat: implement witness utility function and improve error handling
V-Staykov Nov 26, 2024
e115293
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 26, 2024
91f1650
feat: add SMT node retrieval and utility functions
V-Staykov Nov 27, 2024
8e7c551
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 27, 2024
dd895d1
feat: restore L1 Info tree stage functionality with sync, unwind, and…
V-Staykov Nov 27, 2024
7cf3742
fix: correct db table for delete caches
V-Staykov Nov 28, 2024
adee42f
fix: do not unwind if stage witness flag not set
V-Staykov Nov 28, 2024
e92cd47
fix: quit channel in unwindsmt
V-Staykov Nov 28, 2024
e30a623
refactor: separate changes getter in a file
V-Staykov Nov 28, 2024
55cabf0
Merge branch 'zkevm' into 1458-rpc-generate-witness-locally-during-ex…
V-Staykov Nov 28, 2024
d08b3c3
refactor(stage_interhashes): separate functions into smaller ones and…
V-Staykov Nov 28, 2024
b998904
test: fix test
V-Staykov Dec 2, 2024
de13268
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 2, 2024
f217d19
refactor:(smt) code extraction
V-Staykov Dec 2, 2024
660bb5b
fix: use correct logger in itnerhashes
V-Staykov Dec 2, 2024
9fecc5b
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 3, 2024
68daf29
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 4, 2024
8a000a1
refactor: replace repeating code in increment ande remove unused
V-Staykov Dec 4, 2024
d0987e2
fiX: incremental use of changes getter
V-Staykov Dec 4, 2024
8b9f3f8
fix: increment block start
V-Staykov Dec 4, 2024
d8d3810
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 4, 2024
6716ff8
Merge branch 'vs-refactor-interhashes' of https://github.com/0xPolygo…
V-Staykov Dec 4, 2024
f94ab3b
fix: psr block set
V-Staykov Dec 4, 2024
183a4c8
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 18, 2024
8ca052b
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Dec 19, 2024
0cfb76a
Merge branch 'zkevm' into vs-refactor-interhashes
V-Staykov Jan 3, 2025
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
703 changes: 0 additions & 703 deletions erigon-lib/gointerfaces/sentry/sentry_client_mock.go

This file was deleted.

77 changes: 0 additions & 77 deletions erigon-lib/kv/remotedbserver/snapshots_mock.go

This file was deleted.

161 changes: 161 additions & 0 deletions zk/smt/account_processor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package smt

import (
"fmt"
"math/big"
"strings"

"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/types/accounts"
"github.com/ledgerwatch/erigon/smt/pkg/utils"
"github.com/status-im/keycard-go/hexutils"
)

//go:generate mockgen -typed=true -destination=./mocks/account_collector_db_mock.go -package=mocks . AccountCollectorDb

type AccountCollectorDb interface {
InsertKeySource(key utils.NodeKey, value []byte) error
InsertAccountValue(key utils.NodeKey, value utils.NodeValue8) error
}

type accountCollector struct {
db AccountCollectorDb
psr *state.PlainStateReader
keys []utils.NodeKey
}

func NewAccountCollector(db AccountCollectorDb, psr *state.PlainStateReader) *accountCollector {
return &accountCollector{
db: db,
psr: psr,
keys: []utils.NodeKey{},
}
}

// parses the data and saves it to the DB
// collects the saved keys in the array "keys"
func (ac *accountCollector) processAccount(a *accounts.Account, as map[string]string, inc uint64, addr common.Address) error {
// get the account balance and nonce
if err := ac.insertAccountStateToKV(addr.String(), a.Balance.ToBig(), new(big.Int).SetUint64(a.Nonce)); err != nil {
return fmt.Errorf("insertAccountStateToKV: %w", err)
}

// store the contract bytecode
cc, err := ac.psr.ReadAccountCode(addr, inc, a.CodeHash)
if err != nil {
return fmt.Errorf("ReadAccountCode: %w", err)
}

if len(cc) > 0 {
ach := hexutils.BytesToHex(cc)
hexcc := "0x" + ach
if err = ac.insertContractBytecodeToKV(addr.String(), hexcc); err != nil {
return fmt.Errorf("insertContractBytecodeToKV: %w", err)
}
}

if len(as) > 0 {
// store the account storage
if err = ac.insertContractStorageToKV(addr.String(), as); err != nil {
return fmt.Errorf("insertContractStorageToKV: %w", err)
}
}

return nil
}

func (ac *accountCollector) insertContractBytecodeToKV(ethAddr string, bytecode string) error {
keyContractCode := utils.KeyContractCode(ethAddr)
keyContractLength := utils.KeyContractLength(ethAddr)
bi := utils.HashContractBytecodeBigInt(bytecode)

parsedBytecode := strings.TrimPrefix(bytecode, "0x")
if len(parsedBytecode)%2 != 0 {
parsedBytecode = "0" + parsedBytecode
}

bytecodeLength := len(parsedBytecode) / 2

if err := ac.parseAndInsertKV(utils.SC_CODE, ethAddr, keyContractCode, bi, common.Hash{}); err != nil {
return fmt.Errorf("parseAndInsertKV: %w", err)
}

if err := ac.parseAndInsertKV(utils.SC_LENGTH, ethAddr, keyContractLength, big.NewInt(int64(bytecodeLength)), common.Hash{}); err != nil {
return fmt.Errorf("parseAndInsertKV: %w", err)
}

return nil
}

func (ac *accountCollector) insertContractStorageToKV(ethAddr string, storage map[string]string) (err error) {
add := utils.ScalarToArrayBig(utils.ConvertHexToBigInt(ethAddr))

var keyStoragePosition utils.NodeKey
for k, v := range storage {
if v == "" {
continue
}

keyStoragePosition = utils.KeyContractStorage(add, k)

base := 10
if strings.HasPrefix(v, "0x") {
v = v[2:]
base = 16
}

val, _ := new(big.Int).SetString(v, base)
sp, _ := utils.StrValToBigInt(k)
if err := ac.parseAndInsertKV(utils.SC_STORAGE, ethAddr, keyStoragePosition, val, common.BigToHash(sp)); err != nil {
return fmt.Errorf("parseAndInsertKV: %w", err)
}
}

return nil
}

func (ac *accountCollector) insertAccountStateToKV(ethAddr string, balance, nonce *big.Int) error {
keyBalance := utils.KeyEthAddrBalance(ethAddr)
keyNonce := utils.KeyEthAddrNonce(ethAddr)

if err := ac.parseAndInsertKV(utils.KEY_BALANCE, ethAddr, keyBalance, balance, common.Hash{}); err != nil {
return fmt.Errorf("parseAndInsertKV: %w", err)
}

if err := ac.parseAndInsertKV(utils.KEY_NONCE, ethAddr, keyNonce, nonce, common.Hash{}); err != nil {
return fmt.Errorf("parseAndInsertKV: %w", err)
}
return nil
}

func (ac *accountCollector) parseAndInsertKV(encodeKey int, ethAddr string, key utils.NodeKey, val *big.Int, storagePos common.Hash) error {
x := utils.ScalarToArrayBig(val)
valueNode, err := utils.NodeValue8FromBigIntArray(x)
if err != nil {
return fmt.Errorf("NodeValue8FromBigIntArray: %w", err)
}

if !valueNode.IsZero() {
if err := ac.insertKVtoDb(encodeKey, ethAddr, key, valueNode, storagePos); err != nil {
return fmt.Errorf("processAccount: %w", err)
}
}

return nil
}

func (ac *accountCollector) insertKVtoDb(encodeKey int, ethAddr string, key utils.NodeKey, val *utils.NodeValue8, storagePos common.Hash) error {
if err := ac.db.InsertAccountValue(key, *val); err != nil {
return fmt.Errorf("InsertAccountValue: %w", err)
}

ks := utils.EncodeKeySource(encodeKey, utils.ConvertHexToAddress(ethAddr), storagePos)
if err := ac.db.InsertKeySource(key, ks); err != nil {
return fmt.Errorf("InsertKeySource: %w", err)
}

ac.keys = append(ac.keys, key)

return nil
}
141 changes: 141 additions & 0 deletions zk/smt/account_processor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package smt

import (
"context"
"errors"
"testing"

"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/smt/pkg/utils"
"github.com/ledgerwatch/erigon/zk/smt/mocks"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
)

type insertKeySourceParams struct {
key utils.NodeKey
value []byte
result error
}

type insertAccountValueParams struct {
key utils.NodeKey
value utils.NodeValue8
result error
}
type testStruct struct {
name string
encodeKey int
ethAddress string
key utils.NodeKey
val utils.NodeValue8
insertKeySourceParams *insertKeySourceParams
insertAccountValueParams *insertAccountValueParams
resultError string
}

func Test_insertKVtoDb(t *testing.T) {
tests := []testStruct{
{
name: "inserted key in keys array",
encodeKey: 1,
ethAddress: "0x1234567890abcdef",
key: utils.NodeKey{1, 2, 3, 4},
val: utils.NodeValue8{},
insertKeySourceParams: nil,
insertAccountValueParams: nil,
resultError: "",
},
{
name: "InsertAccountValue inserts correct values",
encodeKey: 1,
ethAddress: "0x1234567890abcdef",
key: utils.NodeKey{1, 2, 3, 4},
val: utils.NodeValue8{},
insertAccountValueParams: &insertAccountValueParams{
key: utils.NodeKey{1, 2, 3, 4},
value: utils.NodeValue8{},
result: nil,
},
insertKeySourceParams: nil,
resultError: "",
},
{
name: "InsertAccountValue returns err",
encodeKey: 1,
ethAddress: "0x1234567890abcdef",
key: utils.NodeKey{1, 2, 3, 4},
val: utils.NodeValue8{},
insertAccountValueParams: &insertAccountValueParams{
key: utils.NodeKey{1, 2, 3, 4},
value: utils.NodeValue8{},
result: errors.New("error"),
},
insertKeySourceParams: nil,
resultError: "InsertAccountValue",
},
{
name: "InsertKeySource inserts correct values",
encodeKey: 1,
ethAddress: "0x1234567890abcdef",
key: utils.NodeKey{1, 2, 3, 4},
val: utils.NodeValue8{},
insertAccountValueParams: nil,
insertKeySourceParams: &insertKeySourceParams{
key: utils.NodeKey{1, 2, 3, 4},
value: []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 144, 171, 205, 239},
result: nil,
},
resultError: "",
},
{
name: "InsertKeySource returns err",
encodeKey: 1,
ethAddress: "0x1234567890abcdef",
key: utils.NodeKey{1, 2, 3, 4},
val: utils.NodeValue8{},
insertAccountValueParams: nil,
insertKeySourceParams: &insertKeySourceParams{
key: utils.NodeKey{1, 2, 3, 4},
value: []byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 52, 86, 120, 144, 171, 205, 239},
result: errors.New("error"),
},
resultError: "InsertKeySource",
},
}
db := memdb.NewTestDB(t)
defer db.Close()
tx, err := db.BeginRw(context.Background())
assert.NoError(t, err)
defer tx.Rollback()
ctrl := gomock.NewController(t)
psr := state.NewPlainStateReader(tx)
defer ctrl.Finish()

for _, tc := range tests {
eriDb := mocks.NewMockAccountCollectorDb(ctrl)
if tc.insertKeySourceParams != nil {
eriDb.EXPECT().InsertKeySource(tc.insertKeySourceParams.key, tc.insertKeySourceParams.value).Return(tc.insertKeySourceParams.result).Times(1)
} else {
eriDb.EXPECT().InsertKeySource(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
}
if tc.insertAccountValueParams != nil {
eriDb.EXPECT().InsertAccountValue(tc.insertAccountValueParams.key, tc.insertAccountValueParams.value).Return(tc.insertAccountValueParams.result).Times(1)
} else {
eriDb.EXPECT().InsertAccountValue(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
}

accCollector := NewAccountCollector(eriDb, psr)
err = accCollector.insertKVtoDb(tc.encodeKey, tc.ethAddress, tc.key, &tc.val, common.Hash{})
if tc.resultError != "" {
assert.ErrorContains(t, err, tc.resultError)
assert.Equal(t, 0, len(accCollector.keys))
} else {
assert.NoError(t, err)
assert.Equal(t, 1, len(accCollector.keys))
assert.Equal(t, tc.key, accCollector.keys[0])
}
}
}
Loading
Loading