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

feat: wrap gRPC client within http handler #14

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions gcosmos/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@

# go build . will make a binary named gcosmos, which we never want to commit.
gcosmos

example-tx*
43 changes: 36 additions & 7 deletions gcosmos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,43 @@ but sometimes a local patch makes more sense.
Begin running the updated siampp commands from the `gcosmos` directory.

```bash
go run . init moniker
echo -n "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" > $HOME/.simappv2/mnemonic.txt
rm -rf ~/.simappv2/
go build -o gcosmos .

go run . keys add val --recover --source $HOME/.simappv2/mnemonic.txt
./gcosmos init moniker

go run . genesis add-genesis-account val 1000000stake --keyring-backend=test
go run . genesis gentx val 1000000stake --keyring-backend=test --chain-id=gcosmos
go run . genesis collect-gentxs
# cosmos1r5v5srda7xfth3hn2s26txvrcrntldjumt8mhl
echo -n "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" > example-mnemonic.txt

go run . start
./gcosmos keys add val --recover --source example-mnemonic.txt
./gcosmos genesis add-genesis-account val 10000000stake --keyring-backend=test
./gcosmos genesis gentx val 1000000stake --keyring-backend=test --chain-id=gcosmos
./gcosmos genesis collect-gentxs

# rm -rf ~/.simappv2/data/application.db/
./gcosmos start --g-http-addr 127.0.0.1:26657 --g-grpc-addr 127.0.0.1:9092
```

# Interact
```bash
# go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

grpcurl -plaintext localhost:9092 list
grpcurl -plaintext localhost:9092 server.GordianGRPC/GetBlocksWatermark
grpcurl -plaintext localhost:9092 server.GordianGRPC/GetValidators

# grpcurl -plaintext localhost:9092 server.GordianGRPC/SubmitTransaction
grpcurl -plaintext -d '{"account_id":"cosmos1r5v5srda7xfth3hn2s26txvrcrntldjumt8mhl","denom":"stake"}' localhost:9092 server.GordianGRPC/QueryAccountBalance
```

# Testing
```bash
./gcosmos tx bank send val cosmos10r39fueph9fq7a6lgswu4zdsg8t3gxlqvvvyvn 1stake --chain-id=TODO:TEMPORARY_CHAIN_ID --generate-only > example-tx.json

# TODO: get account number
./gcosmos tx sign ./example-tx.json --offline --from=val --sequence=1 --account-number=1 --chain-id=TODO:TEMPORARY_CHAIN_ID --keyring-backend=test > example-tx-signed.json

grpcurl -plaintext -d '{"tx":"'$(cat example-tx-signed.json | base64 -w 0)'"}' localhost:9092 server.GordianGRPC/SimulateTransaction

grpcurl -plaintext -d '{"tx":"'$(cat example-tx-signed.json | base64 -w 0)'"}' localhost:9092 server.GordianGRPC/SubmitTransaction
```
1 change: 1 addition & 0 deletions gcosmos/example-mnemonic.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art
69 changes: 51 additions & 18 deletions gcosmos/gserver/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ import (
dht "github.com/libp2p/go-libp2p-kad-dht"
libp2phost "github.com/libp2p/go-libp2p/core/host"
libp2ppeer "github.com/libp2p/go-libp2p/core/peer"
"github.com/rollchains/gordian/gcosmos/gserver/internal/ggrpc"
"github.com/rollchains/gordian/gcosmos/gserver/internal/gsbd"
"github.com/rollchains/gordian/gcosmos/gserver/internal/gsi"
"github.com/rollchains/gordian/gcosmos/gserver/internal/txmanager"
"github.com/rollchains/gordian/gcrypto"
"github.com/rollchains/gordian/gdriver/gtxbuf"
"github.com/rollchains/gordian/gwatchdog"
Expand All @@ -39,6 +41,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"google.golang.org/grpc"
)

// The various interfaces we expect a Component to satisfy.
Expand Down Expand Up @@ -72,10 +75,13 @@ type Component struct {

seedAddrs string

httpLn net.Listener
httpLn net.Listener
grpcLn net.Listener

ms tmstore.MirrorStore
fs tmstore.FinalizationStore
httpServer *gsi.HTTPServer
grpcServer *ggrpc.GordianGRPC
}

// NewComponent returns a new server component
Expand Down Expand Up @@ -157,7 +163,7 @@ func (c *Component) Start(ctx context.Context) error {

am := *(c.app.GetAppManager())

txm := gsi.TxManager{AppManager: am}
txm := txmanager.TxManager{AppManager: am}
txBuf := gtxbuf.New(
ctx, c.log.With("d_sys", "tx_buffer"),
txm.AddTx, txm.TxDeleterFunc,
Expand Down Expand Up @@ -249,23 +255,32 @@ func (c *Component) Start(ctx context.Context) error {
Handler: e,
})

if c.httpLn != nil {
c.httpServer = gsi.NewHTTPServer(ctx, c.log.With("sys", "http"), gsi.HTTPServerConfig{
Listener: c.httpLn,
if c.grpcLn != nil {
c.grpcServer = ggrpc.NewGordianGRPCServer(ctx, c.log.With("sys", "grpc"), ggrpc.GRPCServerConfig{
Listener: c.grpcLn,

MirrorStore: c.ms,
FinalizationStore: c.fs,
MirrorStore: c.ms,

CryptoRegistry: reg,

Libp2pHost: c.h,
Libp2pconn: c.conn,

AppManager: am,
// debug:
TxCodec: c.txc,
AppManager: am,
TxBuf: txBuf,
Codec: c.codec,
})
}

TxBuffer: txBuf,
if c.httpLn != nil {
gRPCClient, err := grpc.DialContext(ctx, c.grpcLn.Addr().String(), grpc.WithInsecure())
if err != nil {
return fmt.Errorf("failed to dial gRPC server: %w", err)
}

c.httpServer = gsi.NewHTTPServer(ctx, c.log.With("sys", "http"), gsi.HTTPServerConfig{
Listener: c.httpLn,
GordianGRPC: ggrpc.NewGordianGRPCClient(gRPCClient),
})
}

Expand Down Expand Up @@ -305,6 +320,20 @@ func (c *Component) Stop(_ context.Context) error {
c.httpServer.Wait()
}
}
if c.grpcLn != nil {
if err := c.grpcLn.Close(); err != nil {
// If the GRPC server is closed directly,
// it will close the underlying listener,
// which will probably happen before our call to close the listener here.
// Don't log if the error already indicated the network connection was closed.
if !errors.Is(err, net.ErrClosed) {
c.log.Warn("Error closing gRPC listener", "err", err)
}
}
if c.grpcServer != nil {
c.grpcServer.Wait()
}
}
return nil
}

Expand All @@ -324,15 +353,17 @@ func (c *Component) Init(app serverv2.AppI[transaction.Tx], v *viper.Viper, log
return fmt.Errorf("failed to listen for HTTP on %q: %w", httpAddr, err)
}

if f := v.GetString(httpAddrFileFlag); f != "" {
// TODO: we should probably track this file and delete it on shutdown.
addr := ln.Addr().String() + "\n"
if err := os.WriteFile(f, []byte(addr), 0600); err != nil {
return fmt.Errorf("failed to write HTTP address to file %q: %w", f, err)
}
c.httpLn = ln
}

// Maybe set up the GRPC server.
if grpcAddrFlag := v.GetString(grpcAddrFlag); grpcAddrFlag != "" {
ln, err := net.Listen("tcp", grpcAddrFlag)
if err != nil {
return fmt.Errorf("failed to listen for GRPC on %q: %w", grpcAddrFlag, err)
}

c.httpLn = ln
c.grpcLn = ln
}

c.seedAddrs = v.GetString(seedAddrsFlag)
Expand Down Expand Up @@ -406,6 +437,7 @@ func (c *Component) Init(app serverv2.AppI[transaction.Tx], v *viper.Viper, log

const (
httpAddrFlag = "g-http-addr"
grpcAddrFlag = "g-grpc-addr"
httpAddrFileFlag = "g-http-addr-file"

seedAddrsFlag = "g-seed-addrs"
Expand All @@ -415,6 +447,7 @@ func (c *Component) StartCmdFlags() *pflag.FlagSet {
flags := pflag.NewFlagSet("gserver", pflag.ExitOnError)

flags.String(httpAddrFlag, "", "TCP address of Gordian's introspective HTTP server; if blank, server will not be started")
flags.String(grpcAddrFlag, "", "GRPC address of Gordian's introspective GRPC server; if blank, server will not be started")
flags.String(httpAddrFileFlag, "", "Write the actual Gordian HTTP listen address to the given file (useful for tests when configured to listen on :0)")

flags.String(seedAddrsFlag, "", "Newline-separated multiaddrs to connect to; if omitted, relies on incoming connections to discover peers")
Expand Down
Loading
Loading