Skip to content

Commit

Permalink
Merge pull request #57 from informalsystems/ph/rebase-v0.37.x
Browse files Browse the repository at this point in the history
Rebase v0.37.x to be up-to-date with the main branch
  • Loading branch information
p-offtermatt authored Sep 12, 2023
2 parents 680d462 + 6fcb137 commit 51c917b
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 119 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
install:
go install ./cometmock
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ controlling which validators sign blocks,

On a technical level, CometMock communicates with applications via ABCI through GRPC or TSP (Tendermint Socket Protocol) calls. It calls BeginBlock, DeliverTx, EndBlock and Commit like CometBFT does during normal execution.

Currently, CometMock imitates CometBFT v0.34. It offers *many* of the RPC endpoints offered by Comet (https://docs.cometbft.com/v0.34/rpc/),
Currently, CometMock maintains releases compatible with CometBFT v0.37 and v0.34, see branches [v0.34.x](https://github.com/informalsystems/CometMock/tree/v0.34.x) and [v0.37.x](https://github.com/informalsystems/CometMock/tree/v0.37.x). It offers *many* of the RPC endpoints offered by Comet (see https://docs.cometbft.com/v0.34/rpc/ and https://docs.cometbft.com/v0.37/rpc/ for the respective version of the interface),
in particular it supports the subset used by Gorelayer (https://github.com/cosmos/relayer/).
See the endpoints offered here: [https://github.com/informalsystems/CometMock/cometmock/rpc_server/routes.go#L30C2-L53](https://github.com/informalsystems/CometMock/blob/main/cometmock/rpc_server/routes.go)

Expand All @@ -27,15 +27,16 @@ CometMock was tested with `go version go1.20.3 darwin/arm64`.
To run CometMock, start your (cosmos-sdk) application instances with the flags ```--with-tendermint=false, --transport=grpc```.
After the applications started, start CometMock like this
```
cometmock {app_address1,app_address2,...} {genesis_file} {cometmock_listen_address} {home_folder1,home_folder2,...} {connection_mode}
cometmock [--block-time=XXX] {app_address1,app_address2,...} {genesis_file} {cometmock_listen_address} {home_folder1,home_folder2,...} {connection_mode}
```

where
* the `app_addresses` are the `--address` flags of the applications (this is by default `"tcp://0.0.0.0:26658"`
* the `genesis_file` is the genesis json that is also used by apps,
* the `cometmock_listen_address` can be freely chosen and will be the address that requests that would normally go to CometBFT rpc endpoints need to be directed to
* the `home_folders` are the home folders of the applications, in the same order as the `app_addresses`. This is required to use the private keys in the application folders to sign as appropriate validators.
* connection mode is the protocol over which CometMock should connect to the ABCI application, either `grpc` or `socket`. See the `--transport` flag for Cosmos SDK applications. For SDK applications, just make sure `--transport` and this argument match, i.e. either both `socket` or both `grpc`.
where:
* The `--block-time` flag is optional and specifies the time in milliseconds between blocks. The default is 1000ms(=1s). Values <= 0 mean that automatic block production is disabled. In this case, blocks can be produced by calling the `advance_blocks` endpoint or by broadcasting transactions (each transaction will be included in a fresh block). Note that all flags have to come before positional arguments.
* The `app_addresses` are the `--address` flags of the applications. This is by default `"tcp://0.0.0.0:26658"`
* The `genesis_file` is the genesis json that is also used by apps.
* The `cometmock_listen_address` can be freely chosen and will be the address that requests that would normally go to CometBFT rpc endpoints need to be directed to.
* The `home_folders` are the home folders of the applications, in the same order as the `app_addresses`. This is required to use the private keys in the application folders to sign as appropriate validators.
* Connection mode is the protocol over which CometMock should connect to the ABCI application, either `grpc` or `socket`. See the `--transport` flag for Cosmos SDK applications. For SDK applications, just make sure `--transport` and this argument match, i.e. either both `socket` or both `grpc`.

When calling the cosmos sdk cli, use as node address the `cometmock_listen_address`,
e.g. `simd q bank total --node {cometmock_listen_address}`.
Expand Down
270 changes: 160 additions & 110 deletions cometmock/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"fmt"
"log"
"os"
"strings"
"time"
Expand All @@ -13,8 +15,11 @@ import (
"github.com/informalsystems/CometMock/cometmock/abci_client"
"github.com/informalsystems/CometMock/cometmock/rpc_server"
"github.com/informalsystems/CometMock/cometmock/storage"
"github.com/urfave/cli/v2"
)

const version = "v0.37.x"

// GetMockPVsFromNodeHomes returns a list of MockPVs, created with the priv_validator_key's from the specified node homes
// We use MockPV because they do not do sanity checks that would e.g. prevent double signing
func GetMockPVsFromNodeHomes(nodeHomes []string) []types.PrivValidator {
Expand All @@ -35,118 +40,163 @@ func GetMockPVsFromNodeHomes(nodeHomes []string) []types.PrivValidator {
func main() {
logger := cometlog.NewTMLogger(cometlog.NewSyncWriter(os.Stdout))

if len(os.Args) != 6 {
logger.Error("Usage: <app-addresses> <genesis-file> <cometmock-listen-address> <node-homes> <abci-connection-mode>")
}

args := os.Args[1:]

appAddresses := strings.Split(args[0], ",")
genesisFile := args[1]
cometMockListenAddress := args[2]
nodeHomesString := args[3]
connectionMode := args[4]

// read node homes from args
nodeHomes := strings.Split(nodeHomesString, ",")

// get priv validators from node Homes
privVals := GetMockPVsFromNodeHomes(nodeHomes)

if connectionMode != "socket" && connectionMode != "grpc" {
logger.Error("Invalid connection mode: %s. Connection mode must be either 'socket' or 'grpc'.", "connectionMode:", connectionMode)
}

genesisDoc, err := state.MakeGenesisDocFromFile(genesisFile)
if err != nil {
logger.Error(err.Error())
}

curState, err := state.MakeGenesisState(genesisDoc)
if err != nil {
logger.Error(err.Error())
}

clients := []abci_client.AbciCounterpartyClient{}
privValsMap := make(map[string]types.PrivValidator)

for i, appAddress := range appAddresses {
logger.Info("Connecting to client at %v", appAddress)

var client comet_abciclient.Client
if connectionMode == "grpc" {
client = comet_abciclient.NewGRPCClient(appAddress, true)
} else {
client = comet_abciclient.NewSocketClient(appAddress, true)
}
client.SetLogger(logger)
client.Start()

privVal := privVals[i]

pubkey, err := privVal.GetPubKey()
if err != nil {
logger.Error(err.Error())
panic(err)
}
validatorAddress := pubkey.Address()

privValsMap[validatorAddress.String()] = privVal

counterpartyClient := abci_client.NewAbciCounterpartyClient(client, appAddress, validatorAddress.String(), privVal)

clients = append(clients, *counterpartyClient)

}

for _, privVal := range privVals {
pubkey, err := privVal.GetPubKey()
if err != nil {
logger.Error(err.Error())
panic(err)
}
addr := pubkey.Address()

privValsMap[addr.String()] = privVal
}

abci_client.GlobalClient = abci_client.NewAbciClient(
clients,
logger,
curState,
&types.Block{},
&types.Commit{},
&storage.MapStorage{},
privValsMap,
true,
)

// connect to clients
abci_client.GlobalClient.RetryDisconnectedClients()

// initialize chain
err = abci_client.GlobalClient.SendInitChain(curState, genesisDoc)
if err != nil {
logger.Error(err.Error())
panic(err)
argumentString := "[--block-time=value] <app-addresses> <genesis-file> <cometmock-listen-address> <node-homes> <abci-connection-mode>"

app := &cli.App{
Name: "cometmock",
HideHelpCommand: true,
Commands: []*cli.Command{
{
Name: "version",
Usage: "Print the version of cometmock",
Action: func(c *cli.Context) error {
fmt.Printf("%s\n", version)
return nil
},
},
},
Flags: []cli.Flag{
&cli.Int64Flag{
Name: "block-time",
Usage: `
Time between blocks in milliseconds.
To disable block production, set to 0.
This will not necessarily mean block production is this fast
- it is just the sleep time between blocks.
Setting this to a value <= 0 disables automatic block production.
In this case, blocks are only produced when instructed explicitly either by
advancing blocks or broadcasting transactions.`,
Value: 1000,
},
},
ArgsUsage: argumentString,
Action: func(c *cli.Context) error {
if c.NArg() < 5 {
return cli.Exit("Not enough arguments.\nUsage: "+argumentString, 1)
}

appAddresses := strings.Split(c.Args().Get(0), ",")
genesisFile := c.Args().Get(1)
cometMockListenAddress := c.Args().Get(2)
nodeHomesString := c.Args().Get(3)
connectionMode := c.Args().Get(4)

if connectionMode != "socket" && connectionMode != "grpc" {
return cli.Exit(fmt.Sprintf("Invalid connection mode: %s. Connection mode must be either 'socket' or 'grpc'.\nUsage: %s", connectionMode, argumentString), 1)
}

blockTime := c.Int("block-time")
fmt.Printf("Block time: %d\n", blockTime)

// read node homes from args
nodeHomes := strings.Split(nodeHomesString, ",")

// get priv validators from node Homes
privVals := GetMockPVsFromNodeHomes(nodeHomes)

genesisDoc, err := state.MakeGenesisDocFromFile(genesisFile)
if err != nil {
logger.Error(err.Error())
}

curState, err := state.MakeGenesisState(genesisDoc)
if err != nil {
logger.Error(err.Error())
}

clients := []abci_client.AbciCounterpartyClient{}
privValsMap := make(map[string]types.PrivValidator)

for i, appAddress := range appAddresses {
logger.Info("Connecting to client at %v", appAddress)

var client comet_abciclient.Client
if connectionMode == "grpc" {
client = comet_abciclient.NewGRPCClient(appAddress, true)
} else {
client = comet_abciclient.NewSocketClient(appAddress, true)
}
client.SetLogger(logger)
client.Start()

privVal := privVals[i]

pubkey, err := privVal.GetPubKey()
if err != nil {
logger.Error(err.Error())
panic(err)
}
validatorAddress := pubkey.Address()

privValsMap[validatorAddress.String()] = privVal

counterpartyClient := abci_client.NewAbciCounterpartyClient(client, appAddress, validatorAddress.String(), privVal)

clients = append(clients, *counterpartyClient)

}

for _, privVal := range privVals {
pubkey, err := privVal.GetPubKey()
if err != nil {
logger.Error(err.Error())
panic(err)
}
addr := pubkey.Address()

privValsMap[addr.String()] = privVal
}

abci_client.GlobalClient = abci_client.NewAbciClient(
clients,
logger,
curState,
&types.Block{},
&types.Commit{},
&storage.MapStorage{},
privValsMap,
true,
)

// connect to clients
abci_client.GlobalClient.RetryDisconnectedClients()

// initialize chain
err = abci_client.GlobalClient.SendInitChain(curState, genesisDoc)
if err != nil {
logger.Error(err.Error())
panic(err)
}

// run an empty block
_, _, _, _, _, err = abci_client.GlobalClient.RunBlock(nil)
if err != nil {
logger.Error(err.Error())
panic(err)
}

go rpc_server.StartRPCServerWithDefaultConfig(cometMockListenAddress, logger)

if blockTime > 0 {
// produce blocks according to blockTime
for {
_, _, _, _, _, err := abci_client.GlobalClient.RunBlock(nil)
if err != nil {
logger.Error(err.Error())
panic(err)
}
time.Sleep(time.Millisecond * time.Duration(blockTime))
}
} else {
// wait forever
time.Sleep(time.Hour * 24 * 365 * 100) // 100 years
}
return nil
},
}

// run an empty block
_, _, _, _, _, err = abci_client.GlobalClient.RunBlock(nil)
err := app.Run(os.Args)
if err != nil {
logger.Error(err.Error())
panic(err)
}

go rpc_server.StartRPCServerWithDefaultConfig(cometMockListenAddress, logger)

// produce a block every second
for {
_, _, _, _, _, err := abci_client.GlobalClient.RunBlock(nil)
if err != nil {
logger.Error(err.Error())
panic(err)
}
time.Sleep(1 * time.Second)
log.Fatal(err)
}
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cosmos/gogoproto v1.4.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/dgraph-io/badger/v2 v2.2007.4 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
Expand Down Expand Up @@ -41,9 +42,12 @@ require (
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect
github.com/urfave/cli/v2 v2.25.7 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/net v0.7.0 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=
github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8=
github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -276,7 +279,10 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand All @@ -303,7 +309,11 @@ github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok=
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
2 changes: 1 addition & 1 deletion local-testnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -423,4 +423,4 @@ rly paths add consumer provider testpath --file go_rly_ics_path_config.json
rly tx clients testpath
rly tx connection testpath
rly tx channel testpath --src-port consumer --dst-port provider --version 1 --order ordered --debug
rly start
rly start

0 comments on commit 51c917b

Please sign in to comment.