2016-02-14 14:59:53 -08:00
|
|
|
package counter
|
2015-11-29 03:43:49 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2017-11-20 20:26:37 -06:00
|
|
|
"fmt"
|
2015-11-29 03:43:49 -05:00
|
|
|
|
2017-01-12 15:47:55 -05:00
|
|
|
"github.com/tendermint/abci/types"
|
2017-04-21 18:25:13 -04:00
|
|
|
cmn "github.com/tendermint/tmlibs/common"
|
2015-11-29 03:43:49 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
type CounterApplication struct {
|
2017-02-13 18:48:59 -05:00
|
|
|
types.BaseApplication
|
|
|
|
|
2016-01-08 16:52:02 -08:00
|
|
|
hashCount int
|
|
|
|
txCount int
|
|
|
|
serial bool
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2015-12-08 21:01:33 -08:00
|
|
|
func NewCounterApplication(serial bool) *CounterApplication {
|
|
|
|
return &CounterApplication{serial: serial}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2017-09-22 11:10:39 -04:00
|
|
|
func (app *CounterApplication) Info(req types.RequestInfo) types.ResponseInfo {
|
2017-03-03 18:39:10 -05:00
|
|
|
return types.ResponseInfo{Data: cmn.Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2017-11-27 19:04:21 +00:00
|
|
|
func (app *CounterApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption {
|
|
|
|
key, value := req.Key, req.Value
|
2015-11-30 15:22:42 -08:00
|
|
|
if key == "serial" && value == "on" {
|
2016-01-08 16:52:02 -08:00
|
|
|
app.serial = true
|
2015-11-30 15:22:42 -08:00
|
|
|
}
|
2017-11-27 19:04:21 +00:00
|
|
|
return types.ResponseSetOption{}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2017-11-20 20:26:37 -06:00
|
|
|
func (app *CounterApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {
|
2016-01-08 16:52:02 -08:00
|
|
|
if app.serial {
|
2016-11-23 18:22:22 -05:00
|
|
|
if len(tx) > 8 {
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseDeliverTx{
|
|
|
|
Code: types.CodeType_EncodingError,
|
|
|
|
Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
|
2016-11-23 18:22:22 -05:00
|
|
|
}
|
2015-12-08 21:52:40 -08:00
|
|
|
tx8 := make([]byte, 8)
|
2016-01-25 08:01:18 -08:00
|
|
|
copy(tx8[len(tx8)-len(tx):], tx)
|
|
|
|
txValue := binary.BigEndian.Uint64(tx8)
|
2016-01-08 16:52:02 -08:00
|
|
|
if txValue != uint64(app.txCount) {
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseDeliverTx{
|
|
|
|
Code: types.CodeType_BadNonce,
|
|
|
|
Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)}
|
2015-11-30 15:22:42 -08:00
|
|
|
}
|
|
|
|
}
|
2017-01-17 00:26:32 -08:00
|
|
|
app.txCount++
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseDeliverTx{Code: types.CodeType_OK}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2017-11-20 20:26:37 -06:00
|
|
|
func (app *CounterApplication) CheckTx(tx []byte) types.ResponseCheckTx {
|
2016-01-08 16:52:02 -08:00
|
|
|
if app.serial {
|
2016-11-23 18:22:22 -05:00
|
|
|
if len(tx) > 8 {
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseCheckTx{
|
|
|
|
Code: types.CodeType_EncodingError,
|
|
|
|
Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))}
|
2016-11-23 18:22:22 -05:00
|
|
|
}
|
2016-01-08 16:52:02 -08:00
|
|
|
tx8 := make([]byte, 8)
|
2016-01-25 08:01:18 -08:00
|
|
|
copy(tx8[len(tx8)-len(tx):], tx)
|
|
|
|
txValue := binary.BigEndian.Uint64(tx8)
|
2016-01-08 16:52:02 -08:00
|
|
|
if txValue < uint64(app.txCount) {
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseCheckTx{
|
|
|
|
Code: types.CodeType_BadNonce,
|
|
|
|
Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)}
|
2016-01-08 16:52:02 -08:00
|
|
|
}
|
|
|
|
}
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseCheckTx{Code: types.CodeType_OK}
|
2016-01-08 16:52:02 -08:00
|
|
|
}
|
|
|
|
|
2017-11-20 20:26:37 -06:00
|
|
|
func (app *CounterApplication) Commit() (resp types.ResponseCommit) {
|
2017-01-17 00:26:32 -08:00
|
|
|
app.hashCount++
|
2016-01-08 16:52:02 -08:00
|
|
|
if app.txCount == 0 {
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseCommit{Code: types.CodeType_OK}
|
2015-12-04 00:59:26 -08:00
|
|
|
}
|
2017-01-17 00:26:32 -08:00
|
|
|
hash := make([]byte, 8)
|
|
|
|
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
|
2017-11-20 20:26:37 -06:00
|
|
|
return types.ResponseCommit{Code: types.CodeType_OK, Data: hash}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|
|
|
|
|
2017-01-23 23:42:09 -08:00
|
|
|
func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
|
|
|
|
switch reqQuery.Path {
|
2016-12-22 18:24:45 -05:00
|
|
|
case "hash":
|
2017-03-03 18:39:10 -05:00
|
|
|
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.hashCount))}
|
2016-12-22 18:24:45 -05:00
|
|
|
case "tx":
|
2017-03-03 18:39:10 -05:00
|
|
|
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.txCount))}
|
2017-01-27 22:27:32 -08:00
|
|
|
default:
|
2017-03-03 18:39:10 -05:00
|
|
|
return types.ResponseQuery{Log: cmn.Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
|
2016-12-22 18:24:45 -05:00
|
|
|
}
|
2015-11-29 03:43:49 -05:00
|
|
|
}
|