Skip to content

feat(state): new state package + state clean cache #2864

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

Open
wants to merge 129 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
1ebf04e
initial, integrate mempool, still got some bug
weiihann Mar 11, 2025
35aeeb0
add IndexedBatch
weiihann Mar 11, 2025
6343d74
half way there for blockchain
weiihann Mar 12, 2025
cbd13f6
...left with state... bless me...
weiihann Mar 12, 2025
4bd9d19
trie works
weiihann Mar 13, 2025
9797cf5
state but not the main state
weiihann Mar 13, 2025
8e02afb
state is gud
weiihann Mar 13, 2025
ca051e9
blockchain tests passed
weiihann Mar 13, 2025
a6988f0
done migration
weiihann Mar 13, 2025
a921c34
slow
weiihann Mar 14, 2025
207a333
it is time
weiihann Mar 14, 2025
226d43b
all pass!
weiihann Mar 14, 2025
bf0bc64
"fix" remote
weiihann Mar 14, 2025
1996390
yay full integration
weiihann Mar 14, 2025
0b1daa2
use callback pattern for get
weiihann Mar 14, 2025
f9c61d3
tidy up stuff
weiihann Mar 14, 2025
a5b4df0
comments
weiihann Mar 14, 2025
a23323a
rename l1.go
weiihann Mar 19, 2025
52e6350
apply comments
weiihann Mar 25, 2025
4efba60
gather all accessors in core
weiihann Mar 25, 2025
5d46731
add bytes benchmark
weiihann Dec 13, 2024
1b86324
add Rsh test
weiihann Dec 14, 2024
1b2f686
add Truncate
weiihann Dec 14, 2024
9f5f038
all tests passed
weiihann Dec 17, 2024
1708fed
improve comments
weiihann Dec 18, 2024
bba6be1
minor chore
weiihann Dec 18, 2024
301b9a7
improvements
weiihann Dec 19, 2024
b6a5544
Implement trie nodes
weiihann Dec 26, 2024
f566aa1
Update() works on TrieD
weiihann Dec 30, 2024
c82cb88
add docs
weiihann Dec 31, 2024
fd4a75f
Add hasher
weiihann Jan 2, 2025
4065025
add tracer
weiihann Jan 7, 2025
d0c0e6c
Add package `trienode`
weiihann Jan 9, 2025
c3fb1fb
Add collector
weiihann Jan 9, 2025
f41ded7
Add Trie.Commit
weiihann Jan 9, 2025
ae79fc8
add Clear() to OrderedSet
weiihann Jan 15, 2025
50d601e
implement triedb
weiihann Jan 15, 2025
68724ba
rename trie/utils to trie/trieutils
weiihann Jan 15, 2025
bcb3355
minor changes on trienode
weiihann Jan 15, 2025
66fd64c
add trie id
weiihann Jan 15, 2025
4b73aa7
...a bunch of changes
weiihann Jan 15, 2025
7225cb3
bitarray changes
weiihann Jan 17, 2025
2bb211c
bitarray changes
weiihann Jan 20, 2025
3fec789
at this point range proof tests pass 50%
weiihann Jan 20, 2025
3d24120
still failing
weiihann Jan 21, 2025
75380dd
pass base test but got nil dereference bug
weiihann Jan 21, 2025
d4ee772
fix invalid non existent proof
weiihann Jan 21, 2025
5270453
fix hasRightElement
weiihann Jan 21, 2025
cfe0eb6
create TrieDB interface
weiihann Jan 21, 2025
03d21b8
range proof test cases all pass
weiihann Jan 21, 2025
348fddd
hasRightElement fix edgeNode case
weiihann Jan 21, 2025
184fc45
remove test
weiihann Jan 22, 2025
1c2d104
fix node encoding and add tests
weiihann Jan 22, 2025
d91163b
everything pass!!!!!
weiihann Jan 22, 2025
48ccac4
linter
weiihann Jan 23, 2025
57da72a
add comments
weiihann Jan 23, 2025
eb6d513
fix rebase
weiihann Jan 23, 2025
15e6d6a
remove proof_test changes
weiihann Jan 23, 2025
fb54112
add bitarray_test.go
weiihann Jan 23, 2025
f622dba
linter
weiihann Jan 23, 2025
18a043f
add comments
weiihann Jan 23, 2025
f6d4725
Remove leading zero bytes from bit array
weiihann Feb 6, 2025
769c068
comments
weiihann Feb 12, 2025
dbb5b4d
Fix encoding bug
weiihann Feb 17, 2025
ae083b5
make fields and interface public
weiihann Feb 18, 2025
321409b
add node iterator, delete leaf nodes
weiihann Feb 18, 2025
c0bedba
feat(trie): use interface for trie identifiers
weiihann Feb 25, 2025
81d3e71
feat: length is encoded last in bitarray and prepend node type in key
weiihann Feb 26, 2025
d8a63db
fix: parallelization in node collection
weiihann Feb 26, 2025
5223bcd
docs
weiihann Feb 26, 2025
51f02f1
refactor: revert encoding without leading zeros
weiihann Feb 27, 2025
3a9591d
refactor: create pathdb package
weiihann Mar 3, 2025
8ff4fd2
refactor: use type alias path instead of bitarray
weiihann Mar 3, 2025
b24e849
refactor: prepare for hashdb separation
weiihann Mar 3, 2025
f111458
refactor: node hash returns value
weiihann Mar 10, 2025
05c3aea
integrate db refactor
weiihann Mar 20, 2025
433c60e
trie changes
weiihann Mar 25, 2025
23a182b
update gomod
weiihann Mar 25, 2025
25ca8ea
clean up
weiihann Apr 30, 2025
8e3ebed
remove useless code
weiihann Apr 30, 2025
a02f3af
fix lint
weiihann Apr 30, 2025
90530d7
move node related files to trienode
weiihann May 1, 2025
1957cbc
fix go.mod
weiihann May 1, 2025
df3169a
applied some comments
weiihann May 5, 2025
470585b
return value
weiihann May 5, 2025
2cf1f4d
remove tests
weiihann May 5, 2025
4e10ae7
pass felts via reference
weiihann May 6, 2025
3ae0527
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 12, 2025
c665ce5
address first batch of comments
MaksymMalicki May 13, 2025
d0742bb
address next batch of comments
MaksymMalicki May 13, 2025
955d148
address next batch of comments
MaksymMalicki May 13, 2025
2d657ca
address next batch of comments
MaksymMalicki May 13, 2025
d7b9227
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 13, 2025
9341788
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 14, 2025
f94ffa8
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 14, 2025
d0c869d
address next batch of comments
MaksymMalicki May 14, 2025
fc9f60b
Merge branch 'weiihann/node-type' of https://github.com/NethermindEth…
MaksymMalicki May 14, 2025
3284444
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 15, 2025
66ac9db
address next batch of comments
MaksymMalicki May 16, 2025
7d9390a
Merge branch 'weiihann/node-type' of https://github.com/NethermindEth…
MaksymMalicki May 16, 2025
ce91c6d
add comment
MaksymMalicki May 16, 2025
945cd7b
refactor HashNode and ValueNode types
MaksymMalicki May 16, 2025
b3724e0
Merge branch 'main' into weiihann/node-type
MaksymMalicki May 19, 2025
857aec9
add new state package
MaksymMalicki May 20, 2025
7e43cc0
Introduce new state package
MaksymMalicki May 20, 2025
d24505d
fix node reader bug
MaksymMalicki May 23, 2025
6ec10ae
introduce state cache
MaksymMalicki May 30, 2025
3a9e2df
cache refactor
MaksymMalicki Jun 2, 2025
caa6041
Improve cache testing
MaksymMalicki Jun 2, 2025
f4e7808
Merge branch 'main' into maksym/state-refactor
MaksymMalicki Jun 2, 2025
aef6ad3
handle edge case
MaksymMalicki Jun 2, 2025
7180fbb
Merge branch 'maksym/state-refactor' of https://github.com/Nethermind…
MaksymMalicki Jun 2, 2025
0c9a922
fixes
MaksymMalicki Jun 2, 2025
a1b1954
test fix
MaksymMalicki Jun 5, 2025
37dc3a1
Merge branch 'main' into maksym/state-refactor
MaksymMalicki Jun 5, 2025
38f601f
Merge branch 'maksym/state-refactor' of https://github.com/Nethermind…
MaksymMalicki Jun 5, 2025
f1d97a0
minor refactoring
MaksymMalicki Jun 5, 2025
c7faa18
minor fixes of the tests
MaksymMalicki Jun 6, 2025
cff5266
fix CI
MaksymMalicki Jun 8, 2025
83965e4
fix CLI
MaksymMalicki Jun 9, 2025
c736abc
Merge branch 'main' into maksym/state-refactor
MaksymMalicki Jun 9, 2025
b0658fd
small refactor
MaksymMalicki Jun 9, 2025
19cee98
Merge branch 'maksym/state-refactor' of https://github.com/Nethermind…
MaksymMalicki Jun 9, 2025
acf36fe
minor refactoring
MaksymMalicki Jun 9, 2025
d489372
address first batch of comments
MaksymMalicki Jun 10, 2025
8a08d4f
refactor the cache
MaksymMalicki Jun 10, 2025
a1eab91
Merge branch 'main' into maksym/state-refactor
MaksymMalicki Jun 10, 2025
ba805e5
Merge branch 'main' into maksym/state-refactor
MaksymMalicki Jun 11, 2025
67252b5
cli fix
MaksymMalicki Jun 11, 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
33 changes: 33 additions & 0 deletions core/class.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package core

import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"math/big"
"strconv"

"github.com/NethermindEth/juno/core/crypto"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/encoder"
"github.com/consensys/gnark-crypto/ecc/stark-curve/fp"
)

Expand All @@ -16,6 +19,8 @@
_ Class = (*Cairo1Class)(nil)
)

const minDeclaredClassSize = 8

// Single felt identifying the number "0.1.0" as a short string
var SierraVersion010 felt.Felt = felt.New(
fp.Element([4]uint64{
Expand Down Expand Up @@ -255,3 +260,31 @@

return nil
}

type DeclaredClass struct {
At uint64 // block number at which the class was declared
Class Class
}

func (d *DeclaredClass) MarshalBinary() ([]byte, error) {
classEnc, err := encoder.Marshal(d.Class)
if err != nil {
return nil, err
}

Check warning on line 273 in core/class.go

View check run for this annotation

Codecov / codecov/patch

core/class.go#L272-L273

Added lines #L272 - L273 were not covered by tests

size := 8 + len(classEnc)
buf := make([]byte, size)
binary.BigEndian.PutUint64(buf[:8], d.At)
copy(buf[8:], classEnc)

return buf, nil
}

func (d *DeclaredClass) UnmarshalBinary(data []byte) error {
if len(data) < minDeclaredClassSize {
return errors.New("data too short to unmarshal DeclaredClass")
}

Check warning on line 286 in core/class.go

View check run for this annotation

Codecov / codecov/patch

core/class.go#L285-L286

Added lines #L285 - L286 were not covered by tests

d.At = binary.BigEndian.Uint64(data[:8])
return encoder.Unmarshal(data[8:], &d.Class)
}
120 changes: 2 additions & 118 deletions core/contract_test.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package core_test
package core

import (
"testing"

"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/db/memory"
"github.com/NethermindEth/juno/utils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

var NoopOnValueChanged = func(location, oldValue *felt.Felt) error {
return nil
}

func TestContractAddress(t *testing.T) {
tests := []struct {
callerAddress *felt.Felt
Expand Down Expand Up @@ -43,118 +35,10 @@ func TestContractAddress(t *testing.T) {

for _, tt := range tests {
t.Run("Address", func(t *testing.T) {
address := core.ContractAddress(tt.callerAddress, tt.classHash, tt.salt, tt.constructorCallData)
address := ContractAddress(tt.callerAddress, tt.classHash, tt.salt, tt.constructorCallData)
if !address.Equal(tt.want) {
t.Errorf("wrong address: got %s, want %s", address.String(), tt.want.String())
}
})
}
}

func TestNewContract(t *testing.T) {
testDB := memory.New()
txn := testDB.NewIndexedBatch()
addr := new(felt.Felt).SetUint64(234)
classHash := new(felt.Felt).SetBytes([]byte("class hash"))

t.Run("cannot create Contract instance if un-deployed", func(t *testing.T) {
_, err := core.NewContractUpdater(addr, txn)
require.EqualError(t, err, core.ErrContractNotDeployed.Error())
})

_, err := core.DeployContract(addr, classHash, txn)
require.NoError(t, err)

t.Run("redeploy should fail", func(t *testing.T) {
_, err := core.DeployContract(addr, classHash, txn)
require.EqualError(t, err, core.ErrContractAlreadyDeployed.Error())
})
}

func TestNonceAndClassHash(t *testing.T) {
testDB := memory.New()
txn := testDB.NewIndexedBatch()
addr := new(felt.Felt).SetUint64(44)
classHash := new(felt.Felt).SetUint64(37)

contract, err := core.DeployContract(addr, classHash, txn)
require.NoError(t, err)

t.Run("initial nonce should be 0", func(t *testing.T) {
got, err := core.ContractNonce(addr, txn)
require.NoError(t, err)
assert.Equal(t, new(felt.Felt), got)
})
t.Run("UpdateNonce()", func(t *testing.T) {
require.NoError(t, contract.UpdateNonce(classHash))

got, err := core.ContractNonce(addr, txn)
require.NoError(t, err)
assert.Equal(t, classHash, got)
})

t.Run("ClassHash()", func(t *testing.T) {
got, err := core.ContractClassHash(addr, txn)
require.NoError(t, err)
assert.Equal(t, classHash, got)
})

t.Run("Replace()", func(t *testing.T) {
replaceWith := utils.HexToFelt(t, "0xDEADBEEF")
require.NoError(t, contract.Replace(replaceWith))
got, err := core.ContractClassHash(addr, txn)
require.NoError(t, err)
assert.Equal(t, replaceWith, got)
})
}

func TestUpdateStorage(t *testing.T) {
testDB := memory.New()
txn := testDB.NewIndexedBatch()
addr := new(felt.Felt).SetUint64(44)
classHash := new(felt.Felt).SetUint64(37)

contract, err := core.DeployContract(addr, classHash, txn)
require.NoError(t, err)

t.Run("apply storage diff", func(t *testing.T) {
oldRoot, err := core.ContractRoot(addr, txn)
require.NoError(t, err)

require.NoError(t, contract.UpdateStorage(map[felt.Felt]*felt.Felt{*addr: classHash}, NoopOnValueChanged))

gotValue, err := core.ContractStorage(addr, addr, txn)
require.NoError(t, err)
assert.Equal(t, classHash, gotValue)

newRoot, err := core.ContractRoot(addr, txn)
require.NoError(t, err)
assert.NotEqual(t, oldRoot, newRoot)
})

t.Run("delete key from storage with storage diff", func(t *testing.T) {
require.NoError(t, contract.UpdateStorage(map[felt.Felt]*felt.Felt{*addr: new(felt.Felt)}, NoopOnValueChanged))

val, err := core.ContractStorage(addr, addr, txn)
require.NoError(t, err)
require.Equal(t, &felt.Zero, val)

sRoot, err := core.ContractRoot(addr, txn)
require.NoError(t, err)
assert.Equal(t, new(felt.Felt), sRoot)
})
}

func TestPurge(t *testing.T) {
testDB := memory.New()
txn := testDB.NewIndexedBatch()
addr := new(felt.Felt).SetUint64(44)
classHash := new(felt.Felt).SetUint64(37)

contract, err := core.DeployContract(addr, classHash, txn)
require.NoError(t, err)

require.NoError(t, contract.Purge())
_, err = core.NewContractUpdater(addr, txn)
assert.ErrorIs(t, err, core.ErrContractNotDeployed)
}
5 changes: 0 additions & 5 deletions core/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,6 @@ func (s *State) replaceContract(stateTrie *trie.Trie, addr, classHash *felt.Felt
return oldClassHash, nil
}

type DeclaredClass struct {
At uint64
Class Class
}

func (s *State) putClass(classHash *felt.Felt, class Class, declaredAt uint64) error {
classKey := db.ClassKey(classHash)

Expand Down
133 changes: 133 additions & 0 deletions core/state/accessors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package state

import (
"errors"
"fmt"

"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/db"
)

func GetStateObject(r db.KeyValueReader, state *State, addr *felt.Felt) (*stateObject, error) {
contract, err := GetContract(r, addr)
if err != nil {
return nil, err
}

return newStateObject(state, addr, &contract), nil
}

// Wrapper around getContract which checks if a contract is deployed
func GetContract(r db.KeyValueReader, addr *felt.Felt) (stateContract, error) {
contract, err := getContract(r, addr)
if err != nil {
if errors.Is(err, db.ErrKeyNotFound) {
return stateContract{}, ErrContractNotDeployed
}
return stateContract{}, err

Check warning on line 28 in core/state/accessors.go

View check run for this annotation

Codecov / codecov/patch

core/state/accessors.go#L28

Added line #L28 was not covered by tests
}

return contract, nil
}

// Gets a contract instance from the database.
func getContract(r db.KeyValueReader, addr *felt.Felt) (stateContract, error) {
key := db.ContractKey(addr)
var contract stateContract
if err := r.Get(key, func(val []byte) error {
if err := contract.UnmarshalBinary(val); err != nil {
return fmt.Errorf("failed to unmarshal contract: %w", err)
}

Check warning on line 41 in core/state/accessors.go

View check run for this annotation

Codecov / codecov/patch

core/state/accessors.go#L40-L41

Added lines #L40 - L41 were not covered by tests
return nil
}); err != nil {
return stateContract{}, err
}
return contract, nil
}

func HasContract(r db.KeyValueReader, addr *felt.Felt) (bool, error) {
key := db.ContractKey(addr)
return r.Has(key)
}

func WriteContract(w db.KeyValueWriter, addr *felt.Felt, contract *stateContract) error {
key := db.ContractKey(addr)
data, err := contract.MarshalBinary()
if err != nil {
return err
}

Check warning on line 59 in core/state/accessors.go

View check run for this annotation

Codecov / codecov/patch

core/state/accessors.go#L58-L59

Added lines #L58 - L59 were not covered by tests

return w.Put(key, data)
}

func DeleteContract(w db.KeyValueWriter, addr *felt.Felt) error {
key := db.ContractKey(addr)
return w.Delete(key)
}

func WriteNonceHistory(w db.KeyValueWriter, addr *felt.Felt, blockNum uint64, nonce *felt.Felt) error {
key := db.ContractHistoryNonceKey(addr, blockNum)
return w.Put(key, nonce.Marshal())
}

func WriteClassHashHistory(w db.KeyValueWriter, addr *felt.Felt, blockNum uint64, classHash *felt.Felt) error {
key := db.ContractHistoryClassHashKey(addr, blockNum)
return w.Put(key, classHash.Marshal())
}

func WriteStorageHistory(w db.KeyValueWriter, addr, key *felt.Felt, blockNum uint64, value *felt.Felt) error {
dbKey := db.ContractHistoryStorageKey(addr, key, blockNum)
return w.Put(dbKey, value.Marshal())
}

func DeleteStorageHistory(w db.KeyValueWriter, addr, key *felt.Felt, blockNum uint64) error {
dbKey := db.ContractHistoryStorageKey(addr, key, blockNum)
return w.Delete(dbKey)
}

func DeleteNonceHistory(w db.KeyValueWriter, addr *felt.Felt, blockNum uint64) error {
dbKey := db.ContractHistoryNonceKey(addr, blockNum)
return w.Delete(dbKey)
}

func DeleteClassHashHistory(w db.KeyValueWriter, addr *felt.Felt, blockNum uint64) error {
dbKey := db.ContractHistoryClassHashKey(addr, blockNum)
return w.Delete(dbKey)
}

func WriteClass(w db.KeyValueWriter, classHash *felt.Felt, class core.Class, declaredAt uint64) error {
key := db.ClassKey(classHash)

dc := core.DeclaredClass{
At: declaredAt,
Class: class,
}
enc, err := dc.MarshalBinary()
if err != nil {
return err
}

Check warning on line 109 in core/state/accessors.go

View check run for this annotation

Codecov / codecov/patch

core/state/accessors.go#L108-L109

Added lines #L108 - L109 were not covered by tests

return w.Put(key, enc)
}

func DeleteClass(w db.KeyValueWriter, classHash *felt.Felt) error {
key := db.ClassKey(classHash)
return w.Delete(key)
}

func GetClass(r db.KeyValueReader, classHash *felt.Felt) (*core.DeclaredClass, error) {
key := db.ClassKey(classHash)

var class core.DeclaredClass
if err := r.Get(key, class.UnmarshalBinary); err != nil {
return nil, err
}

return &class, nil
}

func HasClass(r db.KeyValueReader, classHash *felt.Felt) (bool, error) {
key := db.ClassKey(classHash)
return r.Has(key)
}
Loading
Loading