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.

94 lines
2.7 KiB

9 years ago
9 years ago
7 years ago
8 years ago
8 years ago
9 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
7 years ago
7 years ago
9 years ago
7 years ago
7 years ago
9 years ago
9 years ago
  1. package counter
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "github.com/tendermint/abci/example/code"
  6. "github.com/tendermint/abci/types"
  7. cmn "github.com/tendermint/tmlibs/common"
  8. )
  9. type CounterApplication struct {
  10. types.BaseApplication
  11. hashCount int
  12. txCount int
  13. serial bool
  14. }
  15. func NewCounterApplication(serial bool) *CounterApplication {
  16. return &CounterApplication{serial: serial}
  17. }
  18. func (app *CounterApplication) Info(req types.RequestInfo) types.ResponseInfo {
  19. return types.ResponseInfo{Data: cmn.Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
  20. }
  21. func (app *CounterApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption {
  22. key, value := req.Key, req.Value
  23. if key == "serial" && value == "on" {
  24. app.serial = true
  25. }
  26. return types.ResponseSetOption{}
  27. }
  28. func (app *CounterApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
  29. if app.serial {
  30. if len(tx) > 8 {
  31. return types.ResponseDeliverTx{
  32. Code: code.CodeTypeEncodingError,
  33. Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
  34. }
  35. tx8 := make([]byte, 8)
  36. copy(tx8[len(tx8)-len(tx):], tx)
  37. txValue := binary.BigEndian.Uint64(tx8)
  38. if txValue != uint64(app.txCount) {
  39. return types.ResponseDeliverTx{
  40. Code: code.CodeTypeBadNonce,
  41. Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)}
  42. }
  43. }
  44. app.txCount++
  45. return types.ResponseDeliverTx{Code: code.CodeTypeOK}
  46. }
  47. func (app *CounterApplication) CheckTx(tx []byte) types.ResponseCheckTx {
  48. if app.serial {
  49. if len(tx) > 8 {
  50. return types.ResponseCheckTx{
  51. Code: code.CodeTypeEncodingError,
  52. Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
  53. }
  54. tx8 := make([]byte, 8)
  55. copy(tx8[len(tx8)-len(tx):], tx)
  56. txValue := binary.BigEndian.Uint64(tx8)
  57. if txValue < uint64(app.txCount) {
  58. return types.ResponseCheckTx{
  59. Code: code.CodeTypeBadNonce,
  60. Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)}
  61. }
  62. }
  63. return types.ResponseCheckTx{Code: code.CodeTypeOK}
  64. }
  65. func (app *CounterApplication) Commit() (resp types.ResponseCommit) {
  66. app.hashCount++
  67. if app.txCount == 0 {
  68. return types.ResponseCommit{Code: code.CodeTypeOK}
  69. }
  70. hash := make([]byte, 8)
  71. binary.BigEndian.PutUint64(hash, uint64(app.txCount))
  72. return types.ResponseCommit{Code: code.CodeTypeOK, Data: hash}
  73. }
  74. func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
  75. switch reqQuery.Path {
  76. case "hash":
  77. return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.hashCount))}
  78. case "tx":
  79. return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.txCount))}
  80. default:
  81. return types.ResponseQuery{Log: cmn.Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
  82. }
  83. }