Skip to content

Commit

Permalink
Temporary Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeniy-scherbina committed May 5, 2024
1 parent 2ab51b9 commit a38d5de
Show file tree
Hide file tree
Showing 3 changed files with 401 additions and 72 deletions.
80 changes: 8 additions & 72 deletions x/evm/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ package evm
import (
"bytes"
"fmt"

Check failure on line 20 in x/evm/genesis.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
"github.com/evmos/ethermint/x/evm/statedb"

abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
Expand All @@ -31,84 +29,22 @@ import (
"github.com/evmos/ethermint/x/evm/types"
)

const PrecompileNonce = 1

var PrecompileCode = []byte{0x1}

type StateDB interface {
SetNonce(common.Address, uint64)
SetCode(common.Address, []byte)
}

func SetDifference(a []string, b []string) []string {
bMap := make(map[string]struct{}, len(b))
for _, elem := range b {
bMap[elem] = struct{}{}
}

diff := make([]string, 0)
for _, elem := range a {
if _, ok := bMap[elem]; !ok {
diff = append(diff, elem)
}
}

return diff
}

func SyncEnabledPrecompiles(old []string, new []string) {
validateInited := old
validateUninited := SetDifference(new, old)
init := SetDifference(new, old)
uninit := SetDifference(old, new)

validateInitedPrecompiles(validateInited)
validateUninitedPrecompiles(validateUninited)
initPrecompiles(init)
uninitPrecompiles(uninit)
}

func validateInitedPrecompiles(precompiles []string) {}

func validateUninitedPrecompiles(precompiles []string) {}

func initPrecompiles(stateDB StateDB, addrs []common.Address) {
for _, addr := range addrs {
initPrecompile(stateDB, addr)
}
}

func initPrecompile(stateDB StateDB, addr common.Address) {
// Set the nonce of the precompile's address (as is done when a contract is created) to ensure
// that it is marked as non-empty and will not be cleaned up when the statedb is finalized.
stateDB.SetNonce(addr, PrecompileNonce)
// Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile
// can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure
// that it does not attempt to invoke a non-existent contract.
stateDB.SetCode(addr, PrecompileCode)
}

func uninitPrecompiles(stateDB StateDB, addr common.Address) {
stateDB.SetNonce(addr, 0)
stateDB.SetCode(addr, nil) // TODO(yevhenii): nil or empty slice
}

// InitGenesis initializes genesis state based on exported genesis
func InitGenesis(
ctx sdk.Context,
k *keeper.Keeper,
accountKeeper types.AccountKeeper,
data types.GenesisState,
registeredModules []precompile_modules.Module,
evmKeeper statedb.Keeper,
// evmKeeper statedb.Keeper,
) []abci.ValidatorUpdate {
txConfig := statedb.TxConfig{
BlockHash: common.Hash{},
TxHash: common.Hash{},
TxIndex: 0,
LogIndex: 0,
}
stateDB := statedb.New(ctx, evmKeeper, txConfig)
//txConfig := statedb.TxConfig{

Check failure on line 41 in x/evm/genesis.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

commentFormatting: put a space between `//` and comment text (gocritic)
// BlockHash: common.Hash{},
// TxHash: common.Hash{},
// TxIndex: 0,
// LogIndex: 0,
//}
//stateDB := statedb.New(ctx, evmKeeper, txConfig)

k.WithChainID(ctx)

Expand Down
116 changes: 116 additions & 0 deletions x/evm/keeper/precompile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package keeper

import (
"bytes"
"fmt"

Check failure on line 5 in x/evm/keeper/precompile.go

View workflow job for this annotation

GitHub Actions / Run golangci-lint

File is not `gofumpt`-ed (gofumpt)
"github.com/ethereum/go-ethereum/common"
)

const PrecompileNonce uint64 = 1

var PrecompileCode = []byte{0x1}

type StateDB interface {
GetNonce(addr common.Address) uint64
GetCode(addr common.Address) []byte
SetNonce(common.Address, uint64)
SetCode(common.Address, []byte)
}

type InitializationConfig struct {
ValidateInitialized []common.Address
ValidateUninitialized []common.Address
Initialize []common.Address
Uninitialize []common.Address
}

func SyncEnabledPrecompiles(stateDB StateDB, old []common.Address, new []common.Address) error {
cfg := DetermineInitializationConfig(old, new)
return ApplyInitializationConfig(stateDB, cfg)
}

func DetermineInitializationConfig(old []common.Address, new []common.Address) *InitializationConfig {
return &InitializationConfig{
ValidateInitialized: old,
ValidateUninitialized: SetDifference(new, old),
Initialize: SetDifference(new, old),
Uninitialize: SetDifference(old, new),
}
}

func ApplyInitializationConfig(stateDB StateDB, cfg *InitializationConfig) error {
if err := ValidatePrecompilesInitialized(stateDB, cfg.ValidateInitialized); err != nil {
return err
}
if err := ValidatePrecompilesUninitialized(stateDB, cfg.ValidateUninitialized); err != nil {
return err
}

InitializePrecompiles(stateDB, cfg.Initialize)
UninitializePrecompiles(stateDB, cfg.Uninitialize)

return nil
}

func SetDifference(a []common.Address, b []common.Address) []common.Address {
bMap := make(map[common.Address]struct{}, len(b))
for _, elem := range b {
bMap[elem] = struct{}{}
}

diff := make([]common.Address, 0)
for _, elem := range a {
if _, ok := bMap[elem]; !ok {
diff = append(diff, elem)
}
}

return diff
}

func ValidatePrecompilesInitialized(stateDB StateDB, addrs []common.Address) error {
for _, addr := range addrs {
nonce := stateDB.GetNonce(addr)
code := stateDB.GetCode(addr)

ok := nonce == PrecompileNonce && bytes.Equal(code, PrecompileCode)
if !ok {
return fmt.Errorf("precompile %v is not initialized, nonce: %v, code: %v", addr, nonce, code)
}
}

return nil
}

func ValidatePrecompilesUninitialized(stateDB StateDB, addrs []common.Address) error {
for _, addr := range addrs {
nonce := stateDB.GetNonce(addr)
code := stateDB.GetCode(addr)

ok := nonce == 0 && bytes.Equal(code, nil)
if !ok {
return fmt.Errorf("precompile %v is initialized, nonce: %v, code: %v", addr, nonce, code)
}
}

return nil
}

func InitializePrecompiles(stateDB StateDB, addrs []common.Address) {
for _, addr := range addrs {
// Set the nonce of the precompile's address (as is done when a contract is created) to ensure
// that it is marked as non-empty and will not be cleaned up when the statedb is finalized.
stateDB.SetNonce(addr, PrecompileNonce)
// Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile
// can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure
// that it does not attempt to invoke a non-existent contract.
stateDB.SetCode(addr, PrecompileCode)
}
}

func UninitializePrecompiles(stateDB StateDB, addrs []common.Address) {
for _, addr := range addrs {
stateDB.SetNonce(addr, 0)
stateDB.SetCode(addr, nil)
}
}
Loading

0 comments on commit a38d5de

Please sign in to comment.