diff --git a/baseapp/abci.go b/baseapp/abci.go index f8201b040..148de4fc6 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -25,6 +25,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/legacytm" + "github.com/cosmos/cosmos-sdk/utils" ) // InitChain implements the ABCI interface. It runs the initialization logic @@ -204,7 +205,7 @@ func (app *BaseApp) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (res abc // internal CheckTx state if the AnteHandler passes. Otherwise, the ResponseCheckTx // will contain releveant error information. Regardless of tx execution outcome, // the ResponseCheckTx will contain relevant gas execution context. -func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) { +func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTxV2, error) { defer telemetry.MeasureSince(time.Now(), "abci", "check_tx") var mode runTxMode @@ -221,17 +222,34 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc } sdkCtx := app.getContextForTx(mode, req.Tx) - gInfo, result, _, priority, err := app.runTx(sdkCtx, mode, req.Tx) + tx, err := app.txDecoder(req.Tx) + if err != nil { + res := sdkerrors.ResponseCheckTx(err, 0, 0, app.trace) + return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err + } + gInfo, result, _, priority, pendingTxChecker, expireTxHandler, txCtx, err := app.runTx(sdkCtx, mode, tx, sha256.Sum256(req.Tx)) if err != nil { res := sdkerrors.ResponseCheckTx(err, gInfo.GasWanted, gInfo.GasUsed, app.trace) - return &res, err + return &abci.ResponseCheckTxV2{ResponseCheckTx: &res}, err } - return &abci.ResponseCheckTx{ - GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? - Data: result.Data, - Priority: priority, - }, nil + res := &abci.ResponseCheckTxV2{ + ResponseCheckTx: &abci.ResponseCheckTx{ + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + Data: result.Data, + Priority: priority, + }, + ExpireTxHandler: expireTxHandler, + EVMNonce: txCtx.EVMNonce(), + EVMSenderAddress: txCtx.EVMSenderAddress(), + IsEVM: txCtx.IsEVM(), + } + if pendingTxChecker != nil { + res.IsPendingTransaction = true + res.Checker = pendingTxChecker + } + + return res, nil } // DeliverTx implements the ABCI interface and executes a tx in DeliverTx mode. @@ -239,7 +257,7 @@ func (app *BaseApp) CheckTx(ctx context.Context, req *abci.RequestCheckTx) (*abc // Otherwise, the ResponseDeliverTx will contain releveant error information. // Regardless of tx execution outcome, the ResponseDeliverTx will contain relevant // gas execution context. -func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx) (res abci.ResponseDeliverTx) { +func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx, tx sdk.Tx, checksum [32]byte) (res abci.ResponseDeliverTx) { defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx") defer func() { for _, streamingListener := range app.abciListeners { @@ -259,7 +277,7 @@ func (app *BaseApp) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTx) (res a telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, req.Tx) + gInfo, result, anteEvents, _, _, _, _, err := app.runTx(ctx.WithTxBytes(req.Tx).WithVoteInfos(app.voteInfos), runTxModeDeliver, tx, checksum) if err != nil { resultStr = "failed" // if we have a result, use those events instead of just the anteEvents @@ -912,7 +930,7 @@ func splitPath(requestPath string) (path []string) { } // ABCI++ -func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { +func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepareProposal) (resp *abci.ResponsePrepareProposal, err error) { defer telemetry.MeasureSince(time.Now(), "abci", "prepare_proposal") header := tmproto.Header{ @@ -946,21 +964,40 @@ func (app *BaseApp) PrepareProposal(ctx context.Context, req *abci.RequestPrepar app.preparePrepareProposalState() + defer func() { + if err := recover(); err != nil { + app.logger.Error( + "panic recovered in PrepareProposal", + "height", req.Height, + "time", req.Time, + "panic", err, + ) + + resp = &abci.ResponsePrepareProposal{ + TxRecords: utils.Map(req.Txs, func(tx []byte) *abci.TxRecord { + return &abci.TxRecord{Action: abci.TxRecord_UNMODIFIED, Tx: tx} + }), + } + } + }() + if app.prepareProposalHandler != nil { - res, err := app.prepareProposalHandler(app.prepareProposalState.ctx, req) + resp, err = app.prepareProposalHandler(app.prepareProposalState.ctx, req) if err != nil { return nil, err } + if cp := app.GetConsensusParams(app.prepareProposalState.ctx); cp != nil { - res.ConsensusParamUpdates = cp + resp.ConsensusParamUpdates = cp } - return res, nil - } else { - return nil, errors.New("no prepare proposal handler") + + return resp, nil } + + return nil, errors.New("no prepare proposal handler") } -func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) { +func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProcessProposal) (resp *abci.ResponseProcessProposal, err error) { defer telemetry.MeasureSince(time.Now(), "abci", "process_proposal") header := tmproto.Header{ @@ -1001,21 +1038,36 @@ func (app *BaseApp) ProcessProposal(ctx context.Context, req *abci.RequestProces } // NOTE: header hash is not set in NewContext, so we manually set it here - app.prepareProcessProposalState(gasMeter, req.Hash) + defer func() { + if err := recover(); err != nil { + app.logger.Error( + "panic recovered in ProcessProposal", + "height", req.Height, + "time", req.Time, + "hash", fmt.Sprintf("%X", req.Hash), + "panic", err, + ) + + resp = &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT} + } + }() + if app.processProposalHandler != nil { - res, err := app.processProposalHandler(app.processProposalState.ctx, req) + resp, err = app.processProposalHandler(app.processProposalState.ctx, req) if err != nil { return nil, err } + if cp := app.GetConsensusParams(app.processProposalState.ctx); cp != nil { - res.ConsensusParamUpdates = cp + resp.ConsensusParamUpdates = cp } - return res, nil - } else { - return nil, errors.New("no process proposal handler") + + return resp, nil } + + return nil, errors.New("no process proposal handler") } func (app *BaseApp) FinalizeBlock(ctx context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ea9c31134..62ac9fe1b 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -2,7 +2,6 @@ package baseapp import ( "context" - "crypto/sha256" "fmt" "reflect" "strings" @@ -155,8 +154,9 @@ type BaseApp struct { //nolint: maligned ChainID string - votesInfoLock sync.RWMutex - commitLock *sync.Mutex + votesInfoLock sync.RWMutex + commitLock *sync.Mutex + checkTxStateLock *sync.RWMutex compactionInterval uint64 @@ -266,7 +266,8 @@ func NewBaseApp( TracingInfo: &tracing.Info{ Tracer: &tr, }, - commitLock: &sync.Mutex{}, + commitLock: &sync.Mutex{}, + checkTxStateLock: &sync.RWMutex{}, } app.TracingInfo.SetContext(context.Background()) @@ -501,6 +502,8 @@ func (app *BaseApp) IsSealed() bool { return app.sealed } func (app *BaseApp) setCheckState(header tmproto.Header) { ms := app.cms.CacheMultiStore() ctx := sdk.NewContext(ms, header, true, app.logger).WithMinGasPrices(app.minGasPrices) + app.checkTxStateLock.Lock() + defer app.checkTxStateLock.Unlock() if app.checkState == nil { app.checkState = &state{ ms: ms, @@ -795,7 +798,7 @@ 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) { +func (app *BaseApp) cacheTxContext(ctx sdk.Context, checksum [32]byte) (sdk.Context, sdk.CacheMultiStore) { ms := ctx.MultiStore() // TODO: https://github.com/cosmos/cosmos-sdk/issues/2824 msCache := ms.CacheMultiStore() @@ -803,7 +806,7 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context msCache = msCache.SetTracingContext( sdk.TraceContext( map[string]interface{}{ - "txHash": fmt.Sprintf("%X", sha256.Sum256(txBytes)), + "txHash": fmt.Sprintf("%X", checksum), }, ), ).(sdk.CacheMultiStore) @@ -819,8 +822,16 @@ func (app *BaseApp) cacheTxContext(ctx sdk.Context, txBytes []byte) (sdk.Context // Note, gas execution info is always returned. A reference to a Result is // returned if the tx does not run out of gas and if all the messages are valid // and execute successfully. An error is returned otherwise. -func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, err error) { - +func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, tx sdk.Tx, checksum [32]byte) ( + gInfo sdk.GasInfo, + result *sdk.Result, + anteEvents []abci.Event, + priority int64, + pendingTxChecker abci.PendingTxChecker, + expireHandler abci.ExpireTxHandler, + txCtx sdk.Context, + err error, +) { defer telemetry.MeasureThroughputSinceWithLabels( telemetry.TxCount, []metrics.Label{ @@ -843,7 +854,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf spanCtx, span := app.TracingInfo.StartWithContext("RunTx", ctx.TraceSpanContext()) defer span.End() ctx = ctx.WithTraceSpanContext(spanCtx) - span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", sha256.Sum256(txBytes)))) + span.SetAttributes(attribute.String("txHash", fmt.Sprintf("%X", checksum))) // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas @@ -854,7 +865,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // only run the tx if there is block gas remaining if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() { - return gInfo, nil, nil, -1, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") + return gInfo, nil, nil, -1, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } defer func() { @@ -890,15 +901,14 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf defer consumeBlockGas() } - tx, err := app.txDecoder(txBytes) - if err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + if tx == nil { + return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx decode error") } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + return sdk.GasInfo{}, nil, nil, 0, nil, nil, ctx, err } if app.anteHandler != nil { @@ -916,7 +926,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // NOTE: Alternatively, we could require that AnteHandler ensures that // writes do not happen if aborted/failed. This may have some // performance benefits, but it'll be more difficult to get right. - anteCtx, msCache = app.cacheTxContext(ctx, txBytes) + anteCtx, msCache = app.cacheTxContext(ctx, checksum) anteCtx = anteCtx.WithEventManager(sdk.NewEventManager()) newCtx, err := app.anteHandler(anteCtx, tx, mode == runTxModeSimulate) @@ -940,7 +950,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // GasMeter expected to be set in AnteHandler gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, err + return gInfo, nil, nil, 0, nil, nil, ctx, err } // Dont need to validate in checkTx mode @@ -955,11 +965,13 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf op.EmitValidationFailMetrics() } errMessage := fmt.Sprintf("Invalid Concurrent Execution antehandler missing %d access operations", len(missingAccessOps)) - return gInfo, nil, nil, 0, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) + return gInfo, nil, nil, 0, nil, nil, ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidConcurrencyExecution, errMessage) } } priority = ctx.Priority() + pendingTxChecker = ctx.PendingTxChecker() + expireHandler = ctx.ExpireTxHandler() msCache.Write() anteEvents = events.ToABCIEvents() anteSpan.End() @@ -968,7 +980,7 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // Create a new Context based off of the existing Context with a MultiStore branch // in case message processing fails. At this point, the MultiStore // is a branch of a branch. - runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) + runMsgCtx, msCache := app.cacheTxContext(ctx, checksum) // Attempt to execute all messages and only update state if all messages pass // and we're in DeliverTx. Note, runMsgs will never return a reference to a @@ -986,7 +998,10 @@ func (app *BaseApp) runTx(ctx sdk.Context, mode runTxMode, txBytes []byte) (gInf // append the events in the order of occurrence result.Events = append(anteEvents, result.Events...) } - return gInfo, result, anteEvents, priority, err + if ctx.CheckTxCallback() != nil { + ctx.CheckTxCallback()(err) + } + return gInfo, result, anteEvents, priority, pendingTxChecker, expireHandler, ctx, err } // runMsgs iterates through a list of messages and executes them with the provided @@ -1031,7 +1046,7 @@ func (app *BaseApp) runMsgs(ctx sdk.Context, msgs []sdk.Msg, mode runTxMode) (*s err error ) - msgCtx, msgMsCache := app.cacheTxContext(ctx, []byte{}) + msgCtx, msgMsCache := app.cacheTxContext(ctx, [32]byte{}) msgCtx = msgCtx.WithMessageIndex(i) startTime := time.Now() @@ -1172,5 +1187,7 @@ func (app *BaseApp) ReloadDB() error { } func (app *BaseApp) GetCheckCtx() sdk.Context { + app.checkTxStateLock.RLock() + defer app.checkTxStateLock.RUnlock() return app.checkState.ctx } diff --git a/baseapp/deliver_tx_test.go b/baseapp/deliver_tx_test.go index c9fdc767d..9307a964f 100644 --- a/baseapp/deliver_tx_test.go +++ b/baseapp/deliver_tx_test.go @@ -3,6 +3,7 @@ package baseapp import ( "bytes" "context" + "crypto/sha256" "encoding/binary" "fmt" "math/rand" @@ -229,7 +230,8 @@ func TestWithRouter(t *testing.T) { txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) } @@ -439,7 +441,8 @@ func TestMultiMsgDeliverTx(t *testing.T) { tx := newTxCounter(0, 0, 1, 2) txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) store := app.deliverState.ctx.KVStore(capKey1) @@ -459,7 +462,8 @@ func TestMultiMsgDeliverTx(t *testing.T) { tx.Msgs = append(tx.Msgs, msgCounter2{1}) txBytes, err = codec.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) store = app.deliverState.ctx.KVStore(capKey1) @@ -658,9 +662,8 @@ func TestRunInvalidTransaction(t *testing.T) { txBytes, err := newCdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) - require.EqualValues(t, sdkerrors.ErrTxDecode.ABCICode(), res.Code) - require.EqualValues(t, sdkerrors.ErrTxDecode.Codespace(), res.Codespace) + _, err = app.txDecoder(txBytes) + require.NotNil(t, err) } } @@ -932,7 +935,8 @@ func TestBaseAppAnteHandler(t *testing.T) { tx.setFailOnAnte(true) txBytes, err := cdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.Empty(t, res.Events) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -948,7 +952,8 @@ func TestBaseAppAnteHandler(t *testing.T) { txBytes, err = cdc.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) // should emit ante event require.NotEmpty(t, res.Events) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -965,7 +970,8 @@ func TestBaseAppAnteHandler(t *testing.T) { txBytes, err = cdc.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ = app.txDecoder(txBytes) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.NotEmpty(t, res.Events) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) @@ -1043,7 +1049,7 @@ func TestGasConsumptionBadTx(t *testing.T) { txBytes, err := cdc.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, tx, sha256.Sum256(txBytes)) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) // require next tx to fail due to black gas limit @@ -1051,7 +1057,7 @@ func TestGasConsumptionBadTx(t *testing.T) { txBytes, err = cdc.Marshal(tx) require.NoError(t, err) - res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + res = app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, tx, sha256.Sum256(txBytes)) require.False(t, res.IsOK(), fmt.Sprintf("%v", res)) } @@ -1520,7 +1526,8 @@ func TestDeliverTx(t *testing.T) { txBytes, err := codec.Marshal(tx) require.NoError(t, err) - res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + decoded, _ := app.txDecoder(txBytes) + res := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, decoded, sha256.Sum256(txBytes)) require.True(t, res.IsOK(), fmt.Sprintf("%v", res)) events := res.GetEvents() require.Len(t, events, 3, "should contain ante handler, message type and counter events respectively") @@ -1724,12 +1731,12 @@ func setupBaseAppWithSnapshots(t *testing.T, blocks uint, blockTxs int, options value := make([]byte, 10000) _, err := r.Read(value) require.NoError(t, err) - tx.Msgs = append(tx.Msgs, msgKeyValue{Key: key, Value: value}) + tx.Msgs = append(tx.Msgs, &msgKeyValue{Key: key, Value: value}) keyCounter++ } txBytes, err := codec.Marshal(tx) require.NoError(t, err) - resp := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}) + resp := app.DeliverTx(app.deliverState.ctx, abci.RequestDeliverTx{Tx: txBytes}, tx, sha256.Sum256(txBytes)) require.True(t, resp.IsOK(), "%v", resp.String()) } app.EndBlock(app.deliverState.ctx, abci.RequestEndBlock{Height: height}) diff --git a/baseapp/msg_service_router_test.go b/baseapp/msg_service_router_test.go index 6c504aba0..0cd6bf385 100644 --- a/baseapp/msg_service_router_test.go +++ b/baseapp/msg_service_router_test.go @@ -2,6 +2,7 @@ package baseapp_test import ( "context" + "crypto/sha256" "testing" "github.com/stretchr/testify/require" @@ -73,7 +74,8 @@ func TestMsgService(t *testing.T) { encCfg := simapp.MakeTestEncodingConfig() testdata.RegisterInterfaces(encCfg.InterfaceRegistry) db := dbm.NewMemDB() - app := baseapp.NewBaseApp("test", log.NewTestingLogger(t), db, encCfg.TxConfig.TxDecoder(), nil, &testutil.TestAppOpts{}) + decoder := encCfg.TxConfig.TxDecoder() + app := baseapp.NewBaseApp("test", log.NewTestingLogger(t), db, decoder, nil, &testutil.TestAppOpts{}) app.SetInterfaceRegistry(encCfg.InterfaceRegistry) testdata.RegisterMsgServer( app.MsgServiceRouter(), @@ -81,10 +83,15 @@ func TestMsgService(t *testing.T) { ) app.SetFinalizeBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { txResults := []*abci.ExecTxResult{} - for _, tx := range req.Txs { + for _, txbz := range req.Txs { + tx, err := decoder(txbz) + if err != nil { + txResults = append(txResults, &abci.ExecTxResult{}) + continue + } deliverTxResp := app.DeliverTx(ctx, abci.RequestDeliverTx{ - Tx: tx, - }) + Tx: txbz, + }, tx, sha256.Sum256(txbz)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index d8b114395..dc8b5150f 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -1,6 +1,8 @@ package baseapp import ( + "crypto/sha256" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -15,7 +17,7 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.checkState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeCheck, bz) + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeCheck, tx, sha256.Sum256(bz)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected checkTx events to be empty") } @@ -25,7 +27,11 @@ func (app *BaseApp) Check(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *sdk func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { ctx := app.checkState.ctx.WithTxBytes(txBytes).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.checkState.ctx)) ctx, _ = ctx.CacheContext() - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeSimulate, txBytes) + tx, err := app.txDecoder(txBytes) + if err != nil { + return sdk.GasInfo{}, nil, err + } + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeSimulate, tx, sha256.Sum256(txBytes)) if len(ctx.MultiStore().GetEvents()) > 0 { panic("Expected simulate events to be empty") } @@ -39,7 +45,11 @@ func (app *BaseApp) Deliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, *s return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } ctx := app.deliverState.ctx.WithTxBytes(bz).WithVoteInfos(app.voteInfos).WithConsensusParams(app.GetConsensusParams(app.deliverState.ctx)) - gasInfo, result, _, _, err := app.runTx(ctx, runTxModeDeliver, bz) + decoded, err := app.txDecoder(bz) + if err != nil { + return sdk.GasInfo{}, &sdk.Result{}, err + } + gasInfo, result, _, _, _, _, _, err := app.runTx(ctx, runTxModeDeliver, decoded, sha256.Sum256(bz)) return gasInfo, result, err } diff --git a/go.mod b/go.mod index 4d21e52e3..aea598c3d 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/regen-network/cosmos-proto v0.3.1 github.com/rs/zerolog v1.30.0 github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8 - github.com/sei-protocol/sei-db v0.0.22 + github.com/sei-protocol/sei-db v0.0.27-0.20240123064153-d6dfa112e760 github.com/sei-protocol/sei-tm-db v0.0.5 github.com/spf13/cast v1.5.0 github.com/spf13/cobra v1.6.1 @@ -180,10 +180,10 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 - github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.25 + github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.28 // Latest goleveldb is broken, we have to stick to this version github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.35 + github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.2.36-evm-rebase-4 // latest grpc doesn't work with with our modified proto compiler, so we need to enforce // the following version across all dependencies. google.golang.org/grpc => google.golang.org/grpc v1.33.2 diff --git a/go.sum b/go.sum index 5ec11222e..dd87863c1 100644 --- a/go.sum +++ b/go.sum @@ -781,12 +781,12 @@ github.com/savaki/jq v0.0.0-20161209013833-0e6baecebbf8/go.mod h1:Nw/CCOXNyF5JDd github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sei-protocol/sei-db v0.0.25 h1:jC1ivcaNxSR7EmxqvxexqPpnN/G0vUTZNHZI+C9T8M8= -github.com/sei-protocol/sei-db v0.0.25/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= +github.com/sei-protocol/sei-db v0.0.28 h1:RE4k2aXSERUixJC2kZri201w1fG3WJ7PZfvCJHCYkiM= +github.com/sei-protocol/sei-db v0.0.28/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE= github.com/sei-protocol/sei-iavl v0.1.9/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk= -github.com/sei-protocol/sei-tendermint v0.2.35 h1:TvmcsNLsv1l8gJRVwsFRNa/YsySp7jtPku/JfyOBO4w= -github.com/sei-protocol/sei-tendermint v0.2.35/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= +github.com/sei-protocol/sei-tendermint v0.2.36-evm-rebase-4 h1:b5IMhO7RZbOwF1Fvu4i2JJHCU50tBFI3Xp0wnnv2G1o= +github.com/sei-protocol/sei-tendermint v0.2.36-evm-rebase-4/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= diff --git a/proto/cosmos/accesscontrol/constants.proto b/proto/cosmos/accesscontrol/constants.proto index a8820fb48..c4a055b52 100644 --- a/proto/cosmos/accesscontrol/constants.proto +++ b/proto/cosmos/accesscontrol/constants.proto @@ -131,6 +131,21 @@ enum ResourceType { KV_BANK_DEFERRED = 93; // child of KV KV_BANK_DEFERRED_MODULE_TX_INDEX = 95; // child of KV_BANK_DEFERRED + + KV_EVM = 96; // child of KV + KV_EVM_BALANCE = 97; // child of KV_EVM; deprecated + KV_EVM_TRANSIENT = 98; // child of KV_EVM + KV_EVM_ACCOUNT_TRANSIENT = 99; // child of KV_EVM + KV_EVM_MODULE_TRANSIENT = 100; // child of KV_EVM + KV_EVM_NONCE = 101; // child of KV_EVM + KV_EVM_RECEIPT = 102; // child of KV_EVM + KV_EVM_S2E = 103; // child of KV_EVM + KV_EVM_E2S = 104; // child of KV_EVM + KV_EVM_CODE_HASH = 105; // child of KV_EVM + KV_EVM_CODE = 106; // child of KV_EVM + KV_EVM_CODE_SIZE = 107; // child of KV_EVM + + KV_BANK_WEI_BALANCE = 108; // child of KV_BANK } enum WasmMessageSubtype { diff --git a/server/mock/app.go b/server/mock/app.go index 959bce012..5aacd477d 100644 --- a/server/mock/app.go +++ b/server/mock/app.go @@ -2,6 +2,7 @@ package mock import ( "context" + "crypto/sha256" "encoding/json" "errors" "fmt" @@ -39,10 +40,15 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) { baseApp.SetInitChainer(InitChainer(capKeyMainStore)) baseApp.SetFinalizeBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { txResults := []*abci.ExecTxResult{} - for _, tx := range req.Txs { + for _, txbz := range req.Txs { + tx, err := decodeTx(txbz) + if err != nil { + txResults = append(txResults, &abci.ExecTxResult{}) + continue + } deliverTxResp := baseApp.DeliverTx(ctx, abci.RequestDeliverTx{ - Tx: tx, - }) + Tx: txbz, + }, tx, sha256.Sum256(txbz)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/server/mock/store.go b/server/mock/store.go index 0a47cc08c..38f175665 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -226,6 +226,14 @@ func (kv kvStore) ReverseSubspaceIterator(prefix []byte) sdk.Iterator { panic("not implemented") } +func (kv kvStore) VersionExists(version int64) bool { + panic("not implemented") +} + +func (kv kvStore) DeleteAll(start, end []byte) error { + panic("not implemented") +} + func NewCommitMultiStore() sdk.CommitMultiStore { return multiStore{kv: make(map[sdk.StoreKey]kvStore)} } diff --git a/simapp/app.go b/simapp/app.go index 4c0af924c..cb4b031c3 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -2,6 +2,7 @@ package simapp import ( "context" + "crypto/sha256" "encoding/json" "fmt" "io" @@ -515,9 +516,13 @@ func (app *SimApp) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlo txResults := []*abci.ExecTxResult{} for i, tx := range req.Txs { ctx = ctx.WithContext(context.WithValue(ctx.Context(), ante.ContextKeyTxIndexKey, i)) + if typedTxs[i] == nil { + txResults = append(txResults, &abci.ExecTxResult{}) // empty result + continue + } deliverTxResp := app.DeliverTx(ctx, abci.RequestDeliverTx{ Tx: tx, - }) + }, typedTxs[i], sha256.Sum256(tx)) txResults = append(txResults, &abci.ExecTxResult{ Code: deliverTxResp.Code, Data: deliverTxResp.Data, diff --git a/store/cachekv/store.go b/store/cachekv/store.go index 06d491d04..a33adf17c 100644 --- a/store/cachekv/store.go +++ b/store/cachekv/store.go @@ -192,6 +192,10 @@ func (store *Store) iterator(start, end []byte, ascending bool) types.Iterator { return NewCacheMergeIterator(parent, cache, ascending, store.storeKey) } +func (store *Store) VersionExists(version int64) bool { + return store.parent.VersionExists(version) +} + func findStartIndex(strL []string, startQ string) int { // Modified binary search to find the very first element in >=startQ. if len(strL) == 0 { @@ -359,3 +363,22 @@ func (store *Store) isDeleted(key string) bool { _, ok := store.deleted.Load(key) return ok } + +func (store *Store) GetParent() types.KVStore { + return store.parent +} + +func (store *Store) DeleteAll(start, end []byte) error { + store.dirtyItems(start, end) + // memdb iterator + cachedIter, err := store.sortedCache.Iterator(start, end) + if err != nil { + return err + } + defer cachedIter.Close() + for ; cachedIter.Valid(); cachedIter.Next() { + // `Delete` would not touch sortedCache so it's okay to perform inside iterator + store.Delete(cachedIter.Key()) + } + return nil +} diff --git a/store/cachekv/store_test.go b/store/cachekv/store_test.go index 3a6d5ab53..c6e7ab5b6 100644 --- a/store/cachekv/store_test.go +++ b/store/cachekv/store_test.go @@ -62,6 +62,19 @@ func TestCacheKVStore(t *testing.T) { st.Write() require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") require.Empty(t, mem.Get(keyFmt(1)), "Expected `key1` to be empty") + + // GetParent returns parent store + require.NotNil(t, st.GetParent()) + + // DeleteAll deletes all entries in cache but not affect mem + st = cachekv.NewStore(mem, types.NewKVStoreKey("CacheKvTest"), types.DefaultCacheSizeLimit) + mem.Set(keyFmt(1), valFmt(1)) + st.Set(keyFmt(1), valFmt(2)) + st.Set(keyFmt(2), valFmt(3)) + require.Nil(t, st.DeleteAll(nil, nil)) + require.Nil(t, st.Get(keyFmt(1))) + require.Nil(t, st.Get(keyFmt(2))) + require.Equal(t, valFmt(1), mem.Get(keyFmt(1))) } func TestCacheKVStoreNoNilSet(t *testing.T) { diff --git a/store/dbadapter/store.go b/store/dbadapter/store.go index bf0c95364..b8de090f1 100644 --- a/store/dbadapter/store.go +++ b/store/dbadapter/store.go @@ -95,5 +95,22 @@ func (dsa Store) CacheWrapWithListeners(storeKey types.StoreKey, listeners []typ return cachekv.NewStore(listenkv.NewStore(dsa, storeKey, listeners), storeKey, types.DefaultCacheSizeLimit) } +func (dsa Store) VersionExists(version int64) bool { + panic("no versioning for dbadater") +} + +func (dsa Store) DeleteAll(start, end []byte) error { + iter := dsa.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + dsa.Delete(key) + } + return nil +} + // dbm.DB implements KVStore so we can CacheKVStore it. var _ types.KVStore = Store{} diff --git a/store/dbadapter/store_test.go b/store/dbadapter/store_test.go index 467ba6421..f13209cbe 100644 --- a/store/dbadapter/store_test.go +++ b/store/dbadapter/store_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/dbadapter" "github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/tests/mocks" + dbm "github.com/tendermint/tm-db" ) var errFoo = errors.New("dummy") @@ -74,6 +75,17 @@ func TestAccessors(t *testing.T) { require.Panics(t, func() { store.ReverseIterator(start, end) }) } +func TestDeleteAll(t *testing.T) { + mem := dbadapter.Store{DB: dbm.NewMemDB()} + mem.Set([]byte("1"), []byte("2")) + mem.Set([]byte("3"), []byte("4")) + require.NotNil(t, mem.Get([]byte("1"))) + require.NotNil(t, mem.Get([]byte("3"))) + require.Nil(t, mem.DeleteAll(nil, nil)) + require.Nil(t, mem.Get([]byte("1"))) + require.Nil(t, mem.Get([]byte("3"))) +} + func TestCacheWraps(t *testing.T) { mockCtrl := gomock.NewController(t) mockDB := mocks.NewMockDB(mockCtrl) diff --git a/store/gaskv/store.go b/store/gaskv/store.go index 0aa9f4282..62e3d89c4 100644 --- a/store/gaskv/store.go +++ b/store/gaskv/store.go @@ -126,6 +126,14 @@ func (gs *Store) iterator(start, end []byte, ascending bool) types.Iterator { return gi } +func (gs *Store) VersionExists(version int64) bool { + return gs.parent.VersionExists(version) +} + +func (gs *Store) DeleteAll(start, end []byte) error { + return gs.parent.DeleteAll(start, end) +} + type gasIterator struct { gasMeter types.GasMeter gasConfig types.GasConfig diff --git a/store/iavl/store.go b/store/iavl/store.go index 3bcc9af97..2d5bfad88 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -423,6 +423,19 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} + // Takes a MutableTree, a key, and a flag for creating existence or absence proof and returns the // appropriate merkle.Proof. Since this must be called after querying for the value, this function should never error // Thus, it will panic on error rather than returning it diff --git a/store/iavl/store_test.go b/store/iavl/store_test.go index 3cf0194e9..de56b4277 100644 --- a/store/iavl/store_test.go +++ b/store/iavl/store_test.go @@ -463,6 +463,21 @@ func TestIAVLNoPrune(t *testing.T) { } } +func TestIAVLStoreDeleteAll(t *testing.T) { + db := dbm.NewMemDB() + tree, err := iavl.NewMutableTree(db, cacheSize, false) + require.NoError(t, err) + + iavlStore := UnsafeNewStore(tree) + iavlStore.Set([]byte("1"), []byte("2")) + iavlStore.Set([]byte("3"), []byte("4")) + require.NotNil(t, iavlStore.Get([]byte("1"))) + require.NotNil(t, iavlStore.Get([]byte("3"))) + require.Nil(t, iavlStore.DeleteAll(nil, nil)) + require.Nil(t, iavlStore.Get([]byte("1"))) + require.Nil(t, iavlStore.Get([]byte("3"))) +} + func TestIAVLStoreQuery(t *testing.T) { db := dbm.NewMemDB() tree, err := iavl.NewMutableTree(db, cacheSize, false) diff --git a/store/listenkv/store.go b/store/listenkv/store.go index bf49b1282..20f103ec0 100644 --- a/store/listenkv/store.go +++ b/store/listenkv/store.go @@ -81,6 +81,10 @@ func (s *Store) iterator(start, end []byte, ascending bool) types.Iterator { return newTraceIterator(parent, s.listeners) } +func (s *Store) VersionExists(version int64) bool { + return s.parent.VersionExists(version) +} + type listenIterator struct { parent types.Iterator listeners []types.WriteListener @@ -157,3 +161,7 @@ func (s *Store) onWrite(delete bool, key, value []byte) { l.OnWrite(s.parentStoreKey, key, value, delete) } } + +func (s *Store) DeleteAll(start, end []byte) error { + return s.parent.DeleteAll(start, end) +} diff --git a/store/prefix/store.go b/store/prefix/store.go index f6c29fd15..fd1f2672b 100644 --- a/store/prefix/store.go +++ b/store/prefix/store.go @@ -90,6 +90,18 @@ func (s Store) Delete(key []byte) { s.parent.Delete(s.key(key)) } +func (s Store) DeleteAll(start, end []byte) error { + newstart := cloneAppend(s.prefix, start) + + var newend []byte + if end == nil { + newend = cpIncr(s.prefix) + } else { + newend = cloneAppend(s.prefix, end) + } + return s.parent.DeleteAll(newstart, newend) +} + // Implements KVStore // Check https://github.com/tendermint/tendermint/blob/master/libs/db/prefix_db.go#L106 func (s Store) Iterator(start, end []byte) types.Iterator { @@ -124,6 +136,10 @@ func (s Store) ReverseIterator(start, end []byte) types.Iterator { return newPrefixIterator(s.prefix, start, end, iter) } +func (s Store) VersionExists(version int64) bool { + return s.parent.VersionExists(version) +} + var _ types.Iterator = (*prefixIterator)(nil) type prefixIterator struct { diff --git a/store/tracekv/store.go b/store/tracekv/store.go index 2798d90ec..81fe2034c 100644 --- a/store/tracekv/store.go +++ b/store/tracekv/store.go @@ -182,6 +182,14 @@ func (tkv *Store) CacheWrapWithListeners(_ types.StoreKey, _ []types.WriteListen panic("cannot CacheWrapWithListeners a TraceKVStore") } +func (tkv *Store) VersionExists(version int64) bool { + return tkv.parent.VersionExists(version) +} + +func (tkv *Store) DeleteAll(start, end []byte) error { + return tkv.parent.DeleteAll(start, end) +} + // writeOperation writes a KVStore operation to the underlying io.Writer as // JSON-encoded data where the key/value pair is base64 encoded. func writeOperation(w io.Writer, op operation, tc types.TraceContext, key, value []byte) { diff --git a/store/types/store.go b/store/types/store.go index 19115ab72..9a3df3c03 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -247,6 +247,10 @@ type KVStore interface { ReverseIterator(start, end []byte) Iterator GetWorkingHash() ([]byte, error) + + VersionExists(version int64) bool + + DeleteAll(start, end []byte) error } // Iterator is an alias db's Iterator for convenience. diff --git a/storev2/commitment/store.go b/storev2/commitment/store.go index a51073875..f48362873 100644 --- a/storev2/commitment/store.go +++ b/storev2/commitment/store.go @@ -177,3 +177,21 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } + +func (st *Store) VersionExists(version int64) bool { + // one version per SC tree + return version == st.tree.Version() +} + +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} diff --git a/storev2/rootmulti/store.go b/storev2/rootmulti/store.go index 89076e7d1..be7f4f2af 100644 --- a/storev2/rootmulti/store.go +++ b/storev2/rootmulti/store.go @@ -237,6 +237,8 @@ func (rs *Store) CacheMultiStoreWithVersion(version int64) (types.CacheMultiStor if version <= 0 || (rs.lastCommitInfo != nil && version == rs.lastCommitInfo.Version) { return rs.CacheMultiStore(), nil } + rs.mtx.RLock() + defer rs.mtx.RUnlock() stores := make(map[types.StoreKey]types.CacheWrapper) // add the transient/mem stores registered in current app. for k, store := range rs.ckvStores { diff --git a/storev2/state/store.go b/storev2/state/store.go index 72e4b0ce9..d59a310cb 100644 --- a/storev2/state/store.go +++ b/storev2/state/store.go @@ -1,10 +1,11 @@ package state import ( - "cosmossdk.io/errors" "fmt" "io" + "cosmossdk.io/errors" + "github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/listenkv" "github.com/cosmos/cosmos-sdk/store/tracekv" @@ -125,3 +126,24 @@ func (st *Store) Query(req abci.RequestQuery) (res abci.ResponseQuery) { return res } + +func (st *Store) VersionExists(version int64) bool { + earliest, err := st.store.GetEarliestVersion() + if err != nil { + panic(err) + } + return version >= earliest +} + +func (st *Store) DeleteAll(start, end []byte) error { + iter := st.Iterator(start, end) + keys := [][]byte{} + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + iter.Close() + for _, key := range keys { + st.Delete(key) + } + return nil +} diff --git a/types/accesscontrol/constants.pb.go b/types/accesscontrol/constants.pb.go index 1625561ed..4867c0837 100644 --- a/types/accesscontrol/constants.pb.go +++ b/types/accesscontrol/constants.pb.go @@ -195,101 +195,127 @@ const ( ResourceType_KV_DEX_SHORT_ORDER_COUNT ResourceType = 92 ResourceType_KV_BANK_DEFERRED ResourceType = 93 ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX ResourceType = 95 + ResourceType_KV_EVM ResourceType = 96 + ResourceType_KV_EVM_BALANCE ResourceType = 97 + ResourceType_KV_EVM_TRANSIENT ResourceType = 98 + ResourceType_KV_EVM_ACCOUNT_TRANSIENT ResourceType = 99 + ResourceType_KV_EVM_MODULE_TRANSIENT ResourceType = 100 + ResourceType_KV_EVM_NONCE ResourceType = 101 + ResourceType_KV_EVM_RECEIPT ResourceType = 102 + ResourceType_KV_EVM_S2E ResourceType = 103 + ResourceType_KV_EVM_E2S ResourceType = 104 + ResourceType_KV_EVM_CODE_HASH ResourceType = 105 + ResourceType_KV_EVM_CODE ResourceType = 106 + ResourceType_KV_EVM_CODE_SIZE ResourceType = 107 + ResourceType_KV_BANK_WEI_BALANCE ResourceType = 108 ) var ResourceType_name = map[int32]string{ - 0: "ANY", - 1: "KV", - 2: "Mem", - 3: "DexMem", - 4: "KV_BANK", - 5: "KV_STAKING", - 6: "KV_WASM", - 7: "KV_ORACLE", - 8: "KV_DEX", - 9: "KV_EPOCH", - 10: "KV_TOKENFACTORY", - 11: "KV_ORACLE_VOTE_TARGETS", - 12: "KV_ORACLE_AGGREGATE_VOTES", - 13: "KV_ORACLE_FEEDERS", - 14: "KV_STAKING_DELEGATION", - 15: "KV_STAKING_VALIDATOR", - 16: "KV_AUTH", - 17: "KV_AUTH_ADDRESS_STORE", - 18: "KV_BANK_SUPPLY", - 19: "KV_BANK_DENOM", - 20: "KV_BANK_BALANCES", - 21: "KV_TOKENFACTORY_DENOM", - 22: "KV_TOKENFACTORY_METADATA", - 23: "KV_TOKENFACTORY_ADMIN", - 24: "KV_TOKENFACTORY_CREATOR", - 25: "KV_ORACLE_EXCHANGE_RATE", - 26: "KV_ORACLE_VOTE_PENALTY_COUNTER", - 27: "KV_ORACLE_PRICE_SNAPSHOT", - 28: "KV_STAKING_VALIDATION_POWER", - 29: "KV_STAKING_TOTAL_POWER", - 30: "KV_STAKING_VALIDATORS_CON_ADDR", - 31: "KV_STAKING_UNBONDING_DELEGATION", - 32: "KV_STAKING_UNBONDING_DELEGATION_VAL", - 33: "KV_STAKING_REDELEGATION", - 34: "KV_STAKING_REDELEGATION_VAL_SRC", - 35: "KV_STAKING_REDELEGATION_VAL_DST", - 36: "KV_STAKING_REDELEGATION_QUEUE", - 37: "KV_STAKING_VALIDATOR_QUEUE", - 38: "KV_STAKING_HISTORICAL_INFO", - 39: "KV_STAKING_UNBONDING", - 41: "KV_STAKING_VALIDATORS_BY_POWER", - 40: "KV_DISTRIBUTION", - 42: "KV_DISTRIBUTION_FEE_POOL", - 43: "KV_DISTRIBUTION_PROPOSER_KEY", - 44: "KV_DISTRIBUTION_OUTSTANDING_REWARDS", - 45: "KV_DISTRIBUTION_DELEGATOR_WITHDRAW_ADDR", - 46: "KV_DISTRIBUTION_DELEGATOR_STARTING_INFO", - 47: "KV_DISTRIBUTION_VAL_HISTORICAL_REWARDS", - 48: "KV_DISTRIBUTION_VAL_CURRENT_REWARDS", - 49: "KV_DISTRIBUTION_VAL_ACCUM_COMMISSION", - 50: "KV_DISTRIBUTION_SLASH_EVENT", - 51: "KV_DEX_CONTRACT_LONGBOOK", - 52: "KV_DEX_CONTRACT_SHORTBOOK", - 53: "KV_DEX_SETTLEMENT", - 54: "KV_DEX_PAIR_PREFIX", - 55: "KV_DEX_TWAP", - 56: "KV_DEX_PRICE", - 57: "KV_DEX_SETTLEMENT_ENTRY", - 58: "KV_DEX_REGISTERED_PAIR", - 60: "KV_DEX_ORDER", - 61: "KV_DEX_CANCEL", - 62: "KV_DEX_ACCOUNT_ACTIVE_ORDERS", - 64: "KV_DEX_ASSET_LIST", - 65: "KV_DEX_NEXT_ORDER_ID", - 66: "KV_DEX_NEXT_SETTLEMENT_ID", - 67: "KV_DEX_MATCH_RESULT", - 68: "KV_DEX_SETTLEMENT_ORDER_ID", - 69: "KV_DEX_ORDER_BOOK", - 71: "KV_ACCESSCONTROL", - 72: "KV_ACCESSCONTROL_WASM_DEPENDENCY_MAPPING", - 73: "KV_WASM_CODE", - 74: "KV_WASM_CONTRACT_ADDRESS", - 75: "KV_WASM_CONTRACT_STORE", - 76: "KV_WASM_SEQUENCE_KEY", - 77: "KV_WASM_CONTRACT_CODE_HISTORY", - 78: "KV_WASM_CONTRACT_BY_CODE_ID", - 79: "KV_WASM_PINNED_CODE_INDEX", - 80: "KV_AUTH_GLOBAL_ACCOUNT_NUMBER", - 81: "KV_AUTHZ", - 82: "KV_FEEGRANT", - 83: "KV_FEEGRANT_ALLOWANCE", - 84: "KV_SLASHING", - 85: "KV_SLASHING_VAL_SIGNING_INFO", - 86: "KV_SLASHING_ADDR_PUBKEY_RELATION_KEY", - 87: "KV_DEX_MEM_ORDER", - 88: "KV_DEX_MEM_CANCEL", - 89: "KV_DEX_MEM_DEPOSIT", - 90: "KV_DEX_CONTRACT", - 91: "KV_DEX_LONG_ORDER_COUNT", - 92: "KV_DEX_SHORT_ORDER_COUNT", - 93: "KV_BANK_DEFERRED", - 95: "KV_BANK_DEFERRED_MODULE_TX_INDEX", + 0: "ANY", + 1: "KV", + 2: "Mem", + 3: "DexMem", + 4: "KV_BANK", + 5: "KV_STAKING", + 6: "KV_WASM", + 7: "KV_ORACLE", + 8: "KV_DEX", + 9: "KV_EPOCH", + 10: "KV_TOKENFACTORY", + 11: "KV_ORACLE_VOTE_TARGETS", + 12: "KV_ORACLE_AGGREGATE_VOTES", + 13: "KV_ORACLE_FEEDERS", + 14: "KV_STAKING_DELEGATION", + 15: "KV_STAKING_VALIDATOR", + 16: "KV_AUTH", + 17: "KV_AUTH_ADDRESS_STORE", + 18: "KV_BANK_SUPPLY", + 19: "KV_BANK_DENOM", + 20: "KV_BANK_BALANCES", + 21: "KV_TOKENFACTORY_DENOM", + 22: "KV_TOKENFACTORY_METADATA", + 23: "KV_TOKENFACTORY_ADMIN", + 24: "KV_TOKENFACTORY_CREATOR", + 25: "KV_ORACLE_EXCHANGE_RATE", + 26: "KV_ORACLE_VOTE_PENALTY_COUNTER", + 27: "KV_ORACLE_PRICE_SNAPSHOT", + 28: "KV_STAKING_VALIDATION_POWER", + 29: "KV_STAKING_TOTAL_POWER", + 30: "KV_STAKING_VALIDATORS_CON_ADDR", + 31: "KV_STAKING_UNBONDING_DELEGATION", + 32: "KV_STAKING_UNBONDING_DELEGATION_VAL", + 33: "KV_STAKING_REDELEGATION", + 34: "KV_STAKING_REDELEGATION_VAL_SRC", + 35: "KV_STAKING_REDELEGATION_VAL_DST", + 36: "KV_STAKING_REDELEGATION_QUEUE", + 37: "KV_STAKING_VALIDATOR_QUEUE", + 38: "KV_STAKING_HISTORICAL_INFO", + 39: "KV_STAKING_UNBONDING", + 41: "KV_STAKING_VALIDATORS_BY_POWER", + 40: "KV_DISTRIBUTION", + 42: "KV_DISTRIBUTION_FEE_POOL", + 43: "KV_DISTRIBUTION_PROPOSER_KEY", + 44: "KV_DISTRIBUTION_OUTSTANDING_REWARDS", + 45: "KV_DISTRIBUTION_DELEGATOR_WITHDRAW_ADDR", + 46: "KV_DISTRIBUTION_DELEGATOR_STARTING_INFO", + 47: "KV_DISTRIBUTION_VAL_HISTORICAL_REWARDS", + 48: "KV_DISTRIBUTION_VAL_CURRENT_REWARDS", + 49: "KV_DISTRIBUTION_VAL_ACCUM_COMMISSION", + 50: "KV_DISTRIBUTION_SLASH_EVENT", + 51: "KV_DEX_CONTRACT_LONGBOOK", + 52: "KV_DEX_CONTRACT_SHORTBOOK", + 53: "KV_DEX_SETTLEMENT", + 54: "KV_DEX_PAIR_PREFIX", + 55: "KV_DEX_TWAP", + 56: "KV_DEX_PRICE", + 57: "KV_DEX_SETTLEMENT_ENTRY", + 58: "KV_DEX_REGISTERED_PAIR", + 60: "KV_DEX_ORDER", + 61: "KV_DEX_CANCEL", + 62: "KV_DEX_ACCOUNT_ACTIVE_ORDERS", + 64: "KV_DEX_ASSET_LIST", + 65: "KV_DEX_NEXT_ORDER_ID", + 66: "KV_DEX_NEXT_SETTLEMENT_ID", + 67: "KV_DEX_MATCH_RESULT", + 68: "KV_DEX_SETTLEMENT_ORDER_ID", + 69: "KV_DEX_ORDER_BOOK", + 71: "KV_ACCESSCONTROL", + 72: "KV_ACCESSCONTROL_WASM_DEPENDENCY_MAPPING", + 73: "KV_WASM_CODE", + 74: "KV_WASM_CONTRACT_ADDRESS", + 75: "KV_WASM_CONTRACT_STORE", + 76: "KV_WASM_SEQUENCE_KEY", + 77: "KV_WASM_CONTRACT_CODE_HISTORY", + 78: "KV_WASM_CONTRACT_BY_CODE_ID", + 79: "KV_WASM_PINNED_CODE_INDEX", + 80: "KV_AUTH_GLOBAL_ACCOUNT_NUMBER", + 81: "KV_AUTHZ", + 82: "KV_FEEGRANT", + 83: "KV_FEEGRANT_ALLOWANCE", + 84: "KV_SLASHING", + 85: "KV_SLASHING_VAL_SIGNING_INFO", + 86: "KV_SLASHING_ADDR_PUBKEY_RELATION_KEY", + 87: "KV_DEX_MEM_ORDER", + 88: "KV_DEX_MEM_CANCEL", + 89: "KV_DEX_MEM_DEPOSIT", + 90: "KV_DEX_CONTRACT", + 91: "KV_DEX_LONG_ORDER_COUNT", + 92: "KV_DEX_SHORT_ORDER_COUNT", + 93: "KV_BANK_DEFERRED", + 95: "KV_BANK_DEFERRED_MODULE_TX_INDEX", + 96: "KV_EVM", + 97: "KV_EVM_BALANCE", + 98: "KV_EVM_TRANSIENT", + 99: "KV_EVM_ACCOUNT_TRANSIENT", + 100: "KV_EVM_MODULE_TRANSIENT", + 101: "KV_EVM_NONCE", + 102: "KV_EVM_RECEIPT", + 103: "KV_EVM_S2E", + 104: "KV_EVM_E2S", + 105: "KV_EVM_CODE_HASH", + 106: "KV_EVM_CODE", + 107: "KV_EVM_CODE_SIZE", + 108: "KV_BANK_WEI_BALANCE", } var ResourceType_value = map[string]int32{ @@ -385,6 +411,19 @@ var ResourceType_value = map[string]int32{ "KV_DEX_SHORT_ORDER_COUNT": 92, "KV_BANK_DEFERRED": 93, "KV_BANK_DEFERRED_MODULE_TX_INDEX": 95, + "KV_EVM": 96, + "KV_EVM_BALANCE": 97, + "KV_EVM_TRANSIENT": 98, + "KV_EVM_ACCOUNT_TRANSIENT": 99, + "KV_EVM_MODULE_TRANSIENT": 100, + "KV_EVM_NONCE": 101, + "KV_EVM_RECEIPT": 102, + "KV_EVM_S2E": 103, + "KV_EVM_E2S": 104, + "KV_EVM_CODE_HASH": 105, + "KV_EVM_CODE": 106, + "KV_EVM_CODE_SIZE": 107, + "KV_BANK_WEI_BALANCE": 108, } func (x ResourceType) String() string { @@ -432,96 +471,103 @@ func init() { } var fileDescriptor_36568f7561081112 = []byte{ - // 1445 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x56, 0x5b, 0x73, 0x13, 0xbf, - 0x15, 0xcf, 0xfd, 0xa2, 0x04, 0x38, 0x28, 0xdc, 0x13, 0x0c, 0x84, 0x14, 0x68, 0x80, 0x84, 0x4b, - 0xaf, 0xd0, 0x96, 0xca, 0xab, 0x63, 0x7b, 0xe3, 0x5d, 0x69, 0x2d, 0x69, 0x7d, 0xa1, 0xed, 0x68, - 0x12, 0xd7, 0x43, 0x99, 0x92, 0x98, 0x89, 0x4d, 0xa7, 0xfd, 0x0c, 0x7d, 0xe9, 0xc7, 0xea, 0x23, - 0x8f, 0x7d, 0x64, 0xe0, 0x8b, 0x74, 0xb4, 0x2b, 0x9b, 0xb5, 0x09, 0x7f, 0x9e, 0x12, 0x9f, 0xdf, - 0x4f, 0x67, 0x75, 0x7e, 0xe7, 0x26, 0xb2, 0xd3, 0xed, 0x0f, 0x8e, 0xfb, 0x83, 0xfd, 0xc3, 0x6e, - 0xb7, 0x37, 0x18, 0x74, 0xfb, 0x27, 0xc3, 0xd3, 0xfe, 0xbb, 0xfd, 0x6e, 0xff, 0x64, 0x30, 0x3c, - 0x3c, 0x19, 0x0e, 0xf6, 0xde, 0x9f, 0xf6, 0x87, 0x7d, 0xba, 0x95, 0xb3, 0xf6, 0x26, 0x58, 0x7b, - 0xff, 0x78, 0x7a, 0xd4, 0x1b, 0x1e, 0x3e, 0xdd, 0x7d, 0x41, 0x08, 0xcb, 0x00, 0xf3, 0xaf, 0xf7, - 0x3d, 0xba, 0x46, 0x96, 0x53, 0x51, 0x17, 0xb2, 0x25, 0x60, 0x86, 0xae, 0x90, 0x05, 0x85, 0x8c, - 0xc3, 0x2c, 0x5d, 0x25, 0x8b, 0x2d, 0x15, 0x1a, 0x84, 0x39, 0x4a, 0xc8, 0x52, 0x20, 0xe3, 0x38, - 0x34, 0x30, 0xbf, 0xfb, 0xef, 0x39, 0xb2, 0x99, 0x1f, 0x96, 0xef, 0x7b, 0xa7, 0x87, 0xc3, 0xb7, - 0xfd, 0x13, 0xdd, 0x7b, 0xd7, 0xeb, 0x0e, 0xfb, 0xa7, 0x99, 0xb7, 0x15, 0xb2, 0x20, 0xa4, 0x40, - 0x98, 0xa1, 0x4b, 0x64, 0xee, 0xa0, 0x01, 0xb3, 0xf4, 0x32, 0xb9, 0x78, 0xd0, 0xb0, 0x65, 0x0c, - 0x6a, 0xcf, 0x9f, 0x59, 0xc6, 0xb9, 0x42, 0xad, 0x61, 0x8e, 0x96, 0xc8, 0x8d, 0x83, 0x86, 0x8d, - 0x50, 0x54, 0x4d, 0xcd, 0x26, 0x0a, 0x2b, 0x61, 0x1b, 0xf9, 0x18, 0x9f, 0xa7, 0xd7, 0xc9, 0x65, - 0x8d, 0x82, 0xa3, 0x9a, 0x3e, 0xba, 0x40, 0xb7, 0x49, 0xc9, 0x43, 0xdf, 0x3b, 0xbe, 0x48, 0x2f, - 0x11, 0x08, 0xa4, 0x30, 0x8a, 0x05, 0x66, 0x6c, 0x5d, 0xa2, 0x37, 0xc8, 0x95, 0x83, 0x86, 0x8d, - 0x51, 0x6b, 0x56, 0x45, 0x1b, 0x48, 0xc1, 0x43, 0x13, 0x4a, 0xc1, 0x22, 0x58, 0x76, 0x58, 0x20, - 0x85, 0x36, 0x4c, 0x18, 0xab, 0x8d, 0x0a, 0x45, 0xd5, 0x1a, 0x69, 0x6b, 0xd8, 0x86, 0x15, 0x7a, - 0x85, 0xd0, 0xb1, 0x37, 0x85, 0x15, 0x54, 0x28, 0x02, 0x84, 0xd5, 0xdd, 0x4f, 0x1b, 0x64, 0x5d, - 0xf5, 0x06, 0xfd, 0x0f, 0xa7, 0xdd, 0x5e, 0x16, 0xfe, 0x32, 0x99, 0x67, 0xa2, 0x93, 0x47, 0x5f, - 0x6f, 0xc2, 0xac, 0x33, 0xc4, 0xbd, 0xe3, 0x5c, 0x44, 0xde, 0xfb, 0xa7, 0xfb, 0x7f, 0xde, 0x49, - 0x5e, 0x6f, 0xda, 0x32, 0x13, 0x75, 0x58, 0xa0, 0xe7, 0x09, 0xa9, 0x37, 0xad, 0x36, 0xac, 0x1e, - 0x8a, 0x2a, 0x2c, 0x7a, 0xb0, 0xc5, 0x74, 0x0c, 0x4b, 0xf4, 0x1c, 0x59, 0xad, 0x37, 0xad, 0x54, - 0x2c, 0x88, 0x10, 0x96, 0x9d, 0x93, 0x7a, 0xd3, 0xf2, 0xec, 0x4e, 0xeb, 0x64, 0xa5, 0xde, 0xb4, - 0x98, 0xc8, 0xa0, 0x06, 0xab, 0x74, 0x83, 0x5c, 0xa8, 0x37, 0xad, 0x91, 0x75, 0x14, 0x15, 0x16, - 0x18, 0xa9, 0x3a, 0x40, 0x5c, 0x48, 0xe3, 0xd3, 0xb6, 0x29, 0x0d, 0x5a, 0xc3, 0x54, 0x15, 0x8d, - 0x86, 0x35, 0x7a, 0x93, 0x5c, 0xff, 0x8a, 0xb1, 0x6a, 0x55, 0x61, 0x95, 0x99, 0x9c, 0xa5, 0x61, - 0xdd, 0x65, 0xed, 0x2b, 0x5c, 0x41, 0xe4, 0xa8, 0x34, 0x9c, 0x73, 0x59, 0xf9, 0x7a, 0x59, 0xcb, - 0x31, 0x72, 0xa7, 0x42, 0x29, 0xe0, 0x3c, 0xbd, 0x46, 0x2e, 0x15, 0xa0, 0x26, 0x8b, 0x42, 0xce, - 0x8c, 0x54, 0x70, 0xc1, 0x47, 0xc4, 0x52, 0x53, 0x03, 0xf0, 0x1e, 0xdc, 0x8f, 0x51, 0x5e, 0xac, - 0x36, 0x52, 0x21, 0x5c, 0xa4, 0x94, 0x9c, 0xf7, 0xb2, 0x58, 0x9d, 0x26, 0x49, 0xd4, 0x01, 0x4a, - 0x2f, 0x92, 0x73, 0x23, 0x1b, 0x47, 0x21, 0x63, 0xd8, 0x70, 0xa9, 0x1d, 0x99, 0xca, 0x2c, 0x62, - 0x22, 0x40, 0x0d, 0x97, 0xbc, 0xdf, 0xa2, 0x00, 0xfe, 0xc0, 0x65, 0xba, 0x45, 0xae, 0x4d, 0x43, - 0x31, 0x1a, 0xc6, 0x99, 0x61, 0x70, 0xe5, 0xac, 0x83, 0x8c, 0xc7, 0xa1, 0x80, 0xab, 0x74, 0x93, - 0x5c, 0x9d, 0x86, 0x02, 0x85, 0x59, 0x54, 0xd7, 0x3c, 0xe8, 0x15, 0xc2, 0x76, 0x50, 0x63, 0xa2, - 0x8a, 0x56, 0x31, 0x83, 0x70, 0xdd, 0x95, 0xe8, 0x94, 0xf2, 0x09, 0x0a, 0x16, 0x99, 0x8e, 0x0d, - 0x64, 0x2a, 0x0c, 0x2a, 0xb8, 0xe1, 0xaf, 0xe5, 0x39, 0x89, 0x0a, 0x03, 0xb4, 0x5a, 0xb0, 0x44, - 0xd7, 0xa4, 0x81, 0x4d, 0x7a, 0x8b, 0x6c, 0x7e, 0x2b, 0x67, 0x28, 0x85, 0x4d, 0x64, 0x0b, 0x15, - 0x6c, 0xf9, 0xe4, 0x8e, 0x08, 0x46, 0x1a, 0x16, 0x79, 0xec, 0xa6, 0xff, 0xfc, 0x37, 0xb9, 0xd0, - 0xae, 0xe4, 0x33, 0xd9, 0xa1, 0x44, 0xef, 0x92, 0x5b, 0x05, 0x4e, 0x2a, 0xca, 0xae, 0x1b, 0x26, - 0x93, 0x7a, 0x8b, 0xde, 0x27, 0x77, 0x7f, 0x40, 0x72, 0xde, 0xe1, 0xb6, 0x57, 0x63, 0x44, 0x54, - 0x58, 0xf0, 0x72, 0x67, 0xea, 0x53, 0x45, 0xd0, 0x9d, 0xb6, 0x5a, 0x05, 0xb0, 0xfd, 0x23, 0x12, - 0xd7, 0x06, 0xee, 0xd2, 0x3b, 0xe4, 0xe6, 0xf7, 0x48, 0x8d, 0x14, 0x53, 0x84, 0x1d, 0x37, 0x58, - 0xce, 0x8a, 0xdd, 0xe3, 0x3f, 0x9b, 0xc2, 0x6b, 0xa1, 0xab, 0xbe, 0x30, 0x60, 0x91, 0x0d, 0x45, - 0x45, 0xc2, 0xbd, 0xa9, 0x3a, 0x1e, 0x87, 0x0c, 0xf7, 0xbf, 0xaf, 0x6a, 0xb9, 0xe3, 0x95, 0xff, - 0xb9, 0xef, 0x43, 0x1e, 0xba, 0x09, 0x52, 0x4e, 0xb3, 0xf8, 0x1f, 0xf8, 0x4c, 0x17, 0x8d, 0xae, - 0xa5, 0x6c, 0x22, 0x65, 0x04, 0xbb, 0xf4, 0x36, 0xd9, 0x9a, 0x46, 0x13, 0x25, 0x13, 0xa9, 0x51, - 0xd9, 0x3a, 0x76, 0xe0, 0xa1, 0xcf, 0xc2, 0x04, 0x43, 0xa6, 0xc6, 0x8d, 0x2a, 0x9e, 0xcb, 0xd0, - 0x62, 0x8a, 0x6b, 0x78, 0x44, 0x1f, 0x92, 0xfb, 0xd3, 0x44, 0xaf, 0x90, 0x54, 0xb6, 0x15, 0x9a, - 0x1a, 0x57, 0xac, 0x95, 0x17, 0xc0, 0xe3, 0x9f, 0x26, 0x6b, 0xc3, 0x94, 0x71, 0xce, 0x33, 0x55, - 0xf6, 0xe8, 0x2e, 0xb9, 0x37, 0x4d, 0x76, 0x59, 0x29, 0xc8, 0x37, 0xba, 0xc5, 0xfe, 0x59, 0xd7, - 0x75, 0xdc, 0x20, 0x55, 0x0a, 0x85, 0x19, 0x13, 0x9f, 0xd0, 0x07, 0x64, 0xe7, 0x2c, 0x22, 0x0b, - 0x82, 0x34, 0xb6, 0xd9, 0xca, 0xd1, 0xda, 0x29, 0xf8, 0xd4, 0x77, 0xc3, 0x04, 0x53, 0x47, 0x4c, - 0xd7, 0x2c, 0x36, 0x51, 0x18, 0x78, 0x36, 0x92, 0x18, 0xdb, 0x76, 0x3c, 0xa8, 0x23, 0x29, 0xaa, - 0x65, 0x29, 0xeb, 0xf0, 0xdc, 0x0f, 0xbb, 0x09, 0x54, 0xd7, 0xa4, 0x32, 0x19, 0xfc, 0x0b, 0x3f, - 0xec, 0x1c, 0xac, 0xd1, 0x98, 0x08, 0x63, 0xe7, 0xf3, 0x97, 0x6e, 0xea, 0x7b, 0x73, 0xc2, 0x42, - 0xe5, 0xb7, 0x0c, 0xfc, 0x8a, 0x5e, 0x20, 0x6b, 0xde, 0x6e, 0x5a, 0x2c, 0x81, 0x5f, 0x53, 0x20, - 0xeb, 0x23, 0xa2, 0x6b, 0x63, 0xf8, 0x8d, 0x6f, 0x87, 0x49, 0x8f, 0x16, 0x85, 0x51, 0x1d, 0xf8, - 0xad, 0xef, 0x5c, 0x07, 0x2a, 0xac, 0x86, 0xda, 0xa0, 0x42, 0x9e, 0x7d, 0x02, 0x5e, 0x14, 0x5c, - 0x49, 0xc5, 0x51, 0xc1, 0xef, 0xfc, 0x04, 0xcc, 0xee, 0xee, 0x66, 0x5d, 0x04, 0xbf, 0x1f, 0x55, - 0x0c, 0xb6, 0x9d, 0x54, 0x6e, 0x9e, 0x58, 0x16, 0x98, 0xb0, 0x89, 0xf9, 0x19, 0x0d, 0x7f, 0x28, - 0x44, 0xc4, 0xb4, 0x46, 0x63, 0xa3, 0x50, 0x1b, 0xf8, 0xa3, 0xaf, 0x6d, 0x67, 0x16, 0xd8, 0x36, - 0x39, 0xdd, 0x86, 0x1c, 0x58, 0x41, 0xa1, 0x0c, 0x29, 0xdc, 0x3a, 0xe4, 0x50, 0xa6, 0x57, 0xc9, - 0x86, 0x87, 0x63, 0x66, 0x82, 0x9a, 0x55, 0xa8, 0xd3, 0xc8, 0x40, 0xe0, 0xbb, 0x69, 0x2a, 0xd0, - 0xb1, 0x5f, 0x5e, 0xb8, 0x48, 0x6e, 0xcc, 0x14, 0x47, 0x3f, 0xc3, 0x59, 0x10, 0xa0, 0xd6, 0x59, - 0x4a, 0x64, 0x04, 0x55, 0xfa, 0x88, 0x3c, 0x98, 0xb6, 0x66, 0x8b, 0xd0, 0x72, 0x4c, 0xdc, 0xc2, - 0x17, 0x41, 0xc7, 0xc6, 0x2c, 0x49, 0x5c, 0x3b, 0xd6, 0xbc, 0x54, 0x19, 0x1e, 0x48, 0x8e, 0x10, - 0xfa, 0x22, 0xf0, 0x96, 0xa9, 0xe5, 0x7f, 0xe0, 0x65, 0x9f, 0x44, 0xf3, 0xd5, 0x53, 0xf7, 0xc2, - 0x64, 0x98, 0xc6, 0x46, 0xea, 0xd6, 0x7b, 0xd6, 0x7b, 0x91, 0x9f, 0x38, 0x93, 0xa7, 0xdc, 0xe7, - 0x7c, 0xe9, 0x77, 0x20, 0xf6, 0xc5, 0x39, 0x49, 0x29, 0x77, 0x72, 0x56, 0xc8, 0x41, 0x78, 0x71, - 0x33, 0x42, 0x12, 0x0a, 0x81, 0xdc, 0x63, 0xc2, 0x6d, 0x72, 0xe9, 0x3f, 0x91, 0xad, 0xc4, 0x6a, - 0x24, 0xcb, 0x79, 0x07, 0x64, 0x69, 0x15, 0x69, 0x5c, 0x46, 0x05, 0x89, 0x5f, 0xf6, 0x8e, 0xf2, - 0x1a, 0x1a, 0xbe, 0x00, 0x2b, 0x88, 0x55, 0xc5, 0x84, 0x01, 0xe5, 0x77, 0xd8, 0xc8, 0x60, 0x59, - 0x14, 0xc9, 0x96, 0x2b, 0x16, 0xd0, 0x9e, 0x9b, 0x35, 0x8b, 0x93, 0xcd, 0xf8, 0xe2, 0x19, 0x19, - 0xf2, 0x01, 0x1c, 0x56, 0xc5, 0xb8, 0xd7, 0x53, 0xdf, 0x96, 0x63, 0x86, 0x53, 0xd0, 0x26, 0x69, - 0xb9, 0x8e, 0x1d, 0xab, 0x30, 0xca, 0xa7, 0xad, 0x13, 0xa7, 0xe9, 0xd3, 0x98, 0x95, 0x05, 0xc6, - 0xbe, 0x62, 0x5b, 0x85, 0x9c, 0x3b, 0xab, 0xaf, 0xda, 0x76, 0xa1, 0x9d, 0x9c, 0x99, 0x63, 0x22, - 0x75, 0x68, 0xa0, 0x33, 0x1a, 0x99, 0x85, 0xe6, 0x84, 0xd7, 0x85, 0x06, 0x72, 0x6d, 0xec, 0x8b, - 0x27, 0x13, 0x05, 0xfe, 0x54, 0x68, 0xf6, 0xac, 0x8b, 0x27, 0xd0, 0x3f, 0x17, 0xdf, 0x07, 0xdc, - 0xbd, 0xd5, 0x14, 0x72, 0xf8, 0x0b, 0xdd, 0x21, 0xb7, 0xa7, 0xad, 0x36, 0x96, 0x3c, 0x8d, 0xd0, - 0x9a, 0xb6, 0x4f, 0x85, 0xdd, 0x5e, 0x58, 0x79, 0x09, 0x2f, 0xb7, 0x17, 0x56, 0x5e, 0xc1, 0xab, - 0xed, 0x85, 0x95, 0x0a, 0x54, 0x76, 0x1f, 0x11, 0xda, 0x3a, 0x1c, 0x1c, 0xc7, 0xbd, 0xc1, 0xe0, - 0xf0, 0x4d, 0x4f, 0x7f, 0x38, 0x1a, 0xba, 0x77, 0xde, 0x2a, 0x59, 0x6c, 0xa4, 0xa8, 0xdc, 0x4b, - 0x6f, 0x8d, 0x2c, 0x63, 0x1b, 0x83, 0xd4, 0x20, 0xcc, 0x96, 0x0f, 0xfe, 0xfb, 0xb9, 0x34, 0xfb, - 0xf1, 0x73, 0x69, 0xf6, 0xd3, 0xe7, 0xd2, 0xec, 0x7f, 0xbe, 0x94, 0x66, 0x3e, 0x7e, 0x29, 0xcd, - 0xfc, 0xef, 0x4b, 0x69, 0xe6, 0xf5, 0x93, 0x37, 0x6f, 0x87, 0x7f, 0xfb, 0x70, 0xb4, 0xd7, 0xed, - 0x1f, 0xef, 0xfb, 0x37, 0x7c, 0xfe, 0xe7, 0xf1, 0xe0, 0xaf, 0x7f, 0xdf, 0x77, 0x4e, 0xa7, 0x1e, - 0xf5, 0x47, 0x4b, 0xd9, 0x5b, 0xfe, 0xf9, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x19, 0x02, 0xe2, - 0x5e, 0xf3, 0x0b, 0x00, 0x00, + // 1554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x57, 0x59, 0x77, 0x14, 0xb9, + 0x15, 0xb6, 0xc1, 0x78, 0x11, 0xdb, 0x45, 0xec, 0x5b, 0xc3, 0x18, 0x32, 0x10, 0x0f, 0x63, 0x0f, + 0x90, 0x75, 0x26, 0xc9, 0x44, 0x5d, 0x75, 0xdd, 0x2d, 0x77, 0x95, 0x54, 0x96, 0x54, 0xbd, 0x90, + 0xe4, 0x28, 0x76, 0x4f, 0x87, 0x21, 0x03, 0x34, 0xc7, 0xdd, 0xe4, 0x24, 0xbf, 0x21, 0x2f, 0xf9, + 0x59, 0x79, 0x9c, 0xc7, 0x3c, 0xe6, 0xc0, 0x73, 0xfe, 0x43, 0x8e, 0xaa, 0x6e, 0x37, 0xd5, 0x35, + 0x30, 0x3c, 0xd9, 0x7d, 0xbf, 0x4f, 0x57, 0xba, 0xdf, 0x5d, 0xa4, 0x62, 0x77, 0x87, 0xe3, 0xc9, + 0x8b, 0xf1, 0x64, 0xe7, 0x60, 0x38, 0x1c, 0x4d, 0x26, 0xc3, 0xf1, 0xcb, 0xe9, 0xd1, 0xf8, 0xf9, + 0xce, 0x70, 0xfc, 0x72, 0x32, 0x3d, 0x78, 0x39, 0x9d, 0x6c, 0xbf, 0x3a, 0x1a, 0x4f, 0xc7, 0xfc, + 0x46, 0xc9, 0xda, 0x5e, 0x60, 0x6d, 0xff, 0xed, 0xe1, 0xe1, 0x68, 0x7a, 0xf0, 0x70, 0xeb, 0x4b, + 0xc6, 0x44, 0x01, 0xb8, 0x7f, 0xbc, 0x1a, 0xf1, 0x93, 0x6c, 0x2d, 0x57, 0x1d, 0xa5, 0x7b, 0x0a, + 0x96, 0xf8, 0x3a, 0x5b, 0x31, 0x28, 0x62, 0x58, 0xe6, 0x1b, 0xec, 0x44, 0xcf, 0x48, 0x87, 0x70, + 0x8c, 0x33, 0xb6, 0x1a, 0xe9, 0x34, 0x95, 0x0e, 0x8e, 0x6f, 0xfd, 0xf3, 0x18, 0xbb, 0x5e, 0x2e, + 0xd6, 0xaf, 0x46, 0x47, 0x07, 0xd3, 0x67, 0xe3, 0x97, 0x76, 0xf4, 0x7c, 0x34, 0x9c, 0x8e, 0x8f, + 0x0a, 0x6f, 0xeb, 0x6c, 0x45, 0x69, 0x85, 0xb0, 0xc4, 0x57, 0xd9, 0xb1, 0xbd, 0x7d, 0x58, 0xe6, + 0x17, 0xd9, 0xb9, 0xbd, 0x7d, 0xdf, 0xc4, 0xa8, 0xfd, 0xf8, 0x91, 0x17, 0x71, 0x6c, 0xd0, 0x5a, + 0x38, 0xc6, 0x1b, 0xec, 0xda, 0xde, 0xbe, 0x4f, 0x50, 0xb5, 0x5c, 0xdb, 0x67, 0x06, 0x77, 0x65, + 0x1f, 0xe3, 0x39, 0x7e, 0x9c, 0x5f, 0x65, 0x17, 0x2d, 0xaa, 0x18, 0x4d, 0x7d, 0xe9, 0x0a, 0xdf, + 0x64, 0x0d, 0x82, 0x3e, 0xb4, 0xfc, 0x04, 0xbf, 0xc0, 0x20, 0xd2, 0xca, 0x19, 0x11, 0xb9, 0xb9, + 0x75, 0x95, 0x5f, 0x63, 0x97, 0xf6, 0xf6, 0x7d, 0x8a, 0xd6, 0x8a, 0x16, 0xfa, 0x48, 0xab, 0x58, + 0x3a, 0xa9, 0x95, 0x48, 0x60, 0x2d, 0x60, 0x91, 0x56, 0xd6, 0x09, 0xe5, 0xbc, 0x75, 0x46, 0xaa, + 0x96, 0x77, 0xda, 0xb7, 0xb1, 0x0f, 0xeb, 0xfc, 0x12, 0xe3, 0x73, 0x6f, 0x06, 0x77, 0xd1, 0xa0, + 0x8a, 0x10, 0x36, 0xb6, 0xfe, 0x77, 0x91, 0x9d, 0x32, 0xa3, 0xc9, 0xf8, 0xf5, 0xd1, 0x70, 0x54, + 0x84, 0xbf, 0xc6, 0x8e, 0x0b, 0x35, 0x28, 0xa3, 0xef, 0x74, 0x61, 0x39, 0x18, 0xd2, 0xd1, 0x8b, + 0x52, 0xc4, 0x78, 0xf4, 0xf7, 0xf0, 0xff, 0xf1, 0x20, 0x79, 0xa7, 0xeb, 0x9b, 0x42, 0x75, 0x60, + 0x85, 0x9f, 0x61, 0xac, 0xd3, 0xf5, 0xd6, 0x89, 0x8e, 0x54, 0x2d, 0x38, 0x41, 0x60, 0x4f, 0xd8, + 0x14, 0x56, 0xf9, 0x69, 0xb6, 0xd1, 0xe9, 0x7a, 0x6d, 0x44, 0x94, 0x20, 0xac, 0x05, 0x27, 0x9d, + 0xae, 0x8f, 0x8b, 0x33, 0x9d, 0x62, 0xeb, 0x9d, 0xae, 0xc7, 0x4c, 0x47, 0x6d, 0xd8, 0xe0, 0xe7, + 0xd9, 0xd9, 0x4e, 0xd7, 0x3b, 0xdd, 0x41, 0xb5, 0x2b, 0x22, 0xa7, 0xcd, 0x00, 0x58, 0x08, 0x69, + 0xbe, 0xda, 0x77, 0xb5, 0x43, 0xef, 0x84, 0x69, 0xa1, 0xb3, 0x70, 0x92, 0xdf, 0x64, 0x57, 0xdf, + 0x61, 0xa2, 0xd5, 0x32, 0xd8, 0x12, 0xae, 0x64, 0x59, 0x38, 0x15, 0xb2, 0xf6, 0x0e, 0xde, 0x45, + 0x8c, 0xd1, 0x58, 0x38, 0x1d, 0xb2, 0xf2, 0xee, 0xb0, 0x3e, 0xc6, 0x24, 0xac, 0x92, 0x5a, 0xc1, + 0x19, 0x7e, 0x85, 0x5d, 0xa8, 0x40, 0x5d, 0x91, 0xc8, 0x58, 0x38, 0x6d, 0xe0, 0x2c, 0x45, 0x24, + 0x72, 0xd7, 0x06, 0x20, 0x0f, 0xe1, 0xc7, 0x2c, 0x2f, 0xde, 0x3a, 0x6d, 0x10, 0xce, 0x71, 0xce, + 0xce, 0x90, 0x2c, 0xde, 0xe6, 0x59, 0x96, 0x0c, 0x80, 0xf3, 0x73, 0xec, 0xf4, 0xcc, 0x16, 0xa3, + 0xd2, 0x29, 0x9c, 0x0f, 0xa9, 0x9d, 0x99, 0x9a, 0x22, 0x11, 0x2a, 0x42, 0x0b, 0x17, 0xc8, 0x6f, + 0x55, 0x00, 0x5a, 0x70, 0x91, 0xdf, 0x60, 0x57, 0xea, 0x50, 0x8a, 0x4e, 0xc4, 0xc2, 0x09, 0xb8, + 0xf4, 0xbe, 0x85, 0x22, 0x4e, 0xa5, 0x82, 0xcb, 0xfc, 0x3a, 0xbb, 0x5c, 0x87, 0x22, 0x83, 0x45, + 0x54, 0x57, 0x08, 0x24, 0x85, 0xb0, 0x1f, 0xb5, 0x85, 0x6a, 0xa1, 0x37, 0xc2, 0x21, 0x5c, 0x0d, + 0x25, 0x5a, 0x53, 0x3e, 0x43, 0x25, 0x12, 0x37, 0xf0, 0x91, 0xce, 0x95, 0x43, 0x03, 0xd7, 0xe8, + 0x58, 0xc4, 0xc9, 0x8c, 0x8c, 0xd0, 0x5b, 0x25, 0x32, 0xdb, 0xd6, 0x0e, 0xae, 0xf3, 0x5b, 0xec, + 0xfa, 0x0f, 0xe5, 0x94, 0x5a, 0xf9, 0x4c, 0xf7, 0xd0, 0xc0, 0x0d, 0x4a, 0xee, 0x8c, 0xe0, 0xb4, + 0x13, 0x09, 0x61, 0x37, 0x69, 0xfb, 0x1f, 0xe4, 0xc2, 0x86, 0x92, 0x2f, 0x64, 0x87, 0x06, 0xbf, + 0xc3, 0x6e, 0x55, 0x38, 0xb9, 0x6a, 0x86, 0x6e, 0x58, 0x4c, 0xea, 0x2d, 0x7e, 0x8f, 0xdd, 0xf9, + 0x08, 0x29, 0x78, 0x87, 0xdb, 0xa4, 0xc6, 0x8c, 0x68, 0xb0, 0xe2, 0xe5, 0x93, 0xda, 0x56, 0x55, + 0x30, 0xac, 0xf6, 0xd6, 0x44, 0xb0, 0xf9, 0x31, 0x52, 0x6c, 0x1d, 0xdc, 0xe1, 0x9f, 0xb0, 0x9b, + 0x1f, 0x22, 0xed, 0xe7, 0x98, 0x23, 0xdc, 0x0d, 0x83, 0xe5, 0x7d, 0xb1, 0x13, 0xfe, 0x93, 0x1a, + 0xde, 0x96, 0xa1, 0xfa, 0x64, 0x24, 0x12, 0x2f, 0xd5, 0xae, 0x86, 0x4f, 0x6b, 0x75, 0x3c, 0x0f, + 0x19, 0xee, 0x7d, 0x58, 0xd5, 0xe6, 0x80, 0x94, 0xff, 0x29, 0xf5, 0x61, 0x2c, 0xc3, 0x04, 0x69, + 0xe6, 0x45, 0xfc, 0xf7, 0x29, 0xd3, 0x55, 0x63, 0x68, 0x29, 0x9f, 0x69, 0x9d, 0xc0, 0x16, 0xbf, + 0xcd, 0x6e, 0xd4, 0xd1, 0xcc, 0xe8, 0x4c, 0x5b, 0x34, 0xbe, 0x83, 0x03, 0xf8, 0x8c, 0xb2, 0xb0, + 0xc0, 0xd0, 0xb9, 0x0b, 0xa3, 0x2a, 0x2e, 0x65, 0xe8, 0x09, 0x13, 0x5b, 0x78, 0xc0, 0x3f, 0x63, + 0xf7, 0xea, 0x44, 0x52, 0x48, 0x1b, 0xdf, 0x93, 0xae, 0x1d, 0x1b, 0xd1, 0x2b, 0x0b, 0xe0, 0xf3, + 0x1f, 0x27, 0x5b, 0x27, 0x8c, 0x0b, 0xce, 0x0b, 0x55, 0xb6, 0xf9, 0x16, 0xfb, 0xb4, 0x4e, 0x0e, + 0x59, 0xa9, 0xc8, 0x37, 0x3b, 0xc5, 0xce, 0xfb, 0x8e, 0x1b, 0xb8, 0x51, 0x6e, 0x0c, 0x2a, 0x37, + 0x27, 0x7e, 0xc1, 0xef, 0xb3, 0xbb, 0xef, 0x23, 0x8a, 0x28, 0xca, 0x53, 0x5f, 0x5c, 0x39, 0xd6, + 0x06, 0x05, 0x1f, 0x52, 0x37, 0x2c, 0x30, 0x6d, 0x22, 0x6c, 0xdb, 0x63, 0x17, 0x95, 0x83, 0x47, + 0x33, 0x89, 0xb1, 0xef, 0xe7, 0x83, 0x3a, 0xd1, 0xaa, 0xd5, 0xd4, 0xba, 0x03, 0x8f, 0x69, 0xd8, + 0x2d, 0xa0, 0xb6, 0xad, 0x8d, 0x2b, 0xe0, 0x9f, 0xd1, 0xb0, 0x0b, 0xb0, 0x45, 0xe7, 0x12, 0x4c, + 0x83, 0xcf, 0x9f, 0x87, 0xa9, 0x4f, 0xe6, 0x4c, 0x48, 0x43, 0xb7, 0x0c, 0xfc, 0x82, 0x9f, 0x65, + 0x27, 0xc9, 0xee, 0x7a, 0x22, 0x83, 0x5f, 0x72, 0x60, 0xa7, 0x66, 0xc4, 0xd0, 0xc6, 0xf0, 0x2b, + 0x6a, 0x87, 0x45, 0x8f, 0x1e, 0x95, 0x33, 0x03, 0xf8, 0x35, 0x75, 0x6e, 0x00, 0x0d, 0xb6, 0xa4, + 0x75, 0x68, 0x30, 0x2e, 0xb6, 0x80, 0x2f, 0x2b, 0xae, 0xb4, 0x89, 0xd1, 0xc0, 0x6f, 0x68, 0x02, + 0x16, 0x67, 0x0f, 0xb3, 0x2e, 0x81, 0xdf, 0xce, 0x2a, 0x06, 0xfb, 0x41, 0xaa, 0x30, 0x4f, 0xbc, + 0x88, 0x9c, 0xec, 0x62, 0xb9, 0xc6, 0xc2, 0xef, 0x2a, 0x11, 0x09, 0x6b, 0xd1, 0xf9, 0x44, 0x5a, + 0x07, 0xbf, 0xa7, 0xda, 0x0e, 0x66, 0x85, 0x7d, 0x57, 0xd2, 0xbd, 0x8c, 0x41, 0x54, 0x14, 0x2a, + 0x90, 0xca, 0xa9, 0x65, 0x0c, 0x4d, 0x7e, 0x99, 0x9d, 0x27, 0x38, 0x15, 0x2e, 0x6a, 0x7b, 0x83, + 0x36, 0x4f, 0x1c, 0x44, 0xd4, 0x4d, 0xb5, 0x40, 0xe7, 0x7e, 0xe3, 0xca, 0x41, 0x4a, 0x63, 0xa1, + 0x38, 0xd2, 0x0c, 0x17, 0x51, 0x84, 0xd6, 0x16, 0x29, 0xd1, 0x09, 0xb4, 0xf8, 0x03, 0x76, 0xbf, + 0x6e, 0x2d, 0x2e, 0x42, 0x1f, 0x63, 0x16, 0x2e, 0x7c, 0x15, 0x0d, 0x7c, 0x2a, 0xb2, 0x2c, 0xb4, + 0x63, 0x9b, 0xa4, 0x2a, 0xf0, 0x48, 0xc7, 0x08, 0x92, 0x8a, 0x80, 0x2c, 0xb5, 0xcb, 0x7f, 0x8f, + 0x64, 0x5f, 0x44, 0xcb, 0xab, 0xa7, 0x43, 0xc2, 0x14, 0x98, 0xc5, 0xfd, 0x3c, 0x5c, 0xef, 0x45, + 0xef, 0x25, 0x34, 0x71, 0x16, 0x57, 0x85, 0xed, 0xa8, 0xf4, 0x07, 0x90, 0x52, 0x71, 0x2e, 0x52, + 0x9a, 0x83, 0x92, 0x25, 0x63, 0x50, 0x24, 0x6e, 0x41, 0xc8, 0xa4, 0x52, 0x18, 0x13, 0xa6, 0xc2, + 0x4d, 0xae, 0x69, 0x8b, 0xe2, 0x4a, 0x6c, 0x25, 0xba, 0x59, 0x76, 0x40, 0x91, 0x56, 0x95, 0xa7, + 0x4d, 0x34, 0x90, 0xd1, 0x65, 0x1f, 0x28, 0x4f, 0x60, 0x9f, 0x0a, 0x70, 0x17, 0xb1, 0x65, 0x84, + 0x72, 0x60, 0xe8, 0x0e, 0x9b, 0x19, 0xbc, 0x48, 0x12, 0xdd, 0x0b, 0xc5, 0x02, 0x96, 0xb8, 0x45, + 0xb3, 0x04, 0xd9, 0x1c, 0x15, 0xcf, 0xcc, 0x50, 0x0e, 0x60, 0xd9, 0x52, 0xf3, 0x5e, 0xcf, 0xa9, + 0x2d, 0xe7, 0x8c, 0xa0, 0xa0, 0xcf, 0xf2, 0x66, 0x07, 0x07, 0xde, 0x60, 0x52, 0x4e, 0xdb, 0x20, + 0x4e, 0x97, 0xd2, 0x58, 0x94, 0x05, 0xa6, 0x54, 0xb1, 0xbd, 0x4a, 0xce, 0x83, 0x95, 0xaa, 0xb6, + 0x5f, 0x69, 0xa7, 0x60, 0x8e, 0x31, 0xd3, 0x56, 0x3a, 0x18, 0xcc, 0x46, 0x66, 0xa5, 0x39, 0xe1, + 0x49, 0xa5, 0x81, 0x42, 0x1b, 0x53, 0xf1, 0x14, 0xa2, 0xc0, 0x1f, 0x2a, 0xcd, 0x5e, 0x74, 0xf1, + 0x02, 0xfa, 0xc7, 0xea, 0xfb, 0x20, 0x0e, 0x6f, 0x35, 0x83, 0x31, 0xfc, 0x89, 0xdf, 0x65, 0xb7, + 0xeb, 0x56, 0x9f, 0xea, 0x38, 0x4f, 0xd0, 0xbb, 0x3e, 0xa5, 0xc2, 0xd3, 0x03, 0x0b, 0xbb, 0x29, + 0xfc, 0x99, 0x9e, 0x23, 0xd8, 0x4d, 0x67, 0xcf, 0x0c, 0x38, 0x20, 0xdf, 0xc1, 0xe6, 0x8c, 0x50, + 0x56, 0x86, 0x41, 0x71, 0x48, 0xe7, 0x09, 0xd6, 0x59, 0xe2, 0xde, 0xa1, 0x43, 0x0a, 0x25, 0xa0, + 0xb3, 0xfd, 0xe6, 0xe0, 0x37, 0x54, 0xc4, 0x01, 0x54, 0x3a, 0x6c, 0x31, 0xaa, 0x6c, 0x6b, 0x30, + 0x42, 0x99, 0x39, 0xf8, 0x0b, 0xbd, 0x11, 0x83, 0xcd, 0x3e, 0x42, 0x78, 0x5a, 0xf9, 0x8d, 0x8f, + 0x2c, 0x7c, 0x5b, 0x39, 0x56, 0x59, 0x9a, 0xc2, 0xb6, 0xe1, 0x19, 0xa5, 0x7e, 0x66, 0x85, 0xbf, + 0xd6, 0x69, 0x56, 0x3e, 0x41, 0xf8, 0x8e, 0x7a, 0xbb, 0x50, 0xa6, 0x87, 0x72, 0x1e, 0xec, 0xf3, + 0xcd, 0x95, 0xf5, 0xaf, 0xe0, 0xab, 0xcd, 0x95, 0xf5, 0xaf, 0xe1, 0xeb, 0xcd, 0x95, 0xf5, 0x5d, + 0xd8, 0xdd, 0x7a, 0xc0, 0x78, 0xef, 0x60, 0xf2, 0x22, 0x1d, 0x4d, 0x26, 0x07, 0x4f, 0x47, 0xf6, + 0xf5, 0xe1, 0x34, 0x3c, 0x7a, 0x37, 0xd8, 0x89, 0xfd, 0x1c, 0x4d, 0x78, 0xf6, 0x9e, 0x64, 0x6b, + 0xd8, 0xc7, 0x28, 0x77, 0x08, 0xcb, 0xcd, 0xbd, 0x7f, 0xbf, 0x69, 0x2c, 0x7f, 0xff, 0xa6, 0xb1, + 0xfc, 0xdf, 0x37, 0x8d, 0xe5, 0x7f, 0xbd, 0x6d, 0x2c, 0x7d, 0xff, 0xb6, 0xb1, 0xf4, 0x9f, 0xb7, + 0x8d, 0xa5, 0x27, 0x5f, 0x3c, 0x7d, 0x36, 0xfd, 0xf6, 0xf5, 0xe1, 0xf6, 0x70, 0xfc, 0x62, 0x87, + 0x3e, 0x68, 0xca, 0x3f, 0x9f, 0x4f, 0xbe, 0xf9, 0x6e, 0x27, 0x38, 0xad, 0x7d, 0xe1, 0x1c, 0xae, + 0x16, 0x1f, 0x36, 0x8f, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xbf, 0x0c, 0x7e, 0xf1, 0x00, 0x0d, + 0x00, 0x00, } diff --git a/types/accesscontrol/resource.go b/types/accesscontrol/resource.go index a1c4c7190..72a1afa65 100644 --- a/types/accesscontrol/resource.go +++ b/types/accesscontrol/resource.go @@ -22,6 +22,7 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_FEEGRANT, ResourceType_KV_SLASHING, ResourceType_KV_BANK_DEFERRED, + ResourceType_KV_EVM, }}, ResourceType_Mem: {ResourceType_ANY, []ResourceType{ ResourceType_DexMem, @@ -31,12 +32,14 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_BANK_SUPPLY, ResourceType_KV_BANK_DENOM, ResourceType_KV_BANK_BALANCES, + ResourceType_KV_BANK_WEI_BALANCE, }}, ResourceType_KV_BANK_SUPPLY: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_DENOM: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_BALANCES: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_BANK_DEFERRED: {ResourceType_KV, []ResourceType{ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX}}, ResourceType_KV_BANK_DEFERRED_MODULE_TX_INDEX: {ResourceType_KV_BANK_DEFERRED, []ResourceType{}}, + ResourceType_KV_BANK_WEI_BALANCE: {ResourceType_KV_BANK, []ResourceType{}}, ResourceType_KV_STAKING: {ResourceType_KV, []ResourceType{ ResourceType_KV_STAKING_DELEGATION, ResourceType_KV_STAKING_VALIDATOR, @@ -194,6 +197,30 @@ var ResourceTree = map[ResourceType]TreeNode{ ResourceType_KV_DEX_MEM_ORDER: {ResourceType_KV_DEX, []ResourceType{}}, ResourceType_KV_DEX_MEM_CANCEL: {ResourceType_KV_DEX, []ResourceType{}}, ResourceType_KV_DEX_MEM_DEPOSIT: {ResourceType_KV_DEX, []ResourceType{}}, + ResourceType_KV_EVM: {ResourceType_KV, []ResourceType{ + ResourceType_KV_EVM_BALANCE, + ResourceType_KV_EVM_TRANSIENT, + ResourceType_KV_EVM_ACCOUNT_TRANSIENT, + ResourceType_KV_EVM_MODULE_TRANSIENT, + ResourceType_KV_EVM_NONCE, + ResourceType_KV_EVM_RECEIPT, + ResourceType_KV_EVM_S2E, + ResourceType_KV_EVM_E2S, + ResourceType_KV_EVM_CODE_HASH, + ResourceType_KV_EVM_CODE, + ResourceType_KV_EVM_CODE_SIZE, + }}, + ResourceType_KV_EVM_BALANCE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_ACCOUNT_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_MODULE_TRANSIENT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_NONCE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_RECEIPT: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_S2E: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_E2S: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE_HASH: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE: {ResourceType_KV_EVM, []ResourceType{}}, + ResourceType_KV_EVM_CODE_SIZE: {ResourceType_KV_EVM, []ResourceType{}}, } // This returns a slice of all resource types that are dependent to a specific resource type diff --git a/types/context.go b/types/context.go index ef847d3a3..1cf3ac063 100644 --- a/types/context.go +++ b/types/context.go @@ -39,12 +39,21 @@ type Context struct { minGasPrice DecCoins consParams *tmproto.ConsensusParams eventManager *EventManager - priority int64 // The tx priority, only relevant in CheckTx + + priority int64 // The tx priority, only relevant in CheckTx + pendingTxChecker abci.PendingTxChecker // Checker for pending transaction, only relevant in CheckTx + checkTxCallback func(error) // callback to make at the end of CheckTx. Input param is the error (nil-able) of `runMsgs` + expireTxHandler func() // callback that the mempool invokes when a tx is expired txBlockingChannels acltypes.MessageAccessOpsChannelMapping txCompletionChannels acltypes.MessageAccessOpsChannelMapping txMsgAccessOps map[int][]acltypes.AccessOperation + // EVM properties + evm bool // EVM transaction flag + evmNonce uint64 // EVM Transaction nonce + evmSenderAddress string // EVM Sender address + msgValidator *acltypes.MsgValidator messageIndex int // Used to track current message being processed txIndex int @@ -116,6 +125,30 @@ func (c Context) Priority() int64 { return c.priority } +func (c Context) ExpireTxHandler() abci.ExpireTxHandler { + return c.expireTxHandler +} + +func (c Context) EVMSenderAddress() string { + return c.evmSenderAddress +} + +func (c Context) EVMNonce() uint64 { + return c.evmNonce +} + +func (c Context) IsEVM() bool { + return c.evm +} + +func (c Context) PendingTxChecker() abci.PendingTxChecker { + return c.pendingTxChecker +} + +func (c Context) CheckTxCallback() func(error) { + return c.checkTxCallback +} + func (c Context) TxCompletionChannels() acltypes.MessageAccessOpsChannelMapping { return c.txCompletionChannels } @@ -349,6 +382,36 @@ func (c Context) WithTraceSpanContext(ctx context.Context) Context { return c } +func (c Context) WithEVMSenderAddress(address string) Context { + c.evmSenderAddress = address + return c +} + +func (c Context) WithEVMNonce(nonce uint64) Context { + c.evmNonce = nonce + return c +} + +func (c Context) WithIsEVM(isEVM bool) Context { + c.evm = isEVM + return c +} + +func (c Context) WithPendingTxChecker(checker abci.PendingTxChecker) Context { + c.pendingTxChecker = checker + return c +} + +func (c Context) WithCheckTxCallback(checkTxCallback func(error)) Context { + c.checkTxCallback = checkTxCallback + return c +} + +func (c Context) WithExpireTxHandler(expireTxHandler func()) Context { + c.expireTxHandler = expireTxHandler + return c +} + // TODO: remove??? func (c Context) IsZero() bool { return c.ms == nil diff --git a/x/accesscontrol/keeper/keeper.go b/x/accesscontrol/keeper/keeper.go index 1ca93f602..8bab2b9d3 100644 --- a/x/accesscontrol/keeper/keeper.go +++ b/x/accesscontrol/keeper/keeper.go @@ -493,14 +493,14 @@ func (k Keeper) IterateWasmDependencies(ctx sdk.Context, handler func(wasmDepend } } -func (k Keeper) BuildDependencyDag(ctx sdk.Context, txDecoder sdk.TxDecoder, anteDepGen sdk.AnteDepGenerator, txs [][]byte) (*types.Dag, error) { +func (k Keeper) BuildDependencyDag(ctx sdk.Context, anteDepGen sdk.AnteDepGenerator, txs []sdk.Tx) (*types.Dag, error) { defer MeasureBuildDagDuration(time.Now(), "BuildDependencyDag") // contains the latest msg index for a specific Access Operation dependencyDag := types.NewDag() - for txIndex, txBytes := range txs { - tx, err := txDecoder(txBytes) // TODO: results in repetitive decoding for txs with runtx decode (potential optimization) - if err != nil { - return nil, err + for txIndex, tx := range txs { + if tx == nil { + // this implies decoding error + return nil, sdkerrors.ErrTxDecode } // get the ante dependencies and add them to the dag anteDeps, err := anteDepGen([]acltypes.AccessOperation{}, tx, txIndex) @@ -525,6 +525,7 @@ func (k Keeper) BuildDependencyDag(ctx sdk.Context, txDecoder sdk.TxDecoder, ant // add Access ops for msg for anteMsg dependencyDag.AddAccessOpsForMsg(acltypes.ANTE_MSG_INDEX, txIndex, anteAccessOpsList) + ctx = ctx.WithTxIndex(txIndex) msgs := tx.GetMsgs() for messageIndex, msg := range msgs { if types.IsGovMessage(msg) { @@ -578,11 +579,6 @@ func (k Keeper) GetMessageDependencies(ctx sdk.Context, msg sdk.Msg) []acltypes. ctx.Logger().Error(errorMessage) } } - if dependencyMapping.DynamicEnabled { - // there was an issue with dynamic generation, so lets disable it - // this will not error, the validation check was done in previous calls already - _ = k.SetDependencyMappingDynamicFlag(ctx, messageKey, false) - } return dependencyMapping.AccessOps } diff --git a/x/accesscontrol/keeper/keeper_test.go b/x/accesscontrol/keeper/keeper_test.go index f08cd1ade..d0a4695fe 100644 --- a/x/accesscontrol/keeper/keeper_test.go +++ b/x/accesscontrol/keeper/keeper_test.go @@ -112,7 +112,8 @@ func TestInvalidGetMessageDependencies(t *testing.T) { delete(app.AccessControlKeeper.MessageDependencyGeneratorMapper, undelegateKey) accessOps := app.AccessControlKeeper.GetMessageDependencies(ctx, &stakingUndelegate) require.Equal(t, types.SynchronousMessageDependencyMapping("").AccessOps, accessOps) - require.False(t, app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey).DynamicEnabled) + // no longer gets disabled such that there arent writes in the dependency generation path + require.True(t, app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey).DynamicEnabled) } func TestWasmDependencyMapping(t *testing.T) { @@ -1998,13 +1999,11 @@ func TestBuildDependencyDag(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // ensure no errors creating dag - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.NoError(t, err) } @@ -2021,13 +2020,11 @@ func TestBuildDependencyDagWithGovMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // ensure no errors creating dag - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.ErrorIs(t, err, types.ErrGovMsgInBlock) } @@ -2047,13 +2044,11 @@ func TestBuildDependencyDag_GovPropMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // expect ErrGovMsgInBlock - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.EqualError(t, err, types.ErrGovMsgInBlock.Error()) } @@ -2071,13 +2066,11 @@ func TestBuildDependencyDag_GovDepositMessage(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs...) require.NoError(t, err) - bz, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) - txs := [][]byte{ - bz, + txs := []sdk.Tx{ + txBuilder.GetTx(), } // expect ErrGovMsgInBlock - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.EqualError(t, err, types.ErrGovMsgInBlock.Error()) } @@ -2098,49 +2091,28 @@ func TestBuildDependencyDag_MultipleTransactions(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs1...) require.NoError(t, err) - bz1, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx1 := txBuilder.GetTx() err = txBuilder.SetMsgs(msgs2...) require.NoError(t, err) - bz2, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx2 := txBuilder.GetTx() - txs := [][]byte{ - bz1, - bz2, + txs := []sdk.Tx{ + tx1, + tx2, } - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), app.GetAnteDepGenerator(), txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, app.GetAnteDepGenerator(), txs) require.NoError(t, err) mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { return nil, errors.New("Mocked error") } - _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + _, err = app.AccessControlKeeper.BuildDependencyDag(ctx, mockAnteDepGenerator, txs) require.ErrorContains(t, err, "Mocked error") } -func TestBuildDependencyDag_DecoderError(t *testing.T) { - // Set up a mocked app with a failing decoder - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - - // Encode an invalid transaction - txs := [][]byte{ - []byte("invalid tx"), - } - - _, err := app.AccessControlKeeper.BuildDependencyDag( - ctx, - simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), - app.GetAnteDepGenerator(), - txs, - ) - require.Error(t, err) -} - -func BencharkAccessOpsBuildDependencyDag(b *testing.B) { +func BenchmarkAccessOpsBuildDependencyDag(b *testing.B) { app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, tmproto.Header{}) @@ -2156,30 +2128,30 @@ func BencharkAccessOpsBuildDependencyDag(b *testing.B) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() _ = txBuilder.SetMsgs(msgs1...) - bz1, _ := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) + tx1 := txBuilder.GetTx() _ = txBuilder.SetMsgs(msgs2...) - bz2, _ := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - - txs := [][]byte{ - bz1, - bz1, - bz1, - bz1, - bz1, - bz1, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, - bz2, + tx2 := txBuilder.GetTx() + + txs := []sdk.Tx{ + tx1, + tx1, + tx1, + tx1, + tx1, + tx1, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, + tx2, } mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2235,7 +2207,7 @@ func BencharkAccessOpsBuildDependencyDag(b *testing.B) { for i := 0; i < b.N; i++ { _, _ = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) } } @@ -2256,21 +2228,19 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { txBuilder := simapp.MakeTestEncodingConfig().TxConfig.NewTxBuilder() err := txBuilder.SetMsgs(msgs1...) require.NoError(t, err) - bz1, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx1 := txBuilder.GetTx() err = txBuilder.SetMsgs(msgs2...) require.NoError(t, err) - bz2, err := simapp.MakeTestEncodingConfig().TxConfig.TxEncoder()(txBuilder.GetTx()) - require.NoError(t, err) + tx2 := txBuilder.GetTx() - txs := [][]byte{ - bz1, - bz2, - bz2, - bz2, - bz2, - bz2, + txs := []sdk.Tx{ + tx1, + tx2, + tx2, + tx2, + tx2, + tx2, } mockAnteDepGenerator := func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2285,7 +2255,7 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { // ensure no errors creating dag _, err = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) require.Error(t, err) mockAnteDepGenerator = func(_ []acltypes.AccessOperation, _ sdk.Tx, _ int) ([]acltypes.AccessOperation, error) { @@ -2301,7 +2271,7 @@ func TestInvalidAccessOpsBuildDependencyDag(t *testing.T) { // ensure no errors creating dag _, err = app.AccessControlKeeper.BuildDependencyDag( - ctx, simapp.MakeTestEncodingConfig().TxConfig.TxDecoder(), mockAnteDepGenerator, txs) + ctx, mockAnteDepGenerator, txs) require.NoError(t, err) } @@ -2464,14 +2434,14 @@ func (suite *KeeperTestSuite) TestMessageDependencies() { req.Equal(delegateStaticMapping.AccessOps, accessOps) // verify dynamic got disabled dependencyMapping = app.AccessControlKeeper.GetResourceDependencyMapping(ctx, delegateKey) - req.Equal(false, dependencyMapping.DynamicEnabled) + req.Equal(true, dependencyMapping.DynamicEnabled) // lets also try with undelegate, but this time there is no dynamic generator, so we disable it as well accessOps = app.AccessControlKeeper.GetMessageDependencies(ctx, &stakingUndelegate) req.Equal(undelegateStaticMapping.AccessOps, accessOps) // verify dynamic got disabled dependencyMapping = app.AccessControlKeeper.GetResourceDependencyMapping(ctx, undelegateKey) - req.Equal(false, dependencyMapping.DynamicEnabled) + req.Equal(true, dependencyMapping.DynamicEnabled) } func (suite *KeeperTestSuite) TestImportContractReferences() { diff --git a/x/accesscontrol/testutil/accesscontrol.go b/x/accesscontrol/testutil/accesscontrol.go index 29e25e867..2be4ecc95 100644 --- a/x/accesscontrol/testutil/accesscontrol.go +++ b/x/accesscontrol/testutil/accesscontrol.go @@ -23,10 +23,11 @@ var TestingStoreKeyToResourceTypePrefixMap = acltypes.StoreKeyToResourceTypePref acltypes.ResourceType_Mem: acltypes.EmptyPrefix, }, banktypes.StoreKey: { - acltypes.ResourceType_KV_BANK: acltypes.EmptyPrefix, - acltypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, - acltypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, - acltypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + acltypes.ResourceType_KV_BANK: acltypes.EmptyPrefix, + acltypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, + acltypes.ResourceType_KV_BANK_SUPPLY: banktypes.SupplyKey, + acltypes.ResourceType_KV_BANK_DENOM: banktypes.DenomMetadataPrefix, + acltypes.ResourceType_KV_BANK_WEI_BALANCE: banktypes.WeiBalancesPrefix, }, banktypes.DeferredCacheStoreKey: { acltypes.ResourceType_KV_BANK_DEFERRED: acltypes.EmptyPrefix, diff --git a/x/auth/keeper/migrations.go b/x/auth/keeper/migrations.go index d3ad7a2f8..4e16d9288 100644 --- a/x/auth/keeper/migrations.go +++ b/x/auth/keeper/migrations.go @@ -41,3 +41,9 @@ func (m Migrator) Migrate1to2(ctx sdk.Context) error { return iterErr } + +func (m Migrator) Migrate2to3(ctx sdk.Context) error { + defaultParams := types.DefaultParams() + m.keeper.SetParams(ctx, defaultParams) + return nil +} diff --git a/x/auth/keeper/v2_to_v3_test.go b/x/auth/keeper/v2_to_v3_test.go new file mode 100644 index 000000000..92b3e631b --- /dev/null +++ b/x/auth/keeper/v2_to_v3_test.go @@ -0,0 +1,28 @@ +package keeper_test + +import ( + "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/require" + "testing" +) + +func TestMigrate2to3(t *testing.T) { + app, ctx := createTestApp(true) + + prevParams := types.Params{ + MaxMemoCharacters: types.DefaultMaxMemoCharacters, + TxSigLimit: types.DefaultTxSigLimit, + TxSizeCostPerByte: types.DefaultTxSizeCostPerByte, + SigVerifyCostED25519: types.DefaultSigVerifyCostED25519, + SigVerifyCostSecp256k1: types.DefaultSigVerifyCostSecp256k1, + } + + app.AccountKeeper.SetParams(ctx, prevParams) + // migrate to default params + m := keeper.NewMigrator(app.AccountKeeper, app.GRPCQueryRouter()) + err := m.Migrate2to3(ctx) + require.NoError(t, err) + params := app.AccountKeeper.GetParams(ctx) + require.Equal(t, params.DisableSeqnoCheck, false) +} diff --git a/x/auth/module.go b/x/auth/module.go index ef13f74a5..ef2d1f2e2 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -134,6 +134,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err != nil { panic(err) } + err = cfg.RegisterMigration(types.ModuleName, 2, m.Migrate2to3) + if err != nil { + panic(err) + } } // InitGenesis performs genesis initialization for the auth module. It returns @@ -153,7 +157,7 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw } // ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 2 } +func (AppModule) ConsensusVersion() uint64 { return 3 } // AppModuleSimulation functions diff --git a/x/bank/keeper/keeper.go b/x/bank/keeper/keeper.go index cdcf20d6c..8b0bd2f03 100644 --- a/x/bank/keeper/keeper.go +++ b/x/bank/keeper/keeper.go @@ -51,6 +51,8 @@ type Keeper interface { DelegateCoins(ctx sdk.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error UndelegateCoins(ctx sdk.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error + GetStoreKey() sdk.StoreKey + types.QueryServer } @@ -677,6 +679,10 @@ func (k BaseKeeper) trackUndelegation(ctx sdk.Context, addr sdk.AccAddress, amt return nil } +func (k BaseKeeper) GetStoreKey() sdk.StoreKey { + return k.storeKey +} + // IterateTotalSupply iterates over the total supply calling the given cb (callback) function // with the balance of each coin. // The iteration stops if the callback returns true. diff --git a/x/bank/keeper/keeper_test.go b/x/bank/keeper/keeper_test.go index e2eec160a..25600f3f7 100644 --- a/x/bank/keeper/keeper_test.go +++ b/x/bank/keeper/keeper_test.go @@ -76,6 +76,7 @@ func (suite *IntegrationTestSuite) initKeepersWithmAccPerms(blockedAddrs map[str appCodec := simapp.MakeTestEncodingConfig().Marshaler maccPerms[holder] = nil + maccPerms[types.WeiEscrowName] = nil maccPerms[authtypes.Burner] = []string{authtypes.Burner} maccPerms[authtypes.Minter] = []string{authtypes.Minter} maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking} @@ -108,6 +109,55 @@ func (suite *IntegrationTestSuite) SetupTest() { suite.queryClient = queryClient } +func (suite *IntegrationTestSuite) TestSendCoinsAndWei() { + ctx := suite.ctx + require := suite.Require() + authKeeper, keeper := suite.initKeepersWithmAccPerms(make(map[string]bool)) + amt := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))) + require.NoError(keeper.MintCoins(ctx, authtypes.Minter, amt)) + addr1 := sdk.AccAddress([]byte("addr1_______________")) + addr2 := sdk.AccAddress([]byte("addr2_______________")) + addr3 := sdk.AccAddress([]byte("addr3_______________")) + require.NoError(keeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, addr1, amt)) + // should no-op if sending zero + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.ZeroInt())) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr2)) + require.Equal(sdk.NewInt(100), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // should just do usei send if wei is zero + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(50), sdk.ZeroInt())) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(50), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.ZeroInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // should return error if wei amount overflows + require.Error(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.ZeroInt(), sdk.NewInt(1_000_000_000_000))) + // sender gets escrowed one usei, recipient does not get redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr2, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(1))) + require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.OneInt(), keeper.GetWeiBalance(ctx, addr2)) + require.Equal(sdk.NewInt(48), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, addr2, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // sender does not get escrowed due to sufficient wei balance, recipient does not get redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(999_999_999_999))) + require.Equal(sdk.ZeroInt(), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.NewInt(999_999_999_999), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(47), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(51), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) + // sender gets escrowed and recipient gets redeemed + require.NoError(keeper.SendCoinsAndWei(ctx, addr1, addr3, nil, sdk.DefaultBondDenom, sdk.NewInt(1), sdk.NewInt(2))) + require.Equal(sdk.NewInt(999_999_999_998), keeper.GetWeiBalance(ctx, addr1)) + require.Equal(sdk.NewInt(1), keeper.GetWeiBalance(ctx, addr3)) + require.Equal(sdk.NewInt(45), keeper.GetBalance(ctx, addr1, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.NewInt(53), keeper.GetBalance(ctx, addr3, sdk.DefaultBondDenom).Amount) + require.Equal(sdk.OneInt(), keeper.GetBalance(ctx, authKeeper.GetModuleAddress(types.WeiEscrowName), sdk.DefaultBondDenom).Amount) +} + func (suite *IntegrationTestSuite) TestSupply() { ctx := suite.ctx diff --git a/x/bank/keeper/send.go b/x/bank/keeper/send.go index 80fdb555b..93ac398dd 100644 --- a/x/bank/keeper/send.go +++ b/x/bank/keeper/send.go @@ -1,7 +1,10 @@ package keeper import ( + "errors" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -16,6 +19,8 @@ type SendKeeper interface { InputOutputCoins(ctx sdk.Context, inputs []types.Input, outputs []types.Output) error SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error GetParams(ctx sdk.Context) types.Params SetParams(ctx sdk.Context, params types.Params) @@ -27,6 +32,7 @@ type SendKeeper interface { } var _ SendKeeper = (*BaseSendKeeper)(nil) +var MaxWeiBalance sdk.Int = sdk.NewInt(1_000_000_000_000) // BaseSendKeeper only allows transfers between accounts without the possibility of // creating coins. It implements the SendKeeper interface. @@ -131,13 +137,7 @@ func (k BaseSendKeeper) InputOutputCoins(ctx sdk.Context, inputs []types.Input, // SendCoins transfers amt coins from a sending account to a receiving account. // An error is returned upon failure. func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { - err := k.subUnlockedCoins(ctx, fromAddr, amt) - if err != nil { - return err - } - - err = k.addCoins(ctx, toAddr, amt) - if err != nil { + if err := k.SendCoinsWithoutAccCreation(ctx, fromAddr, toAddr, amt); err != nil { return err } @@ -151,6 +151,20 @@ func (k BaseSendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAd k.ak.SetAccount(ctx, k.ak.NewAccountWithAddress(ctx, toAddr)) } + return nil +} + +func (k BaseSendKeeper) SendCoinsWithoutAccCreation(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error { + err := k.subUnlockedCoins(ctx, fromAddr, amt) + if err != nil { + return err + } + + err = k.addCoins(ctx, toAddr, amt) + if err != nil { + return err + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeTransfer, @@ -266,6 +280,20 @@ func (k BaseSendKeeper) setBalance(ctx sdk.Context, addr sdk.AccAddress, balance return nil } +func (k BaseSendKeeper) setWeiBalance(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Int) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.WeiBalancesPrefix) + if amt.IsZero() { + store.Delete(addr) + return nil + } + val, err := amt.Marshal() + if err != nil { + return err + } + store.Set(addr, val) + return nil +} + // IsSendEnabledCoins checks the coins provide and returns an ErrSendDisabled if // any of the coins are not configured for sending. Returns nil if sending is enabled // for all provided coin @@ -288,3 +316,61 @@ func (k BaseSendKeeper) IsSendEnabledCoin(ctx sdk.Context, coin sdk.Coin) bool { func (k BaseSendKeeper) BlockedAddr(addr sdk.AccAddress) bool { return k.blockedAddrs[addr.String()] } + +func (k BaseSendKeeper) SendCoinsAndWei(ctx sdk.Context, from sdk.AccAddress, to sdk.AccAddress, customEscrow sdk.AccAddress, denom string, amt sdk.Int, wei sdk.Int) error { + if wei.Equal(sdk.ZeroInt()) { + if amt.Equal(sdk.ZeroInt()) { + return nil + } + return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) + } + if wei.GTE(MaxWeiBalance) { + return errors.New("cannot send more than 10^12 wei") + } + escrow := customEscrow + if escrow == nil { + escrow = k.ak.GetModuleAddress(types.WeiEscrowName) + } + currentWeiBalanceFrom := k.GetWeiBalance(ctx, from) + postWeiBalanceFrom := currentWeiBalanceFrom.Sub(wei) + if postWeiBalanceFrom.GTE(sdk.ZeroInt()) { + if err := k.setWeiBalance(ctx, from, postWeiBalanceFrom); err != nil { + return err + } + } else { + if err := k.setWeiBalance(ctx, from, MaxWeiBalance.Add(postWeiBalanceFrom)); err != nil { + // postWeiBalanceFrom is negative + return err + } + // need to send one sei to escrow because wei balance is insufficient + if err := k.SendCoinsWithoutAccCreation(ctx, from, escrow, sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt()))); err != nil { + return err + } + } + currentWeiBalanceTo := k.GetWeiBalance(ctx, to) + postWeiBalanceTo := currentWeiBalanceTo.Add(wei) + if postWeiBalanceTo.LT(MaxWeiBalance) { + if err := k.setWeiBalance(ctx, to, postWeiBalanceTo); err != nil { + return err + } + } else { + if err := k.setWeiBalance(ctx, to, postWeiBalanceTo.Sub(MaxWeiBalance)); err != nil { + return err + } + // need to redeem one sei from escrow because wei balance overflowed + one := sdk.NewCoins(sdk.NewCoin(denom, sdk.OneInt())) + if err := k.SendCoinsWithoutAccCreation(ctx, escrow, to, one); err != nil { + if sdkerrors.ErrInsufficientFunds.Is(err) && customEscrow != nil { + // custom escrow does not have enough balance to redeem. Try the global escrow instead + if err := k.SendCoinsWithoutAccCreation(ctx, k.ak.GetModuleAddress(types.WeiEscrowName), to, one); err != nil { + return err + } + } + return err + } + } + if amt.GT(sdk.ZeroInt()) { + return k.SendCoinsWithoutAccCreation(ctx, from, to, sdk.NewCoins(sdk.NewCoin(denom, amt))) + } + return nil +} diff --git a/x/bank/keeper/view.go b/x/bank/keeper/view.go index d126ddd75..7f835ab2b 100644 --- a/x/bank/keeper/view.go +++ b/x/bank/keeper/view.go @@ -26,6 +26,7 @@ type ViewKeeper interface { GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int IterateAccountBalances(ctx sdk.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool)) IterateAllBalances(ctx sdk.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool)) @@ -232,3 +233,17 @@ func (k BaseViewKeeper) getAccountStore(ctx sdk.Context, addr sdk.AccAddress) pr return prefix.NewStore(store, types.CreateAccountBalancesPrefix(addr)) } + +func (k BaseViewKeeper) GetWeiBalance(ctx sdk.Context, addr sdk.AccAddress) sdk.Int { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.WeiBalancesPrefix) + val := store.Get(addr) + if val == nil { + return sdk.ZeroInt() + } + res := new(sdk.Int) + if err := res.Unmarshal(val); err != nil { + // should never happen + panic(err) + } + return *res +} diff --git a/x/bank/types/key.go b/x/bank/types/key.go index 8b8c25a2d..146b30de1 100644 --- a/x/bank/types/key.go +++ b/x/bank/types/key.go @@ -21,10 +21,13 @@ const ( // QuerierRoute defines the module's query routing key QuerierRoute = ModuleName + + WeiEscrowName = "weiescrow" ) // KVStore keys var ( + WeiBalancesPrefix = []byte{0x04} // BalancesPrefix is the prefix for the account balances store. We use a byte // (instead of `[]byte("balances")` to save some disk space). DeferredCachePrefix = []byte{0x03} diff --git a/x/genutil/gentx.go b/x/genutil/gentx.go index 766b16cbf..9ef946f90 100644 --- a/x/genutil/gentx.go +++ b/x/genutil/gentx.go @@ -1,6 +1,7 @@ package genutil import ( + "crypto/sha256" "encoding/json" "fmt" @@ -87,7 +88,7 @@ func ValidateAccountInGenesis( return nil } -type deliverTxfn func(sdk.Context, abci.RequestDeliverTx) abci.ResponseDeliverTx +type deliverTxfn func(sdk.Context, abci.RequestDeliverTx, sdk.Tx, [32]byte) abci.ResponseDeliverTx // DeliverGenTxs iterates over all genesis txs, decodes each into a Tx and // invokes the provided deliverTxfn with the decoded Tx. It returns the result @@ -109,7 +110,7 @@ func DeliverGenTxs( panic(err) } - res := deliverTx(ctx, abci.RequestDeliverTx{Tx: bz}) + res := deliverTx(ctx, abci.RequestDeliverTx{Tx: bz}, tx, sha256.Sum256(bz)) if !res.IsOK() { panic(res.Log) }