You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
5.4 KiB

  1. package tmspcli
  2. import (
  3. types "github.com/tendermint/tmsp/types"
  4. "sync"
  5. )
  6. type localClient struct {
  7. mtx *sync.Mutex
  8. types.Application
  9. Callback
  10. }
  11. func NewLocalClient(mtx *sync.Mutex, app types.Application) *localClient {
  12. if mtx == nil {
  13. mtx = new(sync.Mutex)
  14. }
  15. return &localClient{
  16. mtx: mtx,
  17. Application: app,
  18. }
  19. }
  20. func (app *localClient) SetResponseCallback(cb Callback) {
  21. app.mtx.Lock()
  22. defer app.mtx.Unlock()
  23. app.Callback = cb
  24. }
  25. // TODO: change types.Application to include Error()?
  26. func (app *localClient) Error() error {
  27. return nil
  28. }
  29. func (app *localClient) Stop() bool {
  30. return true
  31. }
  32. func (app *localClient) FlushAsync() *ReqRes {
  33. // Do nothing
  34. return newLocalReqRes(types.ToRequestFlush(), nil)
  35. }
  36. func (app *localClient) EchoAsync(msg string) *ReqRes {
  37. return app.callback(
  38. types.ToRequestEcho(msg),
  39. types.ToResponseEcho(msg),
  40. )
  41. }
  42. func (app *localClient) InfoAsync() *ReqRes {
  43. app.mtx.Lock()
  44. info := app.Application.Info()
  45. app.mtx.Unlock()
  46. return app.callback(
  47. types.ToRequestInfo(),
  48. types.ToResponseInfo(info),
  49. )
  50. }
  51. func (app *localClient) SetOptionAsync(key string, value string) *ReqRes {
  52. app.mtx.Lock()
  53. log := app.Application.SetOption(key, value)
  54. app.mtx.Unlock()
  55. return app.callback(
  56. types.ToRequestSetOption(key, value),
  57. types.ToResponseSetOption(log),
  58. )
  59. }
  60. func (app *localClient) AppendTxAsync(tx []byte) *ReqRes {
  61. app.mtx.Lock()
  62. res := app.Application.AppendTx(tx)
  63. app.mtx.Unlock()
  64. return app.callback(
  65. types.ToRequestAppendTx(tx),
  66. types.ToResponseAppendTx(res.Code, res.Data, res.Log),
  67. )
  68. }
  69. func (app *localClient) CheckTxAsync(tx []byte) *ReqRes {
  70. app.mtx.Lock()
  71. res := app.Application.CheckTx(tx)
  72. app.mtx.Unlock()
  73. return app.callback(
  74. types.ToRequestCheckTx(tx),
  75. types.ToResponseCheckTx(res.Code, res.Data, res.Log),
  76. )
  77. }
  78. func (app *localClient) QueryAsync(tx []byte) *ReqRes {
  79. app.mtx.Lock()
  80. res := app.Application.Query(tx)
  81. app.mtx.Unlock()
  82. return app.callback(
  83. types.ToRequestQuery(tx),
  84. types.ToResponseQuery(res.Code, res.Data, res.Log),
  85. )
  86. }
  87. func (app *localClient) CommitAsync() *ReqRes {
  88. app.mtx.Lock()
  89. res := app.Application.Commit()
  90. app.mtx.Unlock()
  91. return app.callback(
  92. types.ToRequestCommit(),
  93. types.ToResponseCommit(res.Code, res.Data, res.Log),
  94. )
  95. }
  96. func (app *localClient) InitChainAsync(validators []*types.Validator) *ReqRes {
  97. app.mtx.Lock()
  98. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  99. bcApp.InitChain(validators)
  100. }
  101. reqRes := app.callback(
  102. types.ToRequestInitChain(validators),
  103. types.ToResponseInitChain(),
  104. )
  105. app.mtx.Unlock()
  106. return reqRes
  107. }
  108. func (app *localClient) BeginBlockAsync(height uint64) *ReqRes {
  109. app.mtx.Lock()
  110. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  111. bcApp.BeginBlock(height)
  112. }
  113. app.mtx.Unlock()
  114. return app.callback(
  115. types.ToRequestBeginBlock(height),
  116. types.ToResponseBeginBlock(),
  117. )
  118. }
  119. func (app *localClient) EndBlockAsync(height uint64) *ReqRes {
  120. app.mtx.Lock()
  121. var validators []*types.Validator
  122. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  123. validators = bcApp.EndBlock(height)
  124. }
  125. app.mtx.Unlock()
  126. return app.callback(
  127. types.ToRequestEndBlock(height),
  128. types.ToResponseEndBlock(validators),
  129. )
  130. }
  131. //-------------------------------------------------------
  132. func (app *localClient) FlushSync() error {
  133. return nil
  134. }
  135. func (app *localClient) EchoSync(msg string) (res types.Result) {
  136. return types.OK.SetData([]byte(msg))
  137. }
  138. func (app *localClient) InfoSync() (res types.Result) {
  139. app.mtx.Lock()
  140. info := app.Application.Info()
  141. app.mtx.Unlock()
  142. return types.OK.SetData([]byte(info))
  143. }
  144. func (app *localClient) SetOptionSync(key string, value string) (res types.Result) {
  145. app.mtx.Lock()
  146. log := app.Application.SetOption(key, value)
  147. app.mtx.Unlock()
  148. return types.OK.SetLog(log)
  149. }
  150. func (app *localClient) AppendTxSync(tx []byte) (res types.Result) {
  151. app.mtx.Lock()
  152. res = app.Application.AppendTx(tx)
  153. app.mtx.Unlock()
  154. return res
  155. }
  156. func (app *localClient) CheckTxSync(tx []byte) (res types.Result) {
  157. app.mtx.Lock()
  158. res = app.Application.CheckTx(tx)
  159. app.mtx.Unlock()
  160. return res
  161. }
  162. func (app *localClient) QuerySync(query []byte) (res types.Result) {
  163. app.mtx.Lock()
  164. res = app.Application.Query(query)
  165. app.mtx.Unlock()
  166. return res
  167. }
  168. func (app *localClient) CommitSync() (res types.Result) {
  169. app.mtx.Lock()
  170. res = app.Application.Commit()
  171. app.mtx.Unlock()
  172. return res
  173. }
  174. func (app *localClient) InitChainSync(validators []*types.Validator) (err error) {
  175. app.mtx.Lock()
  176. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  177. bcApp.InitChain(validators)
  178. }
  179. app.mtx.Unlock()
  180. return nil
  181. }
  182. func (app *localClient) BeginBlockSync(height uint64) (err error) {
  183. app.mtx.Lock()
  184. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  185. bcApp.BeginBlock(height)
  186. }
  187. app.mtx.Unlock()
  188. return nil
  189. }
  190. func (app *localClient) EndBlockSync(height uint64) (changedValidators []*types.Validator, err error) {
  191. app.mtx.Lock()
  192. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  193. changedValidators = bcApp.EndBlock(height)
  194. }
  195. app.mtx.Unlock()
  196. return changedValidators, nil
  197. }
  198. //-------------------------------------------------------
  199. func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes {
  200. app.Callback(req, res)
  201. return newLocalReqRes(req, res)
  202. }
  203. func newLocalReqRes(req *types.Request, res *types.Response) *ReqRes {
  204. reqRes := NewReqRes(req)
  205. reqRes.Response = res
  206. reqRes.SetDone()
  207. return reqRes
  208. }