github.com/line/ostracon@v1.0.10-0.20230328032236-7f20145f065d/abci/client/local_client.go (about)

     1  package abcicli
     2  
     3  import (
     4  	"github.com/tendermint/tendermint/abci/types"
     5  
     6  	ocabci "github.com/line/ostracon/abci/types"
     7  	"github.com/line/ostracon/libs/service"
     8  	tmsync "github.com/line/ostracon/libs/sync"
     9  )
    10  
    11  var _ Client = (*localClient)(nil)
    12  
    13  // NOTE: use defer to unlock mutex because Application might panic (e.g., in
    14  // case of malicious tx or query). It only makes sense for publicly exposed
    15  // methods like CheckTx (/broadcast_tx_* RPC endpoint) or Query (/abci_query
    16  // RPC endpoint), but defers are used everywhere for the sake of consistency.
    17  type localClient struct {
    18  	service.BaseService
    19  
    20  	// TODO: remove `mtx` to increase concurrency. We could remove it because the app should protect itself.
    21  	mtx *tmsync.Mutex
    22  	// CONTRACT: The application should protect itself from concurrency as an abci server.
    23  	ocabci.Application
    24  
    25  	globalCbMtx tmsync.Mutex
    26  	globalCb    GlobalCallback
    27  }
    28  
    29  var _ Client = (*localClient)(nil)
    30  
    31  // NewLocalClient creates a local client, which will be directly calling the
    32  // methods of the given app.
    33  //
    34  // Both Async and Sync methods ignore the given context.Context parameter.
    35  func NewLocalClient(mtx *tmsync.Mutex, app ocabci.Application) Client {
    36  	if mtx == nil {
    37  		mtx = new(tmsync.Mutex)
    38  	}
    39  	cli := &localClient{
    40  		mtx:         mtx,
    41  		Application: app,
    42  	}
    43  	cli.BaseService = *service.NewBaseService(nil, "localClient", cli)
    44  	return cli
    45  }
    46  
    47  func (app *localClient) SetGlobalCallback(globalCb GlobalCallback) {
    48  	app.globalCbMtx.Lock()
    49  	defer app.globalCbMtx.Unlock()
    50  	app.globalCb = globalCb
    51  }
    52  
    53  func (app *localClient) GetGlobalCallback() (cb GlobalCallback) {
    54  	app.globalCbMtx.Lock()
    55  	defer app.globalCbMtx.Unlock()
    56  	cb = app.globalCb
    57  	return cb
    58  }
    59  
    60  // TODO: change abci.Application to include Error()?
    61  func (app *localClient) Error() error {
    62  	return nil
    63  }
    64  
    65  func (app *localClient) FlushAsync(cb ResponseCallback) *ReqRes {
    66  	// Do nothing
    67  	reqRes := NewReqRes(ocabci.ToRequestFlush(), cb)
    68  	return app.done(reqRes, ocabci.ToResponseFlush())
    69  }
    70  
    71  func (app *localClient) EchoAsync(msg string, cb ResponseCallback) *ReqRes {
    72  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
    73  	// app.mtx.Lock()
    74  	// defer app.mtx.Unlock()
    75  
    76  	reqRes := NewReqRes(ocabci.ToRequestEcho(msg), cb)
    77  	return app.done(reqRes, ocabci.ToResponseEcho(msg))
    78  }
    79  
    80  func (app *localClient) InfoAsync(req types.RequestInfo, cb ResponseCallback) *ReqRes {
    81  	app.mtx.Lock()
    82  	defer app.mtx.Unlock()
    83  
    84  	reqRes := NewReqRes(ocabci.ToRequestInfo(req), cb)
    85  	res := app.Application.Info(req)
    86  	return app.done(reqRes, ocabci.ToResponseInfo(res))
    87  }
    88  
    89  func (app *localClient) SetOptionAsync(req types.RequestSetOption, cb ResponseCallback) *ReqRes {
    90  	app.mtx.Lock()
    91  	defer app.mtx.Unlock()
    92  
    93  	reqRes := NewReqRes(ocabci.ToRequestSetOption(req), cb)
    94  	res := app.Application.SetOption(req)
    95  	return app.done(reqRes, ocabci.ToResponseSetOption(res))
    96  }
    97  
    98  func (app *localClient) DeliverTxAsync(req types.RequestDeliverTx, cb ResponseCallback) *ReqRes {
    99  	app.mtx.Lock()
   100  	defer app.mtx.Unlock()
   101  
   102  	reqRes := NewReqRes(ocabci.ToRequestDeliverTx(req), cb)
   103  	res := app.Application.DeliverTx(req)
   104  	return app.done(reqRes, ocabci.ToResponseDeliverTx(res))
   105  }
   106  
   107  func (app *localClient) CheckTxAsync(req types.RequestCheckTx, cb ResponseCallback) *ReqRes {
   108  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   109  	// app.mtx.Lock()
   110  	// defer app.mtx.Unlock()
   111  
   112  	reqRes := NewReqRes(ocabci.ToRequestCheckTx(req), cb)
   113  
   114  	app.Application.CheckTxAsync(req, func(r ocabci.ResponseCheckTx) {
   115  		res := ocabci.ToResponseCheckTx(r)
   116  		app.done(reqRes, res)
   117  	})
   118  
   119  	return reqRes
   120  }
   121  
   122  func (app *localClient) QueryAsync(req types.RequestQuery, cb ResponseCallback) *ReqRes {
   123  	app.mtx.Lock()
   124  	defer app.mtx.Unlock()
   125  
   126  	reqRes := NewReqRes(ocabci.ToRequestQuery(req), cb)
   127  	res := app.Application.Query(req)
   128  	return app.done(reqRes, ocabci.ToResponseQuery(res))
   129  }
   130  
   131  func (app *localClient) CommitAsync(cb ResponseCallback) *ReqRes {
   132  	app.mtx.Lock()
   133  	defer app.mtx.Unlock()
   134  
   135  	reqRes := NewReqRes(ocabci.ToRequestCommit(), cb)
   136  	res := app.Application.Commit()
   137  	return app.done(reqRes, ocabci.ToResponseCommit(res))
   138  }
   139  
   140  func (app *localClient) InitChainAsync(req types.RequestInitChain, cb ResponseCallback) *ReqRes {
   141  	app.mtx.Lock()
   142  	defer app.mtx.Unlock()
   143  
   144  	reqRes := NewReqRes(ocabci.ToRequestInitChain(req), cb)
   145  	res := app.Application.InitChain(req)
   146  	return app.done(reqRes, ocabci.ToResponseInitChain(res))
   147  }
   148  
   149  func (app *localClient) BeginBlockAsync(req ocabci.RequestBeginBlock, cb ResponseCallback) *ReqRes {
   150  	app.mtx.Lock()
   151  	defer app.mtx.Unlock()
   152  
   153  	reqRes := NewReqRes(ocabci.ToRequestBeginBlock(req), cb)
   154  	res := app.Application.BeginBlock(req)
   155  	return app.done(reqRes, ocabci.ToResponseBeginBlock(res))
   156  }
   157  
   158  func (app *localClient) EndBlockAsync(req types.RequestEndBlock, cb ResponseCallback) *ReqRes {
   159  	app.mtx.Lock()
   160  	defer app.mtx.Unlock()
   161  
   162  	reqRes := NewReqRes(ocabci.ToRequestEndBlock(req), cb)
   163  	res := app.Application.EndBlock(req)
   164  	return app.done(reqRes, ocabci.ToResponseEndBlock(res))
   165  }
   166  
   167  func (app *localClient) BeginRecheckTxAsync(req ocabci.RequestBeginRecheckTx, cb ResponseCallback) *ReqRes {
   168  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   169  	// app.mtx.Lock()
   170  	// defer app.mtx.Unlock()
   171  
   172  	reqRes := NewReqRes(ocabci.ToRequestBeginRecheckTx(req), cb)
   173  	res := app.Application.BeginRecheckTx(req)
   174  	return app.done(reqRes, ocabci.ToResponseBeginRecheckTx(res))
   175  }
   176  
   177  func (app *localClient) EndRecheckTxAsync(req ocabci.RequestEndRecheckTx, cb ResponseCallback) *ReqRes {
   178  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   179  	// app.mtx.Lock()
   180  	// defer app.mtx.Unlock()
   181  
   182  	reqRes := NewReqRes(ocabci.ToRequestEndRecheckTx(req), cb)
   183  	res := app.Application.EndRecheckTx(req)
   184  	return app.done(reqRes, ocabci.ToResponseEndRecheckTx(res))
   185  }
   186  
   187  func (app *localClient) ListSnapshotsAsync(req types.RequestListSnapshots, cb ResponseCallback) *ReqRes {
   188  	app.mtx.Lock()
   189  	defer app.mtx.Unlock()
   190  
   191  	reqRes := NewReqRes(ocabci.ToRequestListSnapshots(req), cb)
   192  	res := app.Application.ListSnapshots(req)
   193  	return app.done(reqRes, ocabci.ToResponseListSnapshots(res))
   194  }
   195  
   196  func (app *localClient) OfferSnapshotAsync(req types.RequestOfferSnapshot, cb ResponseCallback) *ReqRes {
   197  	app.mtx.Lock()
   198  	defer app.mtx.Unlock()
   199  
   200  	reqRes := NewReqRes(ocabci.ToRequestOfferSnapshot(req), cb)
   201  	res := app.Application.OfferSnapshot(req)
   202  	return app.done(reqRes, ocabci.ToResponseOfferSnapshot(res))
   203  }
   204  
   205  func (app *localClient) LoadSnapshotChunkAsync(req types.RequestLoadSnapshotChunk, cb ResponseCallback) *ReqRes {
   206  	app.mtx.Lock()
   207  	defer app.mtx.Unlock()
   208  
   209  	reqRes := NewReqRes(ocabci.ToRequestLoadSnapshotChunk(req), cb)
   210  	res := app.Application.LoadSnapshotChunk(req)
   211  	return app.done(reqRes, ocabci.ToResponseLoadSnapshotChunk(res))
   212  }
   213  
   214  func (app *localClient) ApplySnapshotChunkAsync(req types.RequestApplySnapshotChunk, cb ResponseCallback) *ReqRes {
   215  	app.mtx.Lock()
   216  	defer app.mtx.Unlock()
   217  
   218  	reqRes := NewReqRes(ocabci.ToRequestApplySnapshotChunk(req), cb)
   219  	res := app.Application.ApplySnapshotChunk(req)
   220  	return app.done(reqRes, ocabci.ToResponseApplySnapshotChunk(res))
   221  }
   222  
   223  // -------------------------------------------------------
   224  func (app *localClient) FlushSync() (*types.ResponseFlush, error) {
   225  	return &types.ResponseFlush{}, nil
   226  }
   227  
   228  func (app *localClient) EchoSync(msg string) (*types.ResponseEcho, error) {
   229  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   230  	// app.mtx.Lock()
   231  	// defer app.mtx.Unlock()
   232  
   233  	return &types.ResponseEcho{Message: msg}, nil
   234  }
   235  
   236  func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) {
   237  	app.mtx.Lock()
   238  	defer app.mtx.Unlock()
   239  
   240  	res := app.Application.Info(req)
   241  	return &res, nil
   242  }
   243  
   244  func (app *localClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) {
   245  	app.mtx.Lock()
   246  	defer app.mtx.Unlock()
   247  
   248  	res := app.Application.SetOption(req)
   249  	return &res, nil
   250  }
   251  
   252  func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
   253  	app.mtx.Lock()
   254  	defer app.mtx.Unlock()
   255  
   256  	res := app.Application.DeliverTx(req)
   257  	return &res, nil
   258  }
   259  
   260  func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*ocabci.ResponseCheckTx, error) {
   261  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   262  	// app.mtx.Lock()
   263  	// defer app.mtx.Unlock()
   264  
   265  	res := app.Application.CheckTxSync(req)
   266  	return &res, nil
   267  }
   268  
   269  func (app *localClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) {
   270  	app.mtx.Lock()
   271  	defer app.mtx.Unlock()
   272  
   273  	res := app.Application.Query(req)
   274  	return &res, nil
   275  }
   276  
   277  func (app *localClient) CommitSync() (*types.ResponseCommit, error) {
   278  	app.mtx.Lock()
   279  	defer app.mtx.Unlock()
   280  
   281  	res := app.Application.Commit()
   282  	return &res, nil
   283  }
   284  
   285  func (app *localClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) {
   286  	app.mtx.Lock()
   287  	defer app.mtx.Unlock()
   288  
   289  	res := app.Application.InitChain(req)
   290  	return &res, nil
   291  }
   292  
   293  func (app *localClient) BeginBlockSync(req ocabci.RequestBeginBlock) (*types.ResponseBeginBlock, error) {
   294  	app.mtx.Lock()
   295  	defer app.mtx.Unlock()
   296  
   297  	res := app.Application.BeginBlock(req)
   298  	return &res, nil
   299  }
   300  
   301  func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) {
   302  	app.mtx.Lock()
   303  	defer app.mtx.Unlock()
   304  
   305  	res := app.Application.EndBlock(req)
   306  	return &res, nil
   307  }
   308  
   309  func (app *localClient) BeginRecheckTxSync(req ocabci.RequestBeginRecheckTx) (*ocabci.ResponseBeginRecheckTx, error) {
   310  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   311  	// app.mtx.Lock()
   312  	// defer app.mtx.Unlock()
   313  
   314  	res := app.Application.BeginRecheckTx(req)
   315  	return &res, nil
   316  }
   317  
   318  func (app *localClient) EndRecheckTxSync(req ocabci.RequestEndRecheckTx) (*ocabci.ResponseEndRecheckTx, error) {
   319  	// NOTE: commented out for performance. delete all after commenting out all `app.mtx`
   320  	// app.mtx.Lock()
   321  	// defer app.mtx.Unlock()
   322  
   323  	res := app.Application.EndRecheckTx(req)
   324  	return &res, nil
   325  }
   326  
   327  func (app *localClient) ListSnapshotsSync(req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) {
   328  	app.mtx.Lock()
   329  	defer app.mtx.Unlock()
   330  
   331  	res := app.Application.ListSnapshots(req)
   332  	return &res, nil
   333  }
   334  
   335  func (app *localClient) OfferSnapshotSync(req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) {
   336  	app.mtx.Lock()
   337  	defer app.mtx.Unlock()
   338  
   339  	res := app.Application.OfferSnapshot(req)
   340  	return &res, nil
   341  }
   342  
   343  func (app *localClient) LoadSnapshotChunkSync(
   344  	req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) {
   345  	app.mtx.Lock()
   346  	defer app.mtx.Unlock()
   347  
   348  	res := app.Application.LoadSnapshotChunk(req)
   349  	return &res, nil
   350  }
   351  
   352  func (app *localClient) ApplySnapshotChunkSync(
   353  	req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) {
   354  	app.mtx.Lock()
   355  	defer app.mtx.Unlock()
   356  
   357  	res := app.Application.ApplySnapshotChunk(req)
   358  	return &res, nil
   359  }
   360  
   361  //-------------------------------------------------------
   362  
   363  func (app *localClient) done(reqRes *ReqRes, res *ocabci.Response) *ReqRes {
   364  	set := reqRes.SetDone(res)
   365  	if set {
   366  		if globalCb := app.GetGlobalCallback(); globalCb != nil {
   367  			globalCb(reqRes.Request, res)
   368  		}
   369  	}
   370  	return reqRes
   371  }