Skip to content

Commit

Permalink
store the offsets aside from the code
Browse files Browse the repository at this point in the history
  • Loading branch information
gballet committed Jan 14, 2022
1 parent 99604b0 commit 62e743d
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 6 deletions.
12 changes: 12 additions & 0 deletions core/rawdb/accessors_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,25 @@ func ReadCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte {
return data
}

func ReadPushDataOffsets(db ethdb.KeyValueReader, hash common.Hash) []byte {
data, _ := db.Get(pdKey(hash))
return data
}

// WriteCode writes the provided contract code database.
func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) {
if err := db.Put(codeKey(hash), code); err != nil {
log.Crit("Failed to store contract code", "err", err)
}
}

// WritePushDataOffsets writes the provided contract code database.
func WritePushDataOffsets(db ethdb.KeyValueWriter, hash common.Hash, offsets []byte) {
if err := db.Put(pdKey(hash), offsets); err != nil {
log.Crit("Failed to store pushdata offsets for contract code", "err", err)
}
}

// DeleteCode deletes the specified contract code from the database.
func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) {
if err := db.Delete(codeKey(hash)); err != nil {
Expand Down
6 changes: 6 additions & 0 deletions core/rawdb/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,12 @@ func codeKey(hash common.Hash) []byte {
return append(CodePrefix, hash.Bytes()...)
}

// pdKey = CodePrefix + hash + "pd", so that it's right after the
// code in the database.
func pdKey(hash common.Hash) []byte {
return append(codeKey(hash), "pd"...)
}

// IsCodeKey reports whether the given byte slice is the key of contract code,
// if so return the raw code hash as well.
func IsCodeKey(key []byte) (bool, []byte) {
Expand Down
17 changes: 15 additions & 2 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ const (
codeCacheSize = 64 * 1024 * 1024
)

var (
errCodeNotFound = errors.New("no code found")
)

// Database wraps access to tries and contract code.
type Database interface {
// OpenTrie opens the main account trie.
Expand Down Expand Up @@ -181,7 +185,7 @@ func (db *cachingDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
return nil, errCodeNotFound
}

// ContractCodeWithPrefix retrieves a particular contract's code. If the
Expand Down Expand Up @@ -265,7 +269,16 @@ func (db *VerkleDB) ContractCode(addrHash, codeHash common.Hash) ([]byte, error)
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
return nil, errCodeNotFound
}

func (db *VerkleDB) ContractCodePushData(codeHash common.Hash) ([]byte, error) {
pdoffsets := rawdb.ReadPushDataOffsets(db.db.DiskDB(), codeHash)
if len(pdoffsets) == 0 {
return nil, errCodeNotFound
}

return pdoffsets, nil
}

// ContractCodeSize retrieves a particular contracts code's size.
Expand Down
8 changes: 6 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,9 @@ func (s *StateDB) updateStateObject(obj *stateObject) {
}

if obj.dirtyCode {
if chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
// Since the DB isn't updated with the code, don't update
// the offsets either.
if _, chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
for i := range chunks {
s.trie.TryUpdate(trieUtils.GetTreeKeyCodeChunk(addr[:], uint256.NewInt(uint64(i))), chunks[i][:])
}
Expand Down Expand Up @@ -996,10 +998,12 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
// Write any contract code associated with the state object
if obj.code != nil && obj.dirtyCode {
if s.trie.IsVerkle() {
if chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
if offsets, chunks, err := trie.ChunkifyCode(addr, obj.code); err == nil {
for i := range chunks {
s.trie.TryUpdate(trieUtils.GetTreeKeyCodeChunk(addr[:], uint256.NewInt(uint64(i))), chunks[i][:])
}

rawdb.WritePushDataOffsets(codeWriter, common.BytesToHash(obj.CodeHash()), offsets)
} else {
s.setError(err)
}
Expand Down
9 changes: 7 additions & 2 deletions trie/verkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,11 @@ const (
PUSH32 = 0x71
)

func ChunkifyCode(addr common.Address, code []byte) ([][32]byte, error) {
// ChunkifyCode returns the list of code offsets for the chunks, as well
// as the generated chunks. The chunks are to be inserted into the tree,
// and the code offsets are to be saved into the database.
func ChunkifyCode(addr common.Address, code []byte) ([]byte, [][32]byte, error) {
var offsets []byte
lastOffset := byte(0)
chunkCount := len(code) / 31
if len(code)%31 != 0 {
Expand All @@ -260,7 +264,8 @@ func ChunkifyCode(addr common.Address, code []byte) ([][32]byte, error) {
}
}
chunks[i][0] = lastOffset
offsets = append(offsets, lastOffset)
}

return chunks, nil
return offsets, chunks, nil
}

0 comments on commit 62e743d

Please sign in to comment.