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.

241 lines
5.5 KiB

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