Skip to content

Commit

Permalink
refactor(tm2): make rpc client not depend on goleveldb (#1603)
Browse files Browse the repository at this point in the history
![image](https://github.com/gnolang/gno/assets/4681308/761f1109-3e0d-4846-b331-3c60b6e803c0)


![image](https://github.com/gnolang/gno/assets/4681308/312b9226-49fa-48ac-b280-f4d704a341df)

The PR depends on #1602 but it's good for review. For ease of reviewing
I put that PR's branch as the base branch; once it is merged I will
rebase on master.

A bunch of changes to get there:

- Split `proxy` into `appconn` and `proxy`. `proxy` has a dependency on
`kvstore`, which then depends on pkg/db and goleveldb.
- Tools for inspecting dependency chains:
- `go list -f '{{ join .Deps "\n" }}'
github.com/gnolang/gno/tm2/your/pkg`
  - [`depth`](https://github.com/KyleBanks/depth)

The original point of the PR was to not include an entire key-store
database as part of `cmd/gno`, but really the better side-effect is that
the dependency is no longer in the rpc package. Sadly, `gnoclient` still
imports `goleveldb`, but I'll leave understanding why that is the case
for another refactor-investigation :)
  • Loading branch information
thehowl committed Mar 1, 2024
1 parent eb44d42 commit 6c5b4cf
Show file tree
Hide file tree
Showing 24 changed files with 325 additions and 287 deletions.
3 changes: 1 addition & 2 deletions contribs/gnodev/pkg/dev/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,12 @@ func NewDevNode(ctx context.Context, logger *slog.Logger, emitter emitter.Emitte
if err != nil {
return nil, fmt.Errorf("unable to initialize the node: %w", err)
}
client := client.NewLocal(node)

return &Node{
Node: node,

emitter: emitter,
client: client,
client: client.NewLocal(),
pkgs: mpkgs,
logger: logger,
loadedPackages: len(pkgsTxs),
Expand Down
2 changes: 0 additions & 2 deletions contribs/gnokeykc/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ require (
)

require (
dario.cat/mergo v1.0.0 // indirect
github.com/alessio/shellescape v1.4.1 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
github.com/btcsuite/btcd/btcutil v1.1.3 // indirect
Expand All @@ -31,7 +30,6 @@ require (
github.com/peterbourgon/ff/v3 v3.4.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/cors v1.10.1 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
Expand Down
65 changes: 33 additions & 32 deletions tm2/pkg/bft/proxy/app_conn.go → tm2/pkg/bft/appconn/app_conn.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package proxy
// Package appconn manages the connection of Tendermint to the application layer.
package appconn

import (
abcicli "github.com/gnolang/gno/tm2/pkg/bft/abci/client"
Expand All @@ -8,7 +9,7 @@ import (
//----------------------------------------------------------------------------------------
// Enforce which abci msgs can be sent on a connection at the type level

type AppConnConsensus interface {
type Consensus interface {
SetResponseCallback(abcicli.Callback)
Error() error

Expand All @@ -20,7 +21,7 @@ type AppConnConsensus interface {
CommitSync() (abci.ResponseCommit, error)
}

type AppConnMempool interface {
type Mempool interface {
SetResponseCallback(abcicli.Callback)
Error() error

Expand All @@ -30,7 +31,7 @@ type AppConnMempool interface {
FlushSync() error
}

type AppConnQuery interface {
type Query interface {
Error() error

EchoSync(string) (abci.ResponseEcho, error)
Expand All @@ -41,104 +42,104 @@ type AppConnQuery interface {
}

//-----------------------------------------------------------------------------------------
// Implements AppConnConsensus (subset of abcicli.Client)
// Implements Consensus (subset of abcicli.Client)

type appConnConsensus struct {
type consensus struct {
appConn abcicli.Client
}

func NewAppConnConsensus(appConn abcicli.Client) *appConnConsensus {
return &appConnConsensus{
func NewConsensus(appConn abcicli.Client) *consensus {
return &consensus{
appConn: appConn,
}
}

func (app *appConnConsensus) SetResponseCallback(cb abcicli.Callback) {
func (app *consensus) SetResponseCallback(cb abcicli.Callback) {
app.appConn.SetResponseCallback(cb)
}

func (app *appConnConsensus) Error() error {
func (app *consensus) Error() error {
return app.appConn.Error()
}

func (app *appConnConsensus) InitChainSync(req abci.RequestInitChain) (abci.ResponseInitChain, error) {
func (app *consensus) InitChainSync(req abci.RequestInitChain) (abci.ResponseInitChain, error) {
return app.appConn.InitChainSync(req)
}

func (app *appConnConsensus) BeginBlockSync(req abci.RequestBeginBlock) (abci.ResponseBeginBlock, error) {
func (app *consensus) BeginBlockSync(req abci.RequestBeginBlock) (abci.ResponseBeginBlock, error) {
return app.appConn.BeginBlockSync(req)
}

func (app *appConnConsensus) DeliverTxAsync(req abci.RequestDeliverTx) *abcicli.ReqRes {
func (app *consensus) DeliverTxAsync(req abci.RequestDeliverTx) *abcicli.ReqRes {
return app.appConn.DeliverTxAsync(req)
}

func (app *appConnConsensus) EndBlockSync(req abci.RequestEndBlock) (abci.ResponseEndBlock, error) {
func (app *consensus) EndBlockSync(req abci.RequestEndBlock) (abci.ResponseEndBlock, error) {
return app.appConn.EndBlockSync(req)
}

func (app *appConnConsensus) CommitSync() (abci.ResponseCommit, error) {
func (app *consensus) CommitSync() (abci.ResponseCommit, error) {
return app.appConn.CommitSync()
}

//------------------------------------------------
// Implements AppConnMempool (subset of abcicli.Client)
// Implements Mempool (subset of abcicli.Client)

type appConnMempool struct {
type mempool struct {
appConn abcicli.Client
}

func NewAppConnMempool(appConn abcicli.Client) *appConnMempool {
return &appConnMempool{
func NewMempool(appConn abcicli.Client) *mempool {
return &mempool{
appConn: appConn,
}
}

func (app *appConnMempool) SetResponseCallback(cb abcicli.Callback) {
func (app *mempool) SetResponseCallback(cb abcicli.Callback) {
app.appConn.SetResponseCallback(cb)
}

func (app *appConnMempool) Error() error {
func (app *mempool) Error() error {
return app.appConn.Error()
}

func (app *appConnMempool) FlushAsync() *abcicli.ReqRes {
func (app *mempool) FlushAsync() *abcicli.ReqRes {
return app.appConn.FlushAsync()
}

func (app *appConnMempool) FlushSync() error {
func (app *mempool) FlushSync() error {
return app.appConn.FlushSync()
}

func (app *appConnMempool) CheckTxAsync(req abci.RequestCheckTx) *abcicli.ReqRes {
func (app *mempool) CheckTxAsync(req abci.RequestCheckTx) *abcicli.ReqRes {
return app.appConn.CheckTxAsync(req)
}

//------------------------------------------------
// Implements AppConnQuery (subset of abcicli.Client)
// Implements Query (subset of abcicli.Client)

type appConnQuery struct {
type query struct {
appConn abcicli.Client
}

func NewAppConnQuery(appConn abcicli.Client) *appConnQuery {
return &appConnQuery{
func NewQuery(appConn abcicli.Client) *query {
return &query{
appConn: appConn,
}
}

func (app *appConnQuery) Error() error {
func (app *query) Error() error {
return app.appConn.Error()
}

func (app *appConnQuery) EchoSync(msg string) (abci.ResponseEcho, error) {
func (app *query) EchoSync(msg string) (abci.ResponseEcho, error) {
return app.appConn.EchoSync(msg)
}

func (app *appConnQuery) InfoSync(req abci.RequestInfo) (abci.ResponseInfo, error) {
func (app *query) InfoSync(req abci.RequestInfo) (abci.ResponseInfo, error) {
return app.appConn.InfoSync(req)
}

func (app *appConnQuery) QuerySync(reqQuery abci.RequestQuery) (abci.ResponseQuery, error) {
func (app *query) QuerySync(reqQuery abci.RequestQuery) (abci.ResponseQuery, error) {
return app.appConn.QuerySync(reqQuery)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package proxy
package appconn

import (
abcicli "github.com/gnolang/gno/tm2/pkg/bft/abci/client"
"github.com/gnolang/gno/tm2/pkg/errors"
"github.com/gnolang/gno/tm2/pkg/service"
)
Expand All @@ -11,56 +12,61 @@ import (
type AppConns interface {
service.Service

Mempool() AppConnMempool
Consensus() AppConnConsensus
Query() AppConnQuery
Mempool() Mempool
Consensus() Consensus
Query() Query
}

// NewABCIClient returns newly connected client
type ClientCreator interface {
NewABCIClient() (abcicli.Client, error)
}

func NewAppConns(clientCreator ClientCreator) AppConns {
return NewMultiAppConn(clientCreator)
return NewMulti(clientCreator)
}

//-----------------------------
// multiAppConn implements AppConns
// multi implements AppConns

// a multiAppConn is made of a few appConns (mempool, consensus, query)
// a multi is made of a few appConns (mempool, consensus, query)
// and manages their underlying abci clients
// TODO: on app restart, clients must reboot together
type multiAppConn struct {
type multi struct {
service.BaseService

mempoolConn *appConnMempool
consensusConn *appConnConsensus
queryConn *appConnQuery
mempoolConn *mempool
consensusConn *consensus
queryConn *query

clientCreator ClientCreator
}

// Make all necessary abci connections to the application
func NewMultiAppConn(clientCreator ClientCreator) *multiAppConn {
multiAppConn := &multiAppConn{
func NewMulti(clientCreator ClientCreator) *multi {
multi := &multi{
clientCreator: clientCreator,
}
multiAppConn.BaseService = *service.NewBaseService(nil, "multiAppConn", multiAppConn)
return multiAppConn
multi.BaseService = *service.NewBaseService(nil, "multi", multi)
return multi
}

// Returns the mempool connection
func (app *multiAppConn) Mempool() AppConnMempool {
func (app *multi) Mempool() Mempool {
return app.mempoolConn
}

// Returns the consensus Connection
func (app *multiAppConn) Consensus() AppConnConsensus {
func (app *multi) Consensus() Consensus {
return app.consensusConn
}

// Returns the query Connection
func (app *multiAppConn) Query() AppConnQuery {
func (app *multi) Query() Query {
return app.queryConn
}

func (app *multiAppConn) OnStart() error {
func (app *multi) OnStart() error {
// query connection
querycli, err := app.clientCreator.NewABCIClient()
if err != nil {
Expand All @@ -70,7 +76,7 @@ func (app *multiAppConn) OnStart() error {
if err := querycli.Start(); err != nil {
return errors.Wrap(err, "Error starting ABCI client (query connection)")
}
app.queryConn = NewAppConnQuery(querycli)
app.queryConn = NewQuery(querycli)

// mempool connection
memcli, err := app.clientCreator.NewABCIClient()
Expand All @@ -81,7 +87,7 @@ func (app *multiAppConn) OnStart() error {
if err := memcli.Start(); err != nil {
return errors.Wrap(err, "Error starting ABCI client (mempool connection)")
}
app.mempoolConn = NewAppConnMempool(memcli)
app.mempoolConn = NewMempool(memcli)

// consensus connection
concli, err := app.clientCreator.NewABCIClient()
Expand All @@ -92,7 +98,7 @@ func (app *multiAppConn) OnStart() error {
if err := concli.Start(); err != nil {
return errors.Wrap(err, "Error starting ABCI client (consensus connection)")
}
app.consensusConn = NewAppConnConsensus(concli)
app.consensusConn = NewConsensus(concli)

return nil
}
5 changes: 3 additions & 2 deletions tm2/pkg/bft/blockchain/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert"

abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
"github.com/gnolang/gno/tm2/pkg/bft/appconn"
cfg "github.com/gnolang/gno/tm2/pkg/bft/config"
"github.com/gnolang/gno/tm2/pkg/bft/mempool/mock"
"github.com/gnolang/gno/tm2/pkg/bft/proxy"
Expand Down Expand Up @@ -48,7 +49,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G

type BlockchainReactorPair struct {
reactor *BlockchainReactor
app proxy.AppConns
app appconn.AppConns
}

func newBlockchainReactor(logger *slog.Logger, genDoc *types.GenesisDoc, privVals []types.PrivValidator, maxBlockHeight int64) BlockchainReactorPair {
Expand All @@ -58,7 +59,7 @@ func newBlockchainReactor(logger *slog.Logger, genDoc *types.GenesisDoc, privVal

app := &testApp{}
cc := proxy.NewLocalClientCreator(app)
proxyApp := proxy.NewAppConns(cc)
proxyApp := appconn.NewAppConns(cc)
err := proxyApp.Start()
if err != nil {
panic(errors.Wrap(err, "error start app"))
Expand Down
Loading

0 comments on commit 6c5b4cf

Please sign in to comment.