package proxy import ( "fmt" "sync" abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/example/counter" "github.com/tendermint/tendermint/abci/example/kvstore" "github.com/tendermint/tendermint/abci/types" ) // NewABCIClient returns newly connected client type ClientCreator interface { NewABCIClient() (abcicli.Client, error) } //---------------------------------------------------- // local proxy uses a mutex on an in-proc app type localClientCreator struct { mtx *sync.Mutex app types.Application } func NewLocalClientCreator(app types.Application) ClientCreator { return &localClientCreator{ mtx: new(sync.Mutex), app: app, } } func (l *localClientCreator) NewABCIClient() (abcicli.Client, error) { return abcicli.NewLocalClient(l.mtx, l.app), nil } //--------------------------------------------------------------- // remote proxy opens new connections to an external app process type remoteClientCreator struct { addr string transport string mustConnect bool } func NewRemoteClientCreator(addr, transport string, mustConnect bool) ClientCreator { return &remoteClientCreator{ addr: addr, transport: transport, mustConnect: mustConnect, } } func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) { remoteApp, err := abcicli.NewClient(r.addr, r.transport, r.mustConnect) if err != nil { return nil, fmt.Errorf("failed to connect to proxy: %w", err) } return remoteApp, nil } //----------------------------------------------------------------- // default func DefaultClientCreator(addr, transport, dbDir string) ClientCreator { switch addr { case "counter": return NewLocalClientCreator(counter.NewApplication(false)) case "counter_serial": return NewLocalClientCreator(counter.NewApplication(true)) case "kvstore": return NewLocalClientCreator(kvstore.NewApplication()) case "persistent_kvstore": return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir)) case "noop": return NewLocalClientCreator(types.NewBaseApplication()) default: mustConnect := false // loop retrying return NewRemoteClientCreator(addr, transport, mustConnect) } }