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.

92 lines
2.6 KiB

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