Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
476ed9f
introduce safe state to prevent data race
Jun 21, 2024
075ae5c
rpc table test
vasylNaumenko May 3, 2024
da6f485
preliminary version of combination of table tests, and business logic…
May 8, 2024
c2bd13d
draft unit tests
May 14, 2024
927ffb0
proxy app checkTx empty response
May 14, 2024
da2b026
add implementation of test abci service
May 15, 2024
f8ebd06
add flexibility to imitate block build process
May 16, 2024
a3eeb5b
add Id param to BlockAccept call
May 16, 2024
906232d
add status service test
May 21, 2024
9533cf0
key encoding to hex
May 23, 2024
12540fc
fix mistake: mempool size will not increase after build block
May 23, 2024
6b22b0e
finalize network service unit test
May 27, 2024
f5f8078
finalize status service unit test
May 27, 2024
80a79ea
preliminary version of history and sign client
May 30, 2024
ac2f226
finalize tests for history client
Jun 4, 2024
cabd636
compare app hash of block to previous state
Jun 6, 2024
dfe0720
fix test block production
Jun 6, 2024
213a2e3
introduce test block results
Jun 10, 2024
23999f7
implement BlockSearch unit test
Jun 10, 2024
100d43b
implement TxSearch unit test
Jun 10, 2024
1eb6ac6
implement commit rpc unit test
Jun 10, 2024
d690c51
fix block by hash params input to appropriate format
Jun 11, 2024
725568d
introduce unconfirmed txs unit test
Jun 11, 2024
144c9e3
check tx unit test implementation
Jun 12, 2024
414f170
add test cases for Check Tx unit test
Jun 13, 2024
c71e9b8
put off checks of unimplemented rpc tests until later. Clean up code
Jun 18, 2024
193e06c
fix U1000 staticcheck: use unused non-imported tests
Jun 19, 2024
09343c2
get rid of new block unnecessary log
Jun 20, 2024
471b779
wait for state to be updated
Jun 20, 2024
21d7485
use safe state of vm in unit tests
Jun 23, 2024
be58ed4
update state instead of create new state; rename field of vm
Jun 23, 2024
d1013e0
fix VM Shutdown panic (#39)
ramilexe Jun 23, 2024
ef508a7
add persistence storage for KVStore and Wasm app (#40)
ramilexe Jun 23, 2024
039ae68
implement websocket connection
Jun 26, 2024
74c1443
change ctx with timeout initialization
Jun 27, 2024
352a546
clean up code for websocket connection
Jul 1, 2024
2f517b5
gRPC endpoint for CosmWasm app (#43)
vasylNaumenko Jul 7, 2024
bb6b432
put same part of ws and httprpc setup to separate func
Jul 9, 2024
d3d9b8f
refactor server setup to maintain ws connection
Jul 10, 2024
7349b70
implement rpcclient.Client interface
Jul 15, 2024
2d75339
add websocket transport for unit tests
Jul 17, 2024
9ece813
Merge branch 'dev' into add-tests-for-websocket-connection
ivansukach Jul 23, 2024
32e6f2d
add constructor for ws client
Jul 31, 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
4 changes: 3 additions & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ name: Go

on:
push:
branches: [ "main" ]
branches:
- "main"
- "dev"
pull_request:

jobs:
Expand Down
9 changes: 8 additions & 1 deletion example/kvstore/kvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ import (
"github.com/cometbft/cometbft/abci/example/kvstore"

"github.com/consideritdone/landslidevm"
"github.com/consideritdone/landslidevm/vm"
)

func main() {
appCreator := landslidevm.NewLocalAppCreator(kvstore.NewInMemoryApplication())
appCreator := KvStoreCreator()
if err := landslidevm.Serve(context.Background(), appCreator); err != nil {
panic(fmt.Sprintf("can't serve application: %s", err))
}
}

func KvStoreCreator() vm.AppCreator {
return func(config *vm.AppCreatorOpts) (vm.Application, error) {
return kvstore.NewPersistentApplication(config.ChainDataDir), nil
}
}
200 changes: 186 additions & 14 deletions example/wasm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,211 @@ package main

import (
"context"
"encoding/json"
"fmt"
"os"
"os/signal"
"syscall"

"cosmossdk.io/log"
"github.com/CosmWasm/wasmd/app"
"github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
"github.com/cosmos/cosmos-sdk/server"
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
servergrpc "github.com/cosmos/cosmos-sdk/server/grpc"
"github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"github.com/consideritdone/landslidevm"
"github.com/consideritdone/landslidevm/utils/ids"
"github.com/consideritdone/landslidevm/vm"
vmtypes "github.com/consideritdone/landslidevm/vm/types"
)

func main() {
db, err := dbm.NewDB("dbName", dbm.MemDBBackend, "")
if err != nil {
panic(err)
appCreator := WasmCreator()
if err := landslidevm.Serve(context.Background(), appCreator); err != nil {
panic(fmt.Sprintf("can't serve application: %s", err))
}
logger := log.NewNopLogger()
}

cfg := sdk.GetConfig()
cfg.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub)
cfg.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub)
cfg.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub)
cfg.SetAddressVerifier(wasmtypes.VerifyAddressLen())
cfg.Seal()
wasmApp := app.NewWasmApp(logger, db, nil, true, sims.NewAppOptionsWithFlagHome(os.TempDir()), []keeper.Option{}, baseapp.SetChainID("landslide-test"))
func WasmCreator() vm.AppCreator {
return func(config *vm.AppCreatorOpts) (vm.Application, error) {
db, err := dbm.NewDB("wasm", dbm.GoLevelDBBackend, config.ChainDataDir)
if err != nil {
panic(err)
}
logger := log.NewNopLogger()

appCreator := landslidevm.NewLocalAppCreator(server.NewCometABCIWrapper(wasmApp))
if err := landslidevm.Serve(context.Background(), appCreator); err != nil {
panic(fmt.Sprintf("can't serve application: %s", err))
cfg := sdk.GetConfig()
cfg.SetBech32PrefixForAccount(app.Bech32PrefixAccAddr, app.Bech32PrefixAccPub)
cfg.SetBech32PrefixForValidator(app.Bech32PrefixValAddr, app.Bech32PrefixValPub)
cfg.SetBech32PrefixForConsensusNode(app.Bech32PrefixConsAddr, app.Bech32PrefixConsPub)
cfg.SetAddressVerifier(wasmtypes.VerifyAddressLen())
cfg.Seal()

srvCfg := *srvconfig.DefaultConfig()
grpcCfg := srvCfg.GRPC
var vmCfg vmtypes.VmConfig
vmCfg.SetDefaults()
if len(config.ConfigBytes) > 0 {
if err := json.Unmarshal(config.ConfigBytes, &vmCfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal config %s: %w", string(config.ConfigBytes), err)
}
// set the grpc port, if it is set to 0, disable gRPC
if vmCfg.GRPCPort > 0 {
grpcCfg.Address = fmt.Sprintf("127.0.0.1:%d", vmCfg.GRPCPort)
} else {
grpcCfg.Enable = false
}
}

if err := vmCfg.Validate(); err != nil {
return nil, err
}
chainID := vmCfg.NetworkName

var wasmApp = app.NewWasmApp(
logger,
db,
nil,
true,
sims.NewAppOptionsWithFlagHome(os.TempDir()),
[]keeper.Option{},
baseapp.SetChainID(chainID),
)

// early return if gRPC is disabled
if !grpcCfg.Enable {
return server.NewCometABCIWrapper(wasmApp), nil
}

interfaceRegistry := wasmApp.InterfaceRegistry()
marshaller := codec.NewProtoCodec(interfaceRegistry)
clientCtx := client.Context{}.
WithCodec(marshaller).
WithLegacyAmino(makeCodec()).
WithTxConfig(tx.NewTxConfig(marshaller, tx.DefaultSignModes)).
WithInterfaceRegistry(interfaceRegistry).
WithChainID(chainID)

avaChainID, err := ids.ToID(config.ChainId)
if err != nil {
return nil, err
}

rpcURI := fmt.Sprintf(
"http://127.0.0.1:%d/ext/bc/%s/rpc",
vmCfg.RPCPort,
avaChainID,
)

clientCtx = clientCtx.WithNodeURI(rpcURI)
rpcclient, err := rpchttp.New(rpcURI, "/websocket")
if err != nil {
return nil, err
}
clientCtx = clientCtx.WithClient(rpcclient)

// use the provided clientCtx to register the services
wasmApp.RegisterTxService(clientCtx)
wasmApp.RegisterTendermintService(clientCtx)
wasmApp.RegisterNodeService(clientCtx, srvconfig.Config{})

maxSendMsgSize := grpcCfg.MaxSendMsgSize
if maxSendMsgSize == 0 {
maxSendMsgSize = srvconfig.DefaultGRPCMaxSendMsgSize
}

maxRecvMsgSize := grpcCfg.MaxRecvMsgSize
if maxRecvMsgSize == 0 {
maxRecvMsgSize = srvconfig.DefaultGRPCMaxRecvMsgSize
}

// if gRPC is enabled, configure gRPC client for gRPC gateway
grpcClient, err := grpc.Dial(
grpcCfg.Address,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithDefaultCallOptions(
grpc.ForceCodec(codec.NewProtoCodec(clientCtx.InterfaceRegistry).GRPCCodec()),
grpc.MaxCallRecvMsgSize(maxRecvMsgSize),
grpc.MaxCallSendMsgSize(maxSendMsgSize),
),
)
if err != nil {
return nil, err
}

clientCtx = clientCtx.WithGRPCClient(grpcClient)
logger.Debug("gRPC client assigned to client context", "target", grpcCfg.Address)

g, ctx := getCtx(logger, false)

grpcSrv, err := servergrpc.NewGRPCServer(clientCtx, wasmApp, grpcCfg)
if err != nil {
return nil, err
}

// Start the gRPC server in a goroutine. Note, the provided ctx will ensure
// that the server is gracefully shut down.
g.Go(func() error {
return servergrpc.StartGRPCServer(ctx, logger.With("module", "grpc-server"), grpcCfg, grpcSrv)
})

return server.NewCometABCIWrapper(wasmApp), nil
}
}

// custom tx codec
func makeCodec() *codec.LegacyAmino {
cdc := codec.NewLegacyAmino()
sdk.RegisterLegacyAminoCodec(cdc)
cryptocodec.RegisterCrypto(cdc)
return cdc
}

func getCtx(logger log.Logger, block bool) (*errgroup.Group, context.Context) {
ctx, cancelFn := context.WithCancel(context.Background())
g, ctx := errgroup.WithContext(ctx)
// listen for quit signals so the calling parent process can gracefully exit
listenForQuitSignals(g, block, cancelFn, logger)
return g, ctx
}

// listenForQuitSignals listens for SIGINT and SIGTERM. When a signal is received,
// the cleanup function is called, indicating the caller can gracefully exit or
// return.
//
// Note, the blocking behavior of this depends on the block argument.
// The caller must ensure the corresponding context derived from the cancelFn is used correctly.
func listenForQuitSignals(g *errgroup.Group, block bool, cancelFn context.CancelFunc, logger log.Logger) {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)

f := func() {
sig := <-sigCh
cancelFn()

logger.Info("caught signal", "signal", sig.String())
}

if block {
g.Go(func() error {
f()
return nil
})
} else {
go f()
}
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/cometbft/cometbft-db v0.8.0
github.com/cosmos/cosmos-db v1.0.2
github.com/cosmos/cosmos-sdk v0.50.1
github.com/gotestyourself/gotestyourself v2.2.0+incompatible
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/mr-tron/base58 v1.2.0
github.com/prometheus/client_golang v1.17.0
Expand Down Expand Up @@ -201,8 +202,12 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools v2.2.0+incompatible // indirect
gotest.tools/v3 v3.5.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

// pin version! 126854af5e6d has issues with the store so that queries fail
replace github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
Loading