Skip to content

Commit

Permalink
add docs on checktx handler
Browse files Browse the repository at this point in the history
  • Loading branch information
tac0turtle committed Sep 30, 2024
1 parent 94f6f3d commit c71365c
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
2 changes: 1 addition & 1 deletion baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ func (app *BaseApp) PrepareProposalVerifyTx(tx sdk.Tx) ([]byte, error) {
return nil, err
}

_, _, _, err = app.runTx(execModePrepareProposal, bz, tx) // TODO: we should remove encoding here
_, _, _, err = app.runTx(execModePrepareProposal, bz, tx)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion baseapp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func (app *BaseApp) SetPrepareProposal(handler sdk.PrepareProposalHandler) {
}

// SetCheckTx sets the checkTx function for the BaseApp.
func (app *BaseApp) SetCheckTx(handler sdk.CheckTxHandler) {
func (app *BaseApp) SetCheckTxHandler(handler sdk.CheckTxHandler) {
if app.sealed {
panic("SetCheckTx() on sealed BaseApp")
}
Expand Down
87 changes: 87 additions & 0 deletions docs/build/abci/04-checktx.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# CheckTx

CheckTx is called by the `BaseApp` when comet receives a transaction from a client, over the p2p network or RPC. The CheckTx method is responsible for validating the transaction and returning an error if the transaction is invalid.

```mermaid
graph TD
subgraph SDK[Cosmos SDK]
B[Baseapp]
A[AnteHandlers]
B <-->|Validate TX| A
end
C[CometBFT] <-->|CheckTx|SDK
U((User)) -->|Submit TX| C
N[P2P] -->|Receive TX| C
```

```go
// CheckTx implements the ABCI interface.
func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
var mode execMode

switch {
case req.Type == abci.CHECK_TX_TYPE_CHECK:
mode = execModeCheck

case req.Type == abci.CHECK_TX_TYPE_RECHECK:
mode = execModeReCheck

default:
return nil, fmt.Errorf("unknown RequestCheckTx type: %s", req.Type)
}

var decodedTx sdk.Tx = nil
ctx := app.getContextForTx(mode, req.Tx)
if app.checkTxHandler != nil {
tx, err := app.checkTxHandler(ctx, req.Tx)
if err != nil {
return nil, fmt.Errorf("checkTxHandler error: %w", err)
}
decodedTx = tx
}

gInfo, result, anteEvents, err := app.runTx(mode, req.Tx, decodedTx)
if err != nil {
return responseCheckTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace), nil
}

return &abci.CheckTxResponse{
GasWanted: int64(gInfo.GasWanted),
GasUsed: int64(gInfo.GasUsed),
Log: result.Log,
Data: result.Data,
Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents),
}, nil
}
```

## CheckTx Handler

`CheckTxHandler` allows users to extend the logic of `CheckTx`. `CheckTxHandler` is called by pasding context and the transaction bytes received through ABCI. It is required that the handler returns deterministic results given the same transaction bytes.

:::note
we return the raw decoded transaction here to avoid decoding it twice.
:::

```go
type CheckTxHandler func(ctx sdk.Context, tx []byte) (Tx, error)
```

Setting a custom `CheckTxHandler` is optional. It can be done from your app.go file:

```go
func NewSimApp(
logger log.Logger,
db corestore.KVStoreWithBatch,
traceStore io.Writer,
loadLatest bool,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
...
// Create ChecktxHandler
checktxHandler := abci.NewCustomCheckTxHandler(...)
app.SetCheckTxHandler(checktxHandler)
...
}
```
2 changes: 1 addition & 1 deletion docs/build/building-apps/02-app-mempool.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Notably it introduces the `PrepareProposal` and `ProcessProposal` steps of ABCI+

## Mempool

+ Before we delve into `PrepareProposal` and `ProcessProposal`, let's first walk through the mempool concepts.
* Before we delve into `PrepareProposal` and `ProcessProposal`, let's first walk through the mempool concepts.

There are countless designs that an application developer can write for a mempool, the SDK opted to provide only simple mempool implementations.
Namely, the SDK provides the following mempools:
Expand Down

0 comments on commit c71365c

Please sign in to comment.