Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: cherry-pick and update docs for v0.46.16-alpha.agoric.2.3 #417

Merged
merged 4 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG-Agoric.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ Ref: https://keepachangelog.com/en/1.0.0/

* (auth, bank) Agoric/agoric-sdk#8989 Remove deprecated lien support

## `v0.46.16-alpha.agoric.2.3` - 2024-04-17

### Improvements

* (baseapp) [#415](https://github.com/agoric-labs/cosmos-sdk/pull/415) Unit tests and documentation for event history.
* (server) [#416](https://github.com/agoric-labs/cosmos-sdk/pull/416) Config entry to select ABCI client type.

### Bug Fixes

* (baseapp) [#415](https://github.com/agoric-labs/cosmos-sdk/pull/415) Avoid duplicates in event history.

## `v0.46.16-alpha.agoric.2.2` - 2024-04-12

### Improvements
Expand Down
23 changes: 17 additions & 6 deletions baseapp/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,11 @@
}

if app.endBlocker != nil {
// Propagate the event history.
em := sdk.NewEventManagerWithHistory(app.deliverState.eventHistory)
res = app.endBlocker(app.deliverState.ctx.WithEventManager(em), req)
// [AGORIC] Propagate the event history.
enhancedEm := sdk.NewEventManagerWithHistory(app.deliverState.eventHistory)
enhancedCtx := app.deliverState.ctx.WithEventManager(enhancedEm)

res = app.endBlocker(enhancedCtx, req)
res.Events = sdk.MarkEventsToIndex(res.Events, app.indexEvents)
}

Expand Down Expand Up @@ -266,6 +268,17 @@
// Regardless of tx execution outcome, the ResponseDeliverTx will contain relevant
// gas execution context.
func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) {
// [AGORIC] Remember event history for successful deliveries.
// deliverTxWithoutEventHistory is the upstream cosmos-sdk DeliverTx.
res = app.deliverTxWithoutEventHistory(req)
// When successful, remember event history.
if res.Code == sdkerrors.SuccessABCICode {

Check failure on line 275 in baseapp/abci.go

View workflow job for this annotation

GitHub Actions / golangci-lint

SA1019: sdkerrors.SuccessABCICode is deprecated: functionality of this package has been moved to it's own module: (staticcheck)

Check failure on line 275 in baseapp/abci.go

View workflow job for this annotation

GitHub Actions / Analyze

SA1019: sdkerrors.SuccessABCICode is deprecated: functionality of this package has been moved to it's own module: (staticcheck)
app.deliverState.eventHistory = append(app.deliverState.eventHistory, res.Events...)
}
return res
}

func (app *BaseApp) deliverTxWithoutEventHistory(req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) {
gInfo := sdk.GasInfo{}
resultStr := "successful"

Expand All @@ -290,14 +303,12 @@
return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(anteEvents, app.indexEvents), app.trace)
}

events := sdk.MarkEventsToIndex(result.Events, app.indexEvents)
app.deliverState.eventHistory = append(app.deliverState.eventHistory, events...)
return abci.ResponseDeliverTx{
GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints?
GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints?
Log: result.Log,
Data: result.Data,
Events: events,
Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents),
}
}

Expand Down
20 changes: 9 additions & 11 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package baseapp

import (
"context"
"errors"
"fmt"
"strings"
Expand Down Expand Up @@ -29,6 +28,7 @@ const (
runTxModeDeliver // Deliver a transaction
)

// [AGORIC] Context keys for including TX hash and msg index.
const (
TxHashContextKey = sdk.ContextKey("tx-hash")
TxMsgIdxContextKey = sdk.ContextKey("tx-msg-idx")
Expand Down Expand Up @@ -435,7 +435,7 @@ func (app *BaseApp) setCheckState(header tmproto.Header) {
app.checkState = &state{
ms: ms,
ctx: sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices),
eventHistory: []abci.Event{},
eventHistory: []abci.Event{}, // [AGORIC]: start with an empty history.
}
}

Expand All @@ -448,7 +448,7 @@ func (app *BaseApp) setDeliverState(header tmproto.Header) {
app.deliverState = &state{
ms: ms,
ctx: sdk.NewContext(ms, header, false, app.logger),
eventHistory: []abci.Event{},
eventHistory: []abci.Event{}, // [AGORIC]: start with an empty history.
}
}

Expand Down Expand Up @@ -607,11 +607,13 @@ func (app *BaseApp) getContextForTx(mode runTxMode, txBytes []byte) sdk.Context
// cacheTxContext returns a new context based off of the provided context with
// a branched multi-store.
func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context, sdk.CacheMultiStore) {
// [AGORIC] Add Tx hash to the context if absent.
txHash, ok := ctx.Context().Value(TxHashContextKey).(string)
if !ok {
txHash = fmt.Sprintf("%X", tmhash.Sum(txBytes))
ctx = ctx.WithContext(context.WithValue(ctx.Context(), TxHashContextKey, txHash))
ctx = ctx.WithValue(TxHashContextKey, txHash)
}

ms := ctx.MultiStore()
// TODO: https://github.com/cosmos/cosmos-sdk/issues/2824
msCache := ms.CacheMultiStore()
Expand Down Expand Up @@ -767,9 +769,6 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
if len(anteEvents) > 0 && (mode == runTxModeDeliver || mode == runTxModeSimulate) {
// append the events in the order of occurrence
result.Events = append(anteEvents, result.Events...)
if app.deliverState != nil && mode == runTxModeDeliver {
app.deliverState.eventHistory = append(app.deliverState.eventHistory, result.Events...)
}
}
}

Expand All @@ -784,7 +783,6 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re
func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*sdk.Result, error) {
msgLogs := make(sdk.ABCIMessageLogs, 0, len(msgs))
events := sdk.EmptyEvents()
historicalEvents := ctx.EventManager().GetABCIEventHistory()
var msgResponses []*codectypes.Any

// NOTE: GasWanted is determined by the AnteHandler and GasUsed by the GasMeter.
Expand All @@ -800,8 +798,9 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
err error
)

msgCtx := ctx.WithEventManager(sdk.NewEventManagerWithHistory(historicalEvents))
msgCtx = msgCtx.WithContext(context.WithValue(msgCtx.Context(), TxMsgIdxContextKey, i))
// [AGORIC] Propagate the message index in the context.
msgCtx := ctx.WithValue(TxMsgIdxContextKey, i)

if handler := app.msgServiceRouter.Handler(msg); handler != nil {
// ADR 031 request type routing
msgResult, err = handler(msgCtx, msg)
Expand Down Expand Up @@ -838,7 +837,6 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s
// Note: Each message result's data must be length-prefixed in order to
// separate each result.
events = events.AppendEvents(msgEvents)
historicalEvents = append(historicalEvents, msgEvents.ToABCIEvents()...)

// Each individual sdk.Result that went through the MsgServiceRouter
// (which should represent 99% of the Msgs now, since everyone should
Expand Down
69 changes: 69 additions & 0 deletions baseapp/baseapp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,75 @@ func TestSimulateTx(t *testing.T) {
}
}

func TestEventHistory(t *testing.T) {
// generates events in the ante
anteKey := []byte("ante-key")
anteOpt := func(bapp *BaseApp) { bapp.SetAnteHandler(anteHandlerTxTest(t, capKey1, anteKey)) }

deliverKey := []byte("deliver-key")
routerOpt := func(bapp *BaseApp) {
r := sdk.NewRoute(routeMsgCounter, handlerMsgCounter(t, capKey1, deliverKey))
bapp.Router().AddRoute(r)
}

// expand setupBaseApp() here so we can override the EndBlocker before app is sealed
app := newBaseApp(t.Name(), anteOpt, routerOpt)
require.Equal(t, t.Name(), app.Name())

app.MountStores(capKey1, capKey2)
app.SetParamStore(&paramStore{db: dbm.NewMemDB()})

var history []abci.Event
app.SetEndBlocker(func(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
history = ctx.EventManager().GetABCIEventHistory()
return abci.ResponseEndBlock{}
})

// stores are mounted (seals the app)
err := app.LoadLatestVersion()
require.Nil(t, err)

app.InitChain(abci.RequestInitChain{})

// Create same codec used in txDecoder
cdc := codec.NewLegacyAmino()
registerTestCodec(cdc)

header := tmproto.Header{Height: int64(1)}
app.BeginBlock(abci.RequestBeginBlock{Header: header})

require.Zero(t, len(app.deliverState.eventHistory))

counter := int64(0)
tx := newTxCounter(counter, counter)
txBytes, err := cdc.Marshal(tx)
require.NoError(t, err)

// simulation returns events, but none in deliverState history
_, simResult, err := app.Simulate(txBytes)
require.NoError(t, err)
require.NotNil(t, simResult)
require.Zero(t, len(app.deliverState.eventHistory))
expectedEvents := simResult.Events
require.NotZero(t, len(expectedEvents))

// delivery results should be reflected in deliverState history
deliverResult := app.DeliverTx(abci.RequestDeliverTx{Tx: txBytes})
require.True(t, deliverResult.IsOK(), fmt.Sprintf("%v", deliverResult))
require.NotZero(t, len(app.deliverState.eventHistory))
// simResult events are not indexed, but should otherwise be the same as deliverResult events
for i, _ := range simResult.Events {
simResult.Events[i].Attributes[0].Index = true
}
require.Equal(t, expectedEvents, deliverResult.Events)
require.Equal(t, expectedEvents, app.deliverState.eventHistory)

// the deliverState event history should be passed to the end blocker in the context, then cleared
app.EndBlock(abci.RequestEndBlock{})
require.Zero(t, len(app.deliverState.eventHistory))
require.Equal(t, expectedEvents, history)
}

func TestRunInvalidTransaction(t *testing.T) {
anteOpt := func(bapp *BaseApp) {
bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) {
Expand Down
8 changes: 6 additions & 2 deletions baseapp/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import (
)

type state struct {
ms sdk.CacheMultiStore
ctx sdk.Context
ms sdk.CacheMultiStore
ctx sdk.Context
// eventHistory accumulates events returned by DeliverTx throughout a block.
// [AGORIC] The accumulated events are passed to the EndBlocker in its context's
// EventManager ABCI event history, and the state's eventHistory is then cleared.
// Not used for modes or states other than delivery.
eventHistory []abci.Event
}

Expand Down
13 changes: 13 additions & 0 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,18 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

// [AGORIC] Valid values for FlagAbciClientType
const (
AbciClientTypeCommitting = "committing"
AbciClientTypeLocal = "local"
)

const (
defaultMinGasPrices = ""

// DefaultABCIClientType defines the default ABCI client type to use with cometbft.
DefaultABCIClientType = AbciClientTypeCommitting // [AGORIC]

// DefaultAPIAddress defines the default address to bind the API server to.
DefaultAPIAddress = "tcp://0.0.0.0:1317"

Expand Down Expand Up @@ -94,6 +103,9 @@ type BaseConfig struct {
// IAVLLazyLoading enable/disable the lazy loading of iavl store.
IAVLLazyLoading bool `mapstructure:"iavl-lazy-loading"`

// ABCIClientType selects the type of ABCI client.
ABCIClientType string `mapstructure:"abci-client-type"`

// AppDBBackend defines the type of Database to use for the application and snapshots databases.
// An empty string indicates that the Tendermint config's DBBackend value should be used.
AppDBBackend string `mapstructure:"app-db-backend"`
Expand Down Expand Up @@ -289,6 +301,7 @@ func DefaultConfig() *Config {
IAVLCacheSize: 781250, // 50 MB
IAVLDisableFastNode: false,
IAVLLazyLoading: false,
ABCIClientType: DefaultABCIClientType, // [AGORIC]
AppDBBackend: "",
},
Telemetry: telemetry.Config{
Expand Down
4 changes: 4 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ iavl-disable-fastnode = {{ .BaseConfig.IAVLDisableFastNode }}
# Default is false.
iavl-lazy-loading = {{ .BaseConfig.IAVLLazyLoading }}

# ABCIClientType selects the type of ABCI client.
# Default is "committing".
abci-client-type = "{{ .BaseConfig.ABCIClientType }}"

# AppDBBackend defines the database backend type to use for the application and snapshots DBs.
# An empty string indicates that a fallback will be used.
# First fallback is the deprecated compile-time types.DBBackend value.
Expand Down
34 changes: 15 additions & 19 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ const (
flagGRPCWebAddress = "grpc-web.address"
)

const (
abciClientTypeCommitting = "committing"
abciClientTypeLocal = "local"
)

// StartCmd runs the service passed in, either stand-alone or in-process with
// Tendermint.
func StartCmd(appCreator types.AppCreator, defaultNodeHome string) *cobra.Command {
Expand Down Expand Up @@ -149,18 +144,9 @@ is performed. Note, when enabled, gRPC will also be automatically enabled.
})
}

abciClientType, err := cmd.Flags().GetString(FlagAbciClientType)
if err != nil {
return err
}
clientCreator, err := getAbciClientCreator(abciClientType)
if err != nil {
return err
}

// amino is needed here for backwards compatibility of REST routes
err = wrapCPUProfile(serverCtx, func() error {
return startInProcess(serverCtx, clientCtx, appCreator, clientCreator)
return startInProcess(serverCtx, clientCtx, appCreator)
})
errCode, ok := err.(ErrorCode)
if !ok {
Expand Down Expand Up @@ -210,7 +196,7 @@ is performed. Note, when enabled, gRPC will also be automatically enabled.
cmd.Flags().Uint32(FlagStateSyncSnapshotKeepRecent, 2, "State sync snapshot to keep")

cmd.Flags().Bool(FlagDisableIAVLFastNode, false, "Disable fast node for IAVL tree")
cmd.Flags().String(FlagAbciClientType, abciClientTypeCommitting, fmt.Sprintf(`Type of ABCI client ("%s" or "%s")`, abciClientTypeCommitting, abciClientTypeLocal))
cmd.Flags().String(FlagAbciClientType, serverconfig.DefaultABCIClientType, fmt.Sprintf(`Type of ABCI client ("%s" or "%s")`, serverconfig.AbciClientTypeCommitting, serverconfig.AbciClientTypeLocal))

// add support for all Tendermint-specific command line options
tcmd.AddNodeFlags(cmd)
Expand Down Expand Up @@ -273,7 +259,7 @@ func startStandAlone(ctx *Context, appCreator types.AppCreator) error {

type abciClientCreator func(abcitypes.Application) proxy.ClientCreator

func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.AppCreator, clientCreator abciClientCreator) error {
func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.AppCreator) error {
cfg := ctx.Config
home := cfg.RootDir

Expand Down Expand Up @@ -306,6 +292,14 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App

genDocProvider := node.DefaultGenesisDocProviderFunc(cfg)

// [AGORIC] allow the ABCI client type to be configurable.
abciClientType := config.ABCIClientType
ctx.Logger.Info(fmt.Sprintf("ABCI client type: %s", abciClientType))
clientCreator, err := getAbciClientCreator(abciClientType)
if err != nil {
return err
}

var (
tmNode *node.Node
gRPCOnly = ctx.Viper.GetBool(flagGRPCOnly)
Expand Down Expand Up @@ -520,11 +514,13 @@ func startInProcess(ctx *Context, clientCtx client.Context, appCreator types.App
return WaitForQuitSignals()
}

// getAbciClientCreator dispatches the client type to the right cometbft constructor.
// [AGORIC] Allows us to disable committingClient.
func getAbciClientCreator(abciClientType string) (abciClientCreator, error) {
switch abciClientType {
case abciClientTypeCommitting:
case serverconfig.AbciClientTypeCommitting:
return proxy.NewCommittingClientCreator, nil
case abciClientTypeLocal:
case serverconfig.AbciClientTypeLocal:
return proxy.NewLocalClientCreator, nil
}
return nil, fmt.Errorf(`unknown ABCI client type "%s"`, abciClientType)
Expand Down
Loading
Loading