github.com/project-88388/tendermint-v0.34.14-terra.2@v1.0.0/proxy/client.go (about)

     1  package proxy
     2  
     3  import (
     4  	"fmt"
     5  
     6  	abcicli "github.com/tendermint/tendermint/abci/client"
     7  	"github.com/tendermint/tendermint/abci/example/counter"
     8  	"github.com/tendermint/tendermint/abci/example/kvstore"
     9  	"github.com/tendermint/tendermint/abci/types"
    10  	tmsync "github.com/tendermint/tendermint/libs/sync"
    11  	e2e "github.com/tendermint/tendermint/test/e2e/app"
    12  )
    13  
    14  // ClientCreator creates new ABCI clients.
    15  type ClientCreator interface {
    16  	// NewABCIClient returns a new ABCI client.
    17  	NewABCIClient() (abcicli.Client, error)
    18  }
    19  
    20  //----------------------------------------------------
    21  // local proxy uses a mutex on an in-proc app
    22  
    23  type localClientCreator struct {
    24  	mtx *tmsync.Mutex
    25  	app types.Application
    26  }
    27  
    28  // NewLocalClientCreator returns a ClientCreator for the given app,
    29  // which will be running locally.
    30  func NewLocalClientCreator(app types.Application) ClientCreator {
    31  	return &localClientCreator{
    32  		mtx: new(tmsync.Mutex),
    33  		app: app,
    34  	}
    35  }
    36  
    37  func (l *localClientCreator) NewABCIClient() (abcicli.Client, error) {
    38  	return abcicli.NewLocalClient(l.mtx, l.app), nil
    39  }
    40  
    41  //---------------------------------------------------------------
    42  // remote proxy opens new connections to an external app process
    43  
    44  type remoteClientCreator struct {
    45  	addr        string
    46  	transport   string
    47  	mustConnect bool
    48  }
    49  
    50  // NewRemoteClientCreator returns a ClientCreator for the given address (e.g.
    51  // "192.168.0.1") and transport (e.g. "tcp"). Set mustConnect to true if you
    52  // want the client to connect before reporting success.
    53  func NewRemoteClientCreator(addr, transport string, mustConnect bool) ClientCreator {
    54  	return &remoteClientCreator{
    55  		addr:        addr,
    56  		transport:   transport,
    57  		mustConnect: mustConnect,
    58  	}
    59  }
    60  
    61  func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) {
    62  	remoteApp, err := abcicli.NewClient(r.addr, r.transport, r.mustConnect)
    63  	if err != nil {
    64  		return nil, fmt.Errorf("failed to connect to proxy: %w", err)
    65  	}
    66  
    67  	return remoteApp, nil
    68  }
    69  
    70  // DefaultClientCreator returns a default ClientCreator, which will create a
    71  // local client if addr is one of: 'counter', 'counter_serial', 'kvstore',
    72  // 'persistent_kvstore' or 'noop', otherwise - a remote client.
    73  func DefaultClientCreator(addr, transport, dbDir string) ClientCreator {
    74  	switch addr {
    75  	case "counter":
    76  		return NewLocalClientCreator(counter.NewApplication(false))
    77  	case "counter_serial":
    78  		return NewLocalClientCreator(counter.NewApplication(true))
    79  	case "kvstore":
    80  		return NewLocalClientCreator(kvstore.NewApplication())
    81  	case "persistent_kvstore":
    82  		return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir))
    83  	case "e2e":
    84  		app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir))
    85  		if err != nil {
    86  			panic(err)
    87  		}
    88  		return NewLocalClientCreator(app)
    89  	case "noop":
    90  		return NewLocalClientCreator(types.NewBaseApplication())
    91  	default:
    92  		mustConnect := false // loop retrying
    93  		return NewRemoteClientCreator(addr, transport, mustConnect)
    94  	}
    95  }