github.com/vipernet-xyz/tm@v0.34.24/abci/example/counter/counter.go (about) 1 package counter 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 7 "github.com/vipernet-xyz/tm/abci/example/code" 8 "github.com/vipernet-xyz/tm/abci/types" 9 ) 10 11 type Application struct { 12 types.BaseApplication 13 14 hashCount int 15 txCount int 16 serial bool 17 } 18 19 func NewApplication(serial bool) *Application { 20 return &Application{serial: serial} 21 } 22 23 func (app *Application) Info(req types.RequestInfo) types.ResponseInfo { 24 return types.ResponseInfo{Data: fmt.Sprintf("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)} 25 } 26 27 func (app *Application) SetOption(req types.RequestSetOption) types.ResponseSetOption { 28 key, value := req.Key, req.Value 29 if key == "serial" && value == "on" { 30 app.serial = true 31 } else { 32 /* 33 TODO Panic and have the ABCI server pass an exception. 34 The client can call SetOptionSync() and get an `error`. 35 return types.ResponseSetOption{ 36 Error: fmt.Sprintf("Unknown key (%s) or value (%s)", key, value), 37 } 38 */ 39 return types.ResponseSetOption{} 40 } 41 42 return types.ResponseSetOption{} 43 } 44 45 func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx { 46 if app.serial { 47 if len(req.Tx) > 8 { 48 return types.ResponseDeliverTx{ 49 Code: code.CodeTypeEncodingError, 50 Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(req.Tx))} 51 } 52 tx8 := make([]byte, 8) 53 copy(tx8[len(tx8)-len(req.Tx):], req.Tx) 54 txValue := binary.BigEndian.Uint64(tx8) 55 if txValue != uint64(app.txCount) { 56 return types.ResponseDeliverTx{ 57 Code: code.CodeTypeBadNonce, 58 Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)} 59 } 60 } 61 app.txCount++ 62 return types.ResponseDeliverTx{Code: code.CodeTypeOK} 63 } 64 65 func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx { 66 if app.serial { 67 if len(req.Tx) > 8 { 68 return types.ResponseCheckTx{ 69 Code: code.CodeTypeEncodingError, 70 Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(req.Tx))} 71 } 72 tx8 := make([]byte, 8) 73 copy(tx8[len(tx8)-len(req.Tx):], req.Tx) 74 txValue := binary.BigEndian.Uint64(tx8) 75 if txValue < uint64(app.txCount) { 76 return types.ResponseCheckTx{ 77 Code: code.CodeTypeBadNonce, 78 Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)} 79 } 80 } 81 return types.ResponseCheckTx{Code: code.CodeTypeOK} 82 } 83 84 func (app *Application) Commit() (resp types.ResponseCommit) { 85 app.hashCount++ 86 if app.txCount == 0 { 87 return types.ResponseCommit{} 88 } 89 hash := make([]byte, 8) 90 binary.BigEndian.PutUint64(hash, uint64(app.txCount)) 91 return types.ResponseCommit{Data: hash} 92 } 93 94 func (app *Application) Query(reqQuery types.RequestQuery) types.ResponseQuery { 95 switch reqQuery.Path { 96 case "hash": 97 return types.ResponseQuery{Value: []byte(fmt.Sprintf("%v", app.hashCount))} 98 case "tx": 99 return types.ResponseQuery{Value: []byte(fmt.Sprintf("%v", app.txCount))} 100 default: 101 return types.ResponseQuery{Log: fmt.Sprintf("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)} 102 } 103 }