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  }