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.

102 lines
2.9 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. } else {
  26. return types.ResponseSetOption{
  27. Code: code.CodeTypeBadOption,
  28. Log: cmn.Fmt("Unknown key (%s) or value (%s)", key, value),
  29. }
  30. }
  31. return types.ResponseSetOption{
  32. Code: code.CodeTypeOK,
  33. }
  34. }
  35. func (app *CounterApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
  36. if app.serial {
  37. if len(tx) > 8 {
  38. return types.ResponseDeliverTx{
  39. Code: code.CodeTypeEncodingError,
  40. Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
  41. }
  42. tx8 := make([]byte, 8)
  43. copy(tx8[len(tx8)-len(tx):], tx)
  44. txValue := binary.BigEndian.Uint64(tx8)
  45. if txValue != uint64(app.txCount) {
  46. return types.ResponseDeliverTx{
  47. Code: code.CodeTypeBadNonce,
  48. Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)}
  49. }
  50. }
  51. app.txCount++
  52. return types.ResponseDeliverTx{Code: code.CodeTypeOK}
  53. }
  54. func (app *CounterApplication) CheckTx(tx []byte) types.ResponseCheckTx {
  55. if app.serial {
  56. if len(tx) > 8 {
  57. return types.ResponseCheckTx{
  58. Code: code.CodeTypeEncodingError,
  59. Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
  60. }
  61. tx8 := make([]byte, 8)
  62. copy(tx8[len(tx8)-len(tx):], tx)
  63. txValue := binary.BigEndian.Uint64(tx8)
  64. if txValue < uint64(app.txCount) {
  65. return types.ResponseCheckTx{
  66. Code: code.CodeTypeBadNonce,
  67. Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)}
  68. }
  69. }
  70. return types.ResponseCheckTx{Code: code.CodeTypeOK}
  71. }
  72. func (app *CounterApplication) Commit() (resp types.ResponseCommit) {
  73. app.hashCount++
  74. if app.txCount == 0 {
  75. return types.ResponseCommit{Code: code.CodeTypeOK}
  76. }
  77. hash := make([]byte, 8)
  78. binary.BigEndian.PutUint64(hash, uint64(app.txCount))
  79. return types.ResponseCommit{Code: code.CodeTypeOK, Data: hash}
  80. }
  81. func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
  82. switch reqQuery.Path {
  83. case "hash":
  84. return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.hashCount))}
  85. case "tx":
  86. return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.txCount))}
  87. default:
  88. return types.ResponseQuery{Log: cmn.Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
  89. }
  90. }