Skip to content

Commit

Permalink
Merge pull request #33 from informalsystems/ph/block-production-flag
Browse files Browse the repository at this point in the history
Adds a flag that controlls block production and pulls changes to be v0.37.x compliant
  • Loading branch information
p-offtermatt authored Aug 21, 2023
2 parents ca2bb6d + 2899022 commit a5cda3a
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 144 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 {app_address1,app_address2,...} {genesis_file} {cometmock_listen_address} {home_folder1,home_folder2,...} {connection_mode} [--block-time=XXX]
```

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 `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`.
* 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).

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
253 changes: 143 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,6 +15,7 @@ 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"
)

// GetMockPVsFromNodeHomes returns a list of MockPVs, created with the priv_validator_key's from the specified node homes
Expand All @@ -35,118 +38,148 @@ 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>")
argumentString := "<app-addresses> <genesis-file> <cometmock-listen-address> <node-homes> <abci-connection-mode> [--block-time=value]"

app := &cli.App{
Name: "cometmock",
HideHelpCommand: true,
Usage: "Your application description",
Flags: []cli.Flag{
&cli.IntFlag{
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)

// 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)
}
},
}

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)
err := app.Run(os.Args)
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)

// 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 @@ -13,6 +13,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 @@ -40,9 +41,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 @@ -72,7 +72,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 @@ -274,7 +277,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 @@ -301,7 +307,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
16 changes: 16 additions & 0 deletions go_rly_consumer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"type": "cosmos",
"value": {
"key": "default",
"chain-id": "consumer",
"rpc-addr": "tcp://127.0.0.1:22332",
"account-prefix": "cosmos",
"keyring-backend": "test",
"gas-adjustment": 1.2,
"gas-prices": "0.01stake",
"debug": true,
"timeout": "20s",
"output-format": "json",
"sign-mode": "direct"
}
}
14 changes: 14 additions & 0 deletions go_rly_ics_path_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"src": {
"chain-id": "consumer",
"client-id": "07-tendermint-0"
},
"dst": {
"chain-id": "provider",
"client-id": "07-tendermint-0"
},
"src-channel-filter": {
"rule": "",
"channel-list": []
}
}
Loading

0 comments on commit a5cda3a

Please sign in to comment.