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

imp(contracts): Add contracts directory and compilation script #24

Merged
merged 27 commits into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2d0025e
add wallets types
MalteHerrmann Aug 2, 2024
b38681a
add changelog entry
MalteHerrmann Aug 2, 2024
974b38b
use example chain ID in wallet tests
MalteHerrmann Aug 2, 2024
38442cc
add crypto package
MalteHerrmann Aug 2, 2024
3541a4d
regenerate protos
MalteHerrmann Aug 2, 2024
2ac53ca
add changelog entry
MalteHerrmann Aug 2, 2024
d12c2a3
change mention of Ethermint
MalteHerrmann Aug 2, 2024
5018c0b
adjust package imports
MalteHerrmann Aug 2, 2024
b770d55
add encoding package
MalteHerrmann Aug 2, 2024
2459447
replace import paths for encoding
MalteHerrmann Aug 2, 2024
464216d
adjust changelog
MalteHerrmann Aug 2, 2024
0928771
add rpc and kv indexer types
MalteHerrmann Aug 2, 2024
8e8303d
add changelog entry
MalteHerrmann Aug 2, 2024
81ba954
add testutil tx subpackage
MalteHerrmann Aug 4, 2024
071d933
adjust import paths and address linters
MalteHerrmann Aug 4, 2024
1eca56d
add server implementation and adjust import paths
MalteHerrmann Aug 4, 2024
0150dbc
remove unnecessary legacy import
MalteHerrmann Aug 4, 2024
88e9785
run gofumpt
MalteHerrmann Aug 4, 2024
9645496
add changelog entry
MalteHerrmann Aug 4, 2024
b465072
sort some more imports
MalteHerrmann Aug 4, 2024
217bb7d
add client, cmd and version packages
MalteHerrmann Aug 4, 2024
eee02ec
add changelog entry
MalteHerrmann Aug 4, 2024
ccc87ba
add contracts directory plus utils and compilation script
MalteHerrmann Aug 4, 2024
f3e8921
add changelog entry
MalteHerrmann Aug 4, 2024
89057fc
adjust import path
MalteHerrmann Aug 4, 2024
979cc81
Merge branch 'main' into add-contracts
MalteHerrmann Aug 6, 2024
9ea91e9
address isort linter
MalteHerrmann Aug 6, 2024
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
3 changes: 2 additions & 1 deletion .clconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"proto",
"rpc",
"staking-precompile",
"tests"
"tests",
"types"
],
"change_types": {
"API Breaking": "api\\s*breaking",
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ This changelog was created using the `clu` binary

### Improvements

- (cli) [#23](https://github.com/evmos/os/pull/23) Add client, cmd and version packages.
- (rpc) [#22](https://github.com/evmos/os/pull/22) Add server implementation.
- (rpc) [#21](https://github.com/evmos/os/pull/21) Add RPC and indexer types.
- (types) [#20](https://github.com/evmos/os/pull/20) Add crypto and encoding packages.
- (types) [#19](https://github.com/evmos/os/pull/19) Add required wallet types for integration.
- (all) [#15](https://github.com/evmos/os/pull/15) Add general types and utils.
- (proto) [#14](https://github.com/evmos/os/pull/14) Add Protobufs and adjust scripts.
- (eip-712) [#13](https://github.com/evmos/os/pull/13) Add EIP-712 package.
Expand Down
73 changes: 73 additions & 0 deletions client/block/block.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright Tharsis Labs Ltd.(Evmos)
// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)

package block

import (
"encoding/json"
"errors"
"fmt"
"strconv"

"github.com/cosmos/cosmos-sdk/server"
"github.com/spf13/cobra"
)

func Cmd() *cobra.Command {
var height string
cmd := &cobra.Command{
Use: "block",
Short: "Get a specific block persisted in the db. If height is not specified, defaults to the latest.",
Long: "Get a specific block persisted in the db. If height is not specified, defaults to the latest.\nThis command works only if no other process is using the db. Before using it, make sure to stop your node.\nIf you're using a custom home directory, specify it with the '--home' flag",
PreRunE: func(cmd *cobra.Command, _ []string) error {
// Bind flags to the Context's Viper so the app construction can set
// options accordingly.
serverCtx := server.GetServerContextFromCmd(cmd)
return serverCtx.Viper.BindPFlags(cmd.Flags())
},
RunE: func(cmd *cobra.Command, _ []string) error {
serverCtx := server.GetServerContextFromCmd(cmd)
cfg := serverCtx.Config
home := cfg.RootDir

store, err := newStore(home, server.GetAppDBBackend(serverCtx.Viper))
if err != nil {
return fmt.Errorf("error while openning db: %w", err)
}

state, err := store.state()
if err != nil {
return fmt.Errorf("error while getting blockstore state: %w", err)
}

var reqHeight int64
if height != "latest" {
reqHeight, err = strconv.ParseInt(height, 10, 64)
if err != nil {
return errors.New("invalid height, please provide an integer")
}
if reqHeight > state.Height {
return fmt.Errorf("invalid height, the latest height found in the db is %d, and you asked for %d", state.Height, reqHeight)
}
} else {
reqHeight = state.Height
}

block, err := store.block(reqHeight)
if err != nil {
return fmt.Errorf("error while getting block with height %d: %w", reqHeight, err)
}

bz, err := json.Marshal(block)
if err != nil {
return fmt.Errorf("error while parsing block to JSON: %w", err)
}

cmd.Println(string(bz))
return nil
},
}

cmd.Flags().StringVar(&height, "height", "latest", "Block height to retrieve")
return cmd
}
137 changes: 137 additions & 0 deletions client/block/store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright Tharsis Labs Ltd.(Evmos)
// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)

package block

import (
"errors"
"fmt"
"path/filepath"

dbm "github.com/cometbft/cometbft-db"
tmstore "github.com/cometbft/cometbft/proto/tendermint/store"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cometbft/cometbft/types"
"github.com/cosmos/gogoproto/proto"
)

var storeKey = []byte("blockStore")

// store is the block store struct
type store struct {
dbm.DB
}

// newStore opens the 'blockstore' db
// and returns it.
func newStore(rootDir string, backendType dbm.BackendType) (*store, error) {
dataDir := filepath.Join(rootDir, "data")
db, err := dbm.NewDB("blockstore", backendType, dataDir)
if err != nil {
return nil, err
}

return &store{db}, nil
}

// state returns the BlockStoreState as loaded from disk.
func (s *store) state() (*tmstore.BlockStoreState, error) {
bytes, err := s.Get(storeKey)
if err != nil {
return nil, err
}

if len(bytes) == 0 {
return nil, errors.New("could not find a BlockStoreState persisted in db")
}

var bss tmstore.BlockStoreState
if err := proto.Unmarshal(bytes, &bss); err != nil {
return nil, fmt.Errorf("could not unmarshal bytes: %X", bytes)
}

// Backwards compatibility with persisted data from before Base existed.
if bss.Height > 0 && bss.Base == 0 {
bss.Base = 1
}

return &bss, nil
}

// block returns the Block for the given height.
func (s *store) block(height int64) (*types.Block, error) {
bm, err := s.meta(height)
if err != nil {
return nil, fmt.Errorf("error getting block metadata: %v", err)
}

pbb := new(tmproto.Block)
buf := []byte{}
for i := uint32(0); i < bm.BlockID.PartSetHeader.Total; i++ {
part, err := s.part(height, i)
// If the part is missing (e.g. since it has been deleted after we
// loaded the block meta) we consider the whole block to be missing.
if err != nil {
return nil, fmt.Errorf("error getting block part: %v", err)
}
buf = append(buf, part.Bytes...)
}
if err := proto.Unmarshal(buf, pbb); err != nil {
// NOTE: The existence of meta should imply the existence of the
// block. So, make sure meta is only saved after blocks are saved.
return nil, fmt.Errorf("error reading block: %v", err)
}

return types.BlockFromProto(pbb)
}

// meta returns the BlockMeta for the given height.
// If no block is found for the given height, it returns nil.
func (s *store) meta(height int64) (*types.BlockMeta, error) {
bz, err := s.Get(metaKey(height))
if err != nil {
return nil, err
}

if len(bz) == 0 {
return nil, fmt.Errorf("could not find the block metadata for height %d", height)
}

pbbm := new(tmproto.BlockMeta)
if err = proto.Unmarshal(bz, pbbm); err != nil {
return nil, fmt.Errorf("unmarshal to tmproto.BlockMeta: %w", err)
}

return types.BlockMetaFromProto(pbbm)
}

// part returns the part of the block for the given height and part index.
// If no block part is found for the given height and index, it returns nil.
func (s *store) part(height int64, index uint32) (*types.Part, error) {
bz, err := s.Get(partKey(height, index))
if err != nil {
return nil, err
}
if len(bz) == 0 {
return nil, fmt.Errorf("could not find block part with index %d for block at height %d", index, height)
}

pbpart := new(tmproto.Part)
if err := proto.Unmarshal(bz, pbpart); err != nil {
return nil, fmt.Errorf("unmarshal to tmproto.Part failed: %w", err)
}

return types.PartFromProto(pbpart)
}

// metaKey is a helper function that takes the block height
// as input parameter and returns the corresponding block metadata store key
func metaKey(height int64) []byte {
return []byte(fmt.Sprintf("H:%v", height))
}

// partKey is a helper function that takes the block height
// and the part index as input parameters and returns the corresponding block part store key
func partKey(height int64, partIndex uint32) []byte {
return []byte(fmt.Sprintf("P:%v:%v", height, partIndex))
}
69 changes: 69 additions & 0 deletions client/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright Tharsis Labs Ltd.(Evmos)
// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE)

package client

import (
"fmt"
"os"
"path/filepath"

"github.com/cometbft/cometbft/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/evmos/os/types"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// InitConfig adds the chain-id, encoding and output flags to the persistent flag set.
func InitConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil {
return err
}

configFile := filepath.Join(home, "config", "config.toml")
_, err = os.Stat(configFile)
if err != nil && !os.IsNotExist(err) {
// Immediately return if the error isn't related to the file not existing.
// See issue https://github.com/evmos/ethermint/issues/539
return err
}
if err == nil {
viper.SetConfigFile(configFile)

if err := viper.ReadInConfig(); err != nil {
return err
}
}

if err := viper.BindPFlag(flags.FlagChainID, cmd.PersistentFlags().Lookup(flags.FlagChainID)); err != nil {
return err
}

if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil {
return err
}

return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag))
}

// ValidateChainID wraps a cobra command with a RunE function with base 10 integer chain-id verification.
func ValidateChainID(baseCmd *cobra.Command) *cobra.Command {
// Copy base run command to be used after chain verification
baseRunE := baseCmd.RunE

// Function to replace command's RunE function
validateFn := func(cmd *cobra.Command, args []string) error {
chainID, _ := cmd.Flags().GetString(flags.FlagChainID)

if !types.IsValidChainID(chainID) {
return fmt.Errorf("invalid chain-id format: %s", chainID)
}

return baseRunE(cmd, args)
}

baseCmd.RunE = validateFn
return baseCmd
}
27 changes: 27 additions & 0 deletions client/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package client

import (
"os"
"path/filepath"
"testing"

"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/spf13/cobra"
)

func TestInitConfigNonNotExistError(t *testing.T) {
tempDir := t.TempDir()
subDir := filepath.Join(tempDir, "nonPerms")
if err := os.Mkdir(subDir, 0o600); err != nil {
t.Fatalf("Failed to create sub directory: %v", err)
}
cmd := &cobra.Command{}
cmd.PersistentFlags().String(flags.FlagHome, "", "")
if err := cmd.PersistentFlags().Set(flags.FlagHome, subDir); err != nil {
t.Fatalf("Could not set home flag [%T] %v", err, err)
}

if err := InitConfig(cmd); !os.IsPermission(err) {
t.Fatalf("Failed to catch permissions error, got: [%T] %v", err, err)
}
}
Loading
Loading