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

Naming refactor #48

Merged
merged 3 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ Database contains a minimal subset of the World-State Trie to faithfully replay

There are 5 data structures stored in a substate DB:
1. `SubstateAccount`: account information (nonce, balance, code, storage)
2. `SubstateAlloc`: mapping of account address and `SubstateAccount`
2. `WorldState`: mapping of account address and `SubstateAccount`
3. `SubstateEnv`: information from block headers (block gasLimit, number, timestamp, hashes)
4. `SubstateMessage`: message for transaction execution
5. `SubstateResult`: result of transaction execution

5 values are required to replay transactions and validate results:
1. `InputAlloc`: alloc that is read during transaction execution
1. `PreState`: alloc that is read during transaction execution
evgensheff marked this conversation as resolved.
Show resolved Hide resolved
2. `Env`: block information required for transaction execution
3. `Message`: array with exactly 1 transaction
4. `OutputAlloc`: alloc that is generated by transaction execution
4. `PostState`: alloc that is generated by transaction execution
evgensheff marked this conversation as resolved.
Show resolved Hide resolved
5. `Result`: execution result and receipt array with exactly 1 receipt

The first 2 bytes of a key in a substate DB represent different data types as follows:
Expand Down
26 changes: 13 additions & 13 deletions db/code_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/syndtr/goleveldb/leveldb/opt"
)

const Stage1CodePrefix = "1c" // Stage1CodePrefix + codeHash (256-bit) -> code
const CodeDBPrefix = "1c" // CodeDBPrefix + codeHash (256-bit) -> code

// CodeDB is a wrappe around BaseDB. It extends it with Has/Get/PutCode functions.
type CodeDB interface {
Expand Down Expand Up @@ -60,7 +60,7 @@ func (db *codeDB) HasCode(codeHash common.Hash) (bool, error) {
return false, ErrorEmptyHash
}

key := Stage1CodeKey(codeHash)
key := CodeDBKey(codeHash)
has, err := db.Has(key)
if err != nil {
return false, err
Expand All @@ -74,7 +74,7 @@ func (db *codeDB) GetCode(codeHash common.Hash) ([]byte, error) {
return nil, ErrorEmptyHash
}

key := Stage1CodeKey(codeHash)
key := CodeDBKey(codeHash)
code, err := db.Get(key)
if err != nil {
return nil, fmt.Errorf("cannot get code %s: %v", codeHash.Hex(), err)
Expand All @@ -85,7 +85,7 @@ func (db *codeDB) GetCode(codeHash common.Hash) ([]byte, error) {
// PutCode creates hash for given code and inserts it into the baseDB.
func (db *codeDB) PutCode(code []byte) error {
codeHash := crypto.Keccak256Hash(code)
key := Stage1CodeKey(codeHash)
key := CodeDBKey(codeHash)
err := db.Put(key, code)
if err != nil {
return fmt.Errorf("cannot put code %v; %v", codeHash.Hex(), err)
Expand All @@ -100,30 +100,30 @@ func (db *codeDB) DeleteCode(codeHash common.Hash) error {
return ErrorEmptyHash
}

key := Stage1CodeKey(codeHash)
key := CodeDBKey(codeHash)
err := db.Delete(key)
if err != nil {
return fmt.Errorf("cannot get code %s: %v", codeHash.Hex(), err)
}
return nil
}

// Stage1CodeKey returns Stage1CodePrefix with appended
// CodeDBKey returns CodeDBPrefix with appended
// codeHash creating key used in baseDB for Codes.
func Stage1CodeKey(codeHash common.Hash) []byte {
prefix := []byte(Stage1CodePrefix)
func CodeDBKey(codeHash common.Hash) []byte {
prefix := []byte(CodeDBPrefix)
return append(prefix, codeHash.Bytes()...)
}

// DecodeStage1CodeKey decodes key created by Stage1CodeKey back to hash.
func DecodeStage1CodeKey(key []byte) (codeHash common.Hash, err error) {
prefix := Stage1CodePrefix
// DecodeCodeDBKey decodes key created by CodeDBKey back to hash.
func DecodeCodeDBKey(key []byte) (codeHash common.Hash, err error) {
prefix := CodeDBPrefix
if len(key) != len(prefix)+32 {
err = fmt.Errorf("invalid length of stage1 code key: %v", len(key))
err = fmt.Errorf("invalid length of code db key: %v", len(key))
return
}
if p := string(key[:2]); p != prefix {
err = fmt.Errorf("invalid prefix of stage1 code key: %#x", p)
err = fmt.Errorf("invalid prefix of code db key: %#x", p)
return
}
codeHash = common.BytesToHash(key[len(prefix):])
Expand Down
40 changes: 20 additions & 20 deletions db/substate_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/syndtr/goleveldb/leveldb/opt"
)

const Stage1SubstatePrefix = "1s" // Stage1SubstatePrefix + block (64-bit) + tx (64-bit) -> substateRLP
const SubstateDBPrefix = "1s" // SubstateDBPrefix + block (64-bit) + tx (64-bit) -> substateRLP

// SubstateDB is a wrapper around CodeDB. It extends it with Has/Get/Put/DeleteSubstate functions.
type SubstateDB interface {
Expand Down Expand Up @@ -64,12 +64,12 @@ type substateDB struct {
}

func (db *substateDB) HasSubstate(block uint64, tx int) (bool, error) {
return db.Has(Stage1SubstateKey(block, tx))
return db.Has(SubstateDBKey(block, tx))
}

// GetSubstate returns substate for given block and tx number if exists within DB.
func (db *substateDB) GetSubstate(block uint64, tx int) (*substate.Substate, error) {
val, err := db.Get(Stage1SubstateKey(block, tx))
val, err := db.Get(SubstateDBKey(block, tx))
if err != nil {
return nil, fmt.Errorf("cannot get substate block: %v, tx: %v from db; %v", block, tx, err)
}
Expand All @@ -88,17 +88,17 @@ func (db *substateDB) GetSubstate(block uint64, tx int) (*substate.Substate, err
}

func (db *substateDB) PutSubstate(ss *substate.Substate) error {
for i, account := range ss.InputAlloc {
for i, account := range ss.PreState {
err := db.PutCode(account.Code)
if err != nil {
return fmt.Errorf("cannot put input-alloc code from substate-account %v block %v, %v tx into db; %v", i, ss.Block, ss.Transaction, err)
return fmt.Errorf("cannot put preState code from substate-account %v block %v, %v tx into db; %v", i, ss.Block, ss.Transaction, err)
}
}

for i, account := range ss.OutputAlloc {
for i, account := range ss.PostState {
err := db.PutCode(account.Code)
if err != nil {
return fmt.Errorf("cannot put ouput-alloc code from substate-account %v block %v, %v tx into db; %v", i, ss.Block, ss.Transaction, err)
return fmt.Errorf("cannot put postState code from substate-account %v block %v, %v tx into db; %v", i, ss.Block, ss.Transaction, err)
}
}

Expand All @@ -109,7 +109,7 @@ func (db *substateDB) PutSubstate(ss *substate.Substate) error {
}
}

key := Stage1SubstateKey(ss.Block, ss.Transaction)
key := SubstateDBKey(ss.Block, ss.Transaction)

substateRLP := rlp.NewRLP(ss)
value, err := gethrlp.EncodeToBytes(substateRLP)
Expand All @@ -121,7 +121,7 @@ func (db *substateDB) PutSubstate(ss *substate.Substate) error {
}

func (db *substateDB) DeleteSubstate(block uint64, tx int) error {
return db.Delete(Stage1SubstateKey(block, tx))
return db.Delete(SubstateDBKey(block, tx))
}

// NewSubstateIterator returns iterator which iterates over Substates.
Expand All @@ -142,10 +142,10 @@ func BlockToBytes(block uint64) []byte {
return blockBytes
}

// Stage1SubstateKey returns Stage1SubstatePrefix with appended
// SubstateDBKey returns SubstateDBPrefix with appended
// block number creating key used in baseDB for Substates.
func Stage1SubstateKey(block uint64, tx int) []byte {
prefix := []byte(Stage1SubstatePrefix)
func SubstateDBKey(block uint64, tx int) []byte {
prefix := []byte(SubstateDBPrefix)

blockTx := make([]byte, 16)
binary.BigEndian.PutUint64(blockTx[0:8], block)
Expand All @@ -154,21 +154,21 @@ func Stage1SubstateKey(block uint64, tx int) []byte {
return append(prefix, blockTx...)
}

// Stage1SubstateBlockPrefix returns Stage1SubstatePrefix with appended
// SubstateDBBlockPrefix returns SubstateDBPrefix with appended
// block number creating prefix used in baseDB for Substates.
func Stage1SubstateBlockPrefix(block uint64) []byte {
return append([]byte(Stage1SubstatePrefix), BlockToBytes(block)...)
func SubstateDBBlockPrefix(block uint64) []byte {
return append([]byte(SubstateDBPrefix), BlockToBytes(block)...)
}

// DecodeStage1SubstateKey decodes key created by Stage1SubstateBlockPrefix back to block and tx number.
func DecodeStage1SubstateKey(key []byte) (block uint64, tx int, err error) {
prefix := Stage1SubstatePrefix
// DecodeSubstateDBKey decodes key created by SubstateDBBlockPrefix back to block and tx number.
func DecodeSubstateDBKey(key []byte) (block uint64, tx int, err error) {
prefix := SubstateDBPrefix
if len(key) != len(prefix)+8+8 {
err = fmt.Errorf("invalid length of stage1 substate key: %v", len(key))
err = fmt.Errorf("invalid length of substate db key: %v", len(key))
return
}
if p := string(key[:len(prefix)]); p != prefix {
err = fmt.Errorf("invalid prefix of stage1 substate key: %#x", p)
err = fmt.Errorf("invalid prefix of substate db key: %#x", p)
return
}
blockTx := key[len(prefix):]
Expand Down
8 changes: 4 additions & 4 deletions db/substate_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
)

var testSubstate = &substate.Substate{
InputAlloc: substate.NewAlloc(),
OutputAlloc: substate.NewAlloc(),
PreState: substate.NewWorldState(),
PostState: substate.NewWorldState(),
Env: &substate.Env{
Coinbase: common.Address{1},
Difficulty: new(big.Int).SetUint64(1),
Expand Down Expand Up @@ -121,8 +121,8 @@ func createDbAndPutSubstate(dbPath string) (*substateDB, error) {
h2 := common.Hash{}
h2.SetBytes(nil)

testSubstate.InputAlloc[common.Address{1}] = substate.NewAccount(1, new(big.Int).SetUint64(1), h1.Bytes())
testSubstate.OutputAlloc[common.Address{2}] = substate.NewAccount(2, new(big.Int).SetUint64(2), h2.Bytes())
testSubstate.PreState[common.Address{1}] = substate.NewAccount(1, new(big.Int).SetUint64(1), h1.Bytes())
testSubstate.PostState[common.Address{2}] = substate.NewAccount(2, new(big.Int).SetUint64(2), h2.Bytes())
testSubstate.Env.BlockHashes[1] = common.BytesToHash([]byte{1})

err = db.PutSubstate(testSubstate)
Expand Down
4 changes: 2 additions & 2 deletions db/substate_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func newSubstateIterator(db *substateDB, start []byte) *substateIterator {
r := util.BytesPrefix([]byte(Stage1SubstatePrefix))
r := util.BytesPrefix([]byte(SubstateDBPrefix))
r.Start = append(r.Start, start...)

return &substateIterator{
Expand All @@ -27,7 +27,7 @@ func (i *substateIterator) decode(data rawEntry) (*substate.Substate, error) {
key := data.key
value := data.value

block, tx, err := DecodeStage1SubstateKey(data.key)
block, tx, err := DecodeSubstateDBKey(data.key)
if err != nil {
return nil, fmt.Errorf("invalid substate key: %v; %v", key, err)
}
Expand Down
42 changes: 21 additions & 21 deletions db/update_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (

"github.com/Fantom-foundation/Substate/geth/common"
gethrlp "github.com/Fantom-foundation/Substate/geth/rlp"
"github.com/Fantom-foundation/Substate/update_set"
"github.com/Fantom-foundation/Substate/updateset"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/util"
)

const (
SubstateAllocPrefix = "2s" // SubstateAllocPrefix + block (64-bit) + tx (64-bit) -> substateRLP
UpdateDBPrefix = "2s" // UpdateDBPrefix + block (64-bit) + tx (64-bit) -> substateRLP
)

// UpdateDB represents a CodeDB with in which the UpdateSet is inserted.
Expand All @@ -30,15 +30,15 @@ type UpdateDB interface {
HasUpdateSet(block uint64) (bool, error)

// GetUpdateSet returns UpdateSet for given block. If there is not an UpdateSet for the block, nil is returned.
GetUpdateSet(block uint64) (*update_set.UpdateSet, error)
GetUpdateSet(block uint64) (*updateset.UpdateSet, error)

// PutUpdateSet inserts the UpdateSet with deleted accounts into the DB assigned to given block.
PutUpdateSet(updateSet *update_set.UpdateSet, deletedAccounts []common.Address) error
PutUpdateSet(updateSet *updateset.UpdateSet, deletedAccounts []common.Address) error

// DeleteUpdateSet deletes UpdateSet for given block. It returns an error if there is no UpdateSet on given block.
DeleteUpdateSet(block uint64) error

NewUpdateSetIterator(start, end uint64) Iterator[*update_set.UpdateSet]
NewUpdateSetIterator(start, end uint64) Iterator[*updateset.UpdateSet]
}

// NewDefaultUpdateDB creates new instance of UpdateDB with default options.
Expand All @@ -65,7 +65,7 @@ type updateDB struct {
}

func (db *updateDB) GetFirstKey() (uint64, error) {
r := util.BytesPrefix([]byte(SubstateAllocPrefix))
r := util.BytesPrefix([]byte(UpdateDBPrefix))

iter := db.backend.NewIterator(r, db.ro)
defer iter.Release()
Expand All @@ -81,7 +81,7 @@ func (db *updateDB) GetFirstKey() (uint64, error) {
}

func (db *updateDB) GetLastKey() (uint64, error) {
r := util.BytesPrefix([]byte(SubstateAllocPrefix))
r := util.BytesPrefix([]byte(UpdateDBPrefix))

iter := db.backend.NewIterator(r, nil)
defer iter.Release()
Expand All @@ -99,12 +99,12 @@ func (db *updateDB) GetLastKey() (uint64, error) {
}

func (db *updateDB) HasUpdateSet(block uint64) (bool, error) {
key := SubstateAllocKey(block)
key := UpdateDBKey(block)
return db.Has(key)
}

func (db *updateDB) GetUpdateSet(block uint64) (*update_set.UpdateSet, error) {
key := SubstateAllocKey(block)
func (db *updateDB) GetUpdateSet(block uint64) (*updateset.UpdateSet, error) {
key := UpdateDBKey(block)
value, err := db.Get(key)
if err != nil {
return nil, fmt.Errorf("cannot get updateset block: %v, key %v; %v", block, key, err)
Expand All @@ -115,25 +115,25 @@ func (db *updateDB) GetUpdateSet(block uint64) (*update_set.UpdateSet, error) {
}

// decode value
var updateSetRLP update_set.UpdateSetRLP
var updateSetRLP updateset.UpdateSetRLP
if err = gethrlp.DecodeBytes(value, &updateSetRLP); err != nil {
return nil, fmt.Errorf("cannot decode update-set rlp block: %v, key %v; %v", block, key, err)
}

return updateSetRLP.ToSubstateAlloc(db.GetCode, block)
return updateSetRLP.ToWorldState(db.GetCode, block)
}

func (db *updateDB) PutUpdateSet(updateSet *update_set.UpdateSet, deletedAccounts []common.Address) error {
func (db *updateDB) PutUpdateSet(updateSet *updateset.UpdateSet, deletedAccounts []common.Address) error {
// put deployed/creation code
for _, account := range updateSet.Alloc {
for _, account := range updateSet.WorldState {
err := db.PutCode(account.Code)
if err != nil {
return err
}
}

key := SubstateAllocKey(updateSet.Block)
updateSetRLP := update_set.NewUpdateSetRLP(updateSet, deletedAccounts)
key := UpdateDBKey(updateSet.Block)
updateSetRLP := updateset.NewUpdateSetRLP(updateSet, deletedAccounts)

value, err := gethrlp.EncodeToBytes(updateSetRLP)
if err != nil {
Expand All @@ -144,11 +144,11 @@ func (db *updateDB) PutUpdateSet(updateSet *update_set.UpdateSet, deletedAccount
}

func (db *updateDB) DeleteUpdateSet(block uint64) error {
key := SubstateAllocKey(block)
key := UpdateDBKey(block)
return db.Delete(key)
}

func (db *updateDB) NewUpdateSetIterator(start, end uint64) Iterator[*update_set.UpdateSet] {
func (db *updateDB) NewUpdateSetIterator(start, end uint64) Iterator[*updateset.UpdateSet] {
iter := newUpdateSetIterator(db, start, end)

iter.start(0)
Expand All @@ -157,7 +157,7 @@ func (db *updateDB) NewUpdateSetIterator(start, end uint64) Iterator[*update_set
}

func DecodeUpdateSetKey(key []byte) (block uint64, err error) {
prefix := SubstateAllocPrefix
prefix := UpdateDBPrefix
if len(key) != len(prefix)+8 {
err = fmt.Errorf("invalid length of updateset key: %v", len(key))
return
Expand All @@ -171,8 +171,8 @@ func DecodeUpdateSetKey(key []byte) (block uint64, err error) {
return
}

func SubstateAllocKey(block uint64) []byte {
prefix := []byte(SubstateAllocPrefix)
func UpdateDBKey(block uint64) []byte {
prefix := []byte(UpdateDBPrefix)
blockTx := make([]byte, 8)
binary.BigEndian.PutUint64(blockTx[0:8], block)
return append(prefix, blockTx...)
Expand Down
6 changes: 3 additions & 3 deletions db/update_db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (

"github.com/Fantom-foundation/Substate/geth/common"
"github.com/Fantom-foundation/Substate/substate"
"github.com/Fantom-foundation/Substate/update_set"
"github.com/Fantom-foundation/Substate/updateset"
"github.com/syndtr/goleveldb/leveldb"
)

var testUpdateSet = &update_set.UpdateSet{
Alloc: substate.Alloc{
var testUpdateSet = &updateset.UpdateSet{
WorldState: substate.WorldState{
common.Address{1}: &substate.Account{
Nonce: 1,
Balance: new(big.Int).SetUint64(1),
Expand Down
Loading