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.

258 lines
6.0 KiB

8 years ago
8 years ago
  1. package abcicli
  2. import (
  3. "sync"
  4. . "github.com/tendermint/go-common"
  5. types "github.com/tendermint/abci/types"
  6. )
  7. type localClient struct {
  8. 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 = *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) ProofAsync(key []byte, blockHeight int64) *ReqRes {
  89. app.mtx.Lock()
  90. res := app.Application.Proof(key, blockHeight)
  91. app.mtx.Unlock()
  92. return app.callback(
  93. types.ToRequestProof(key, blockHeight),
  94. types.ToResponseQuery(res.Code, res.Data, res.Log),
  95. )
  96. }
  97. func (app *localClient) CommitAsync() *ReqRes {
  98. app.mtx.Lock()
  99. res := app.Application.Commit()
  100. app.mtx.Unlock()
  101. return app.callback(
  102. types.ToRequestCommit(),
  103. types.ToResponseCommit(res.Code, res.Data, res.Log),
  104. )
  105. }
  106. func (app *localClient) InitChainAsync(validators []*types.Validator) *ReqRes {
  107. app.mtx.Lock()
  108. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  109. bcApp.InitChain(validators)
  110. }
  111. reqRes := app.callback(
  112. types.ToRequestInitChain(validators),
  113. types.ToResponseInitChain(),
  114. )
  115. app.mtx.Unlock()
  116. return reqRes
  117. }
  118. func (app *localClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqRes {
  119. app.mtx.Lock()
  120. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  121. bcApp.BeginBlock(hash, header)
  122. }
  123. app.mtx.Unlock()
  124. return app.callback(
  125. types.ToRequestBeginBlock(hash, header),
  126. types.ToResponseBeginBlock(),
  127. )
  128. }
  129. func (app *localClient) EndBlockAsync(height uint64) *ReqRes {
  130. app.mtx.Lock()
  131. var resEndBlock types.ResponseEndBlock
  132. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  133. resEndBlock = bcApp.EndBlock(height)
  134. }
  135. app.mtx.Unlock()
  136. return app.callback(
  137. types.ToRequestEndBlock(height),
  138. types.ToResponseEndBlock(resEndBlock),
  139. )
  140. }
  141. //-------------------------------------------------------
  142. func (app *localClient) FlushSync() error {
  143. return nil
  144. }
  145. func (app *localClient) EchoSync(msg string) (res types.Result) {
  146. return types.OK.SetData([]byte(msg))
  147. }
  148. func (app *localClient) InfoSync() (resInfo types.ResponseInfo, err error) {
  149. app.mtx.Lock()
  150. defer app.mtx.Unlock()
  151. resInfo = app.Application.Info()
  152. return resInfo, nil
  153. }
  154. func (app *localClient) SetOptionSync(key string, value string) (res types.Result) {
  155. app.mtx.Lock()
  156. log := app.Application.SetOption(key, value)
  157. app.mtx.Unlock()
  158. return types.OK.SetLog(log)
  159. }
  160. func (app *localClient) DeliverTxSync(tx []byte) (res types.Result) {
  161. app.mtx.Lock()
  162. res = app.Application.DeliverTx(tx)
  163. app.mtx.Unlock()
  164. return res
  165. }
  166. func (app *localClient) CheckTxSync(tx []byte) (res types.Result) {
  167. app.mtx.Lock()
  168. res = app.Application.CheckTx(tx)
  169. app.mtx.Unlock()
  170. return res
  171. }
  172. func (app *localClient) QuerySync(query []byte) (res types.Result) {
  173. app.mtx.Lock()
  174. res = app.Application.Query(query)
  175. app.mtx.Unlock()
  176. return res
  177. }
  178. func (app *localClient) ProofSync(key []byte, blockHeight int64) (res types.Result) {
  179. app.mtx.Lock()
  180. res = app.Application.Proof(key, blockHeight)
  181. app.mtx.Unlock()
  182. return res
  183. }
  184. func (app *localClient) CommitSync() (res types.Result) {
  185. app.mtx.Lock()
  186. res = app.Application.Commit()
  187. app.mtx.Unlock()
  188. return res
  189. }
  190. func (app *localClient) InitChainSync(validators []*types.Validator) (err error) {
  191. app.mtx.Lock()
  192. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  193. bcApp.InitChain(validators)
  194. }
  195. app.mtx.Unlock()
  196. return nil
  197. }
  198. func (app *localClient) BeginBlockSync(hash []byte, header *types.Header) (err error) {
  199. app.mtx.Lock()
  200. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  201. bcApp.BeginBlock(hash, header)
  202. }
  203. app.mtx.Unlock()
  204. return nil
  205. }
  206. func (app *localClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) {
  207. app.mtx.Lock()
  208. if bcApp, ok := app.Application.(types.BlockchainAware); ok {
  209. resEndBlock = bcApp.EndBlock(height)
  210. }
  211. app.mtx.Unlock()
  212. return resEndBlock, nil
  213. }
  214. //-------------------------------------------------------
  215. func (app *localClient) callback(req *types.Request, res *types.Response) *ReqRes {
  216. app.Callback(req, res)
  217. return newLocalReqRes(req, res)
  218. }
  219. func newLocalReqRes(req *types.Request, res *types.Response) *ReqRes {
  220. reqRes := NewReqRes(req)
  221. reqRes.Response = res
  222. reqRes.SetDone()
  223. return reqRes
  224. }