diff --git a/baseapp/abci.go b/baseapp/abci.go index 7147d6d88593..e863f60dc3c1 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -241,21 +241,35 @@ func (app *BaseApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx { panic(fmt.Sprintf("unknown RequestCheckTx type: %s", req.Type)) } - gInfo, result, anteEvents, priority, err := app.runTx(mode, req.Tx) + gInfo, result, anteEvents, priority, tx, err := app.runTx(mode, req.Tx) if err != nil { return sdkerrors.ResponseCheckTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, anteEvents, app.trace) } return abci.ResponseCheckTx{ - GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? - GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? - Log: result.Log, - Data: result.Data, - Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents), - Priority: priority, + GasWanted: int64(gInfo.GasWanted), // TODO: Should type accept unsigned ints? + GasUsed: int64(gInfo.GasUsed), // TODO: Should type accept unsigned ints? + Log: result.Log, + Data: result.Data, + Events: sdk.MarkEventsToIndex(result.Events, app.indexEvents), + Priority: priority, + IsOracleTx: isOracleTx(tx.GetMsgs()), } } +func isOracleTx(msgs []sdk.Msg) bool { + for _, msg := range msgs { + if sdk.MsgTypeURL(msg) == "/terra.oracle.v1beta1.MsgAggregateExchangeRatePrevote" || + sdk.MsgTypeURL(msg) == "/terra.oracle.v1beta1.MsgAggregateExchangeRateVote" { + continue + } else { + return false + } + } + + return true +} + // DeliverTx implements the ABCI interface and executes a tx in DeliverTx mode. // State only gets persisted if all messages are valid and get executed successfully. // Otherwise, the ResponseDeliverTx will contain releveant error information. @@ -280,7 +294,7 @@ func (app *BaseApp) DeliverTx(req abci.RequestDeliverTx) (res abci.ResponseDeliv telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted") }() - gInfo, result, anteEvents, _, err := app.runTx(runTxModeDeliver, req.Tx) + gInfo, result, anteEvents, _, _, err := app.runTx(runTxModeDeliver, req.Tx) if err != nil { resultStr = "failed" return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(anteEvents, app.indexEvents), app.trace) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index b42a56efca68..af9a432102cb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -622,7 +622,7 @@ 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(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, err error) { +func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, result *sdk.Result, anteEvents []abci.Event, priority int64, tx sdk.Tx, err error) { // NOTE: GasWanted should be returned by the AnteHandler. GasUsed is // determined by the GasMeter. We need access to the context to get the gas // meter so we initialize upfront. @@ -633,7 +633,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re // only run the tx if there is block gas remaining if mode == runTxModeDeliver && ctx.BlockGasMeter().IsOutOfGas() { - return gInfo, nil, nil, 0, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") + return gInfo, nil, nil, 0, nil, sdkerrors.Wrap(sdkerrors.ErrOutOfGas, "no block gas left to run tx") } defer func() { @@ -666,14 +666,14 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re defer consumeBlockGas() } - tx, err := app.txDecoder(txBytes) + tx, err = app.txDecoder(txBytes) if err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + return sdk.GasInfo{}, nil, nil, 0, nil, err } msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - return sdk.GasInfo{}, nil, nil, 0, err + return sdk.GasInfo{}, nil, nil, 0, nil, err } if app.anteHandler != nil { @@ -709,7 +709,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re gasWanted = ctx.GasMeter().Limit() if err != nil { - return gInfo, nil, nil, 0, err + return gInfo, nil, nil, 0, nil, err } priority = ctx.Priority() @@ -738,7 +738,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re newCtx, err := app.postHandler(postCtx, tx, mode == runTxModeSimulate) if err != nil { - return gInfo, nil, anteEvents, priority, err + return gInfo, nil, anteEvents, priority, nil, err } result.Events = append(result.Events, newCtx.EventManager().ABCIEvents()...) @@ -757,7 +757,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re } } - return gInfo, result, anteEvents, priority, err + return gInfo, result, anteEvents, priority, tx, err } // runMsgs iterates through a list of messages and executes them with the provided diff --git a/baseapp/test_helpers.go b/baseapp/test_helpers.go index 6489595bc8c1..5c1ada34f885 100644 --- a/baseapp/test_helpers.go +++ b/baseapp/test_helpers.go @@ -16,13 +16,13 @@ func (app *BaseApp) SimCheck(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, * if err != nil { return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, _, err := app.runTx(runTxModeCheck, bz) + gasInfo, result, _, _, _, err := app.runTx(runTxModeCheck, bz) return gasInfo, result, err } // Simulate executes a tx in simulate mode to get result and gas info. func (app *BaseApp) Simulate(txBytes []byte) (sdk.GasInfo, *sdk.Result, error) { - gasInfo, result, _, _, err := app.runTx(runTxModeSimulate, txBytes) + gasInfo, result, _, _, _, err := app.runTx(runTxModeSimulate, txBytes) return gasInfo, result, err } @@ -32,7 +32,7 @@ func (app *BaseApp) SimDeliver(txEncoder sdk.TxEncoder, tx sdk.Tx) (sdk.GasInfo, if err != nil { return sdk.GasInfo{}, nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "%s", err) } - gasInfo, result, _, _, err := app.runTx(runTxModeDeliver, bz) + gasInfo, result, _, _, _, err := app.runTx(runTxModeDeliver, bz) return gasInfo, result, err } diff --git a/go.mod b/go.mod index 582d644db1d8..fee6b4cf7c28 100644 --- a/go.mod +++ b/go.mod @@ -174,7 +174,7 @@ replace ( // replace broken goleveldb. github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // use cometbft - github.com/tendermint/tendermint => github.com/cometbft/cometbft v0.34.29 + github.com/tendermint/tendermint => github.com/classic-terra/cometbft v0.34.29-terra.0 ) retract ( diff --git a/go.sum b/go.sum index cd25d3acdee9..446c8fee91f8 100644 --- a/go.sum +++ b/go.sum @@ -187,6 +187,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/classic-terra/cometbft v0.34.29-terra.0 h1:HnRGt7tijI2n5zSVrg/xh1mYYm4Gb4QFlknq+dRP8Jw= +github.com/classic-terra/cometbft v0.34.29-terra.0/go.mod h1:L9shMfbkZ8B+7JlwANEr+NZbBcn+hBpwdbeYvA5rLCw= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= @@ -200,8 +202,6 @@ github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE github.com/coinbase/kryptology v1.8.0/go.mod h1:RYXOAPdzOGUe3qlSFkMGn58i3xUA8hmxYHksuq+8ciI= github.com/coinbase/rosetta-sdk-go v0.7.9 h1:lqllBjMnazTjIqYrOGv8h8jxjg9+hJazIGZr9ZvoCcA= github.com/coinbase/rosetta-sdk-go v0.7.9/go.mod h1:0/knutI7XGVqXmmH4OQD8OckFrbQ8yMsUZTG7FXCR2M= -github.com/cometbft/cometbft v0.34.29 h1:Q4FqMevP9du2pOgryZJHpDV2eA6jg/kMYxBj9ZTY6VQ= -github.com/cometbft/cometbft v0.34.29/go.mod h1:L9shMfbkZ8B+7JlwANEr+NZbBcn+hBpwdbeYvA5rLCw= github.com/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= github.com/cometbft/cometbft-db v0.7.0/go.mod h1:yiKJIm2WKrt6x8Cyxtq9YTEcIMPcEe4XPxhgX59Fzf0= github.com/confio/ics23/go v0.9.0 h1:cWs+wdbS2KRPZezoaaj+qBleXgUk5WOQFMP3CQFGTr4= diff --git a/server/config/config.go b/server/config/config.go index 40087b149603..2cdd59ade219 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -9,6 +9,8 @@ import ( clientflags "github.com/cosmos/cosmos-sdk/client/flags" pruningtypes "github.com/cosmos/cosmos-sdk/pruning/types" + "github.com/cosmos/cosmos-sdk/store/cache" + "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -81,6 +83,9 @@ type BaseConfig struct { // InterBlockCache enables inter-block caching. InterBlockCache bool `mapstructure:"inter-block-cache"` + // InterBlockCacheSize set the size of the inter-block cache. + InterBlockCacheSize uint `mapstructure:"inter-block-cache-size"` + // IndexEvents defines the set of events in the form {eventType}.{attributeKey}, // which informs Tendermint what to index. If empty, all events will be indexed. IndexEvents []string `mapstructure:"index-events"` @@ -281,12 +286,13 @@ func DefaultConfig() *Config { BaseConfig: BaseConfig{ MinGasPrices: defaultMinGasPrices, InterBlockCache: true, + InterBlockCacheSize: cache.DefaultCommitKVStoreCacheSize, Pruning: pruningtypes.PruningOptionDefault, PruningKeepRecent: "0", PruningInterval: "0", MinRetainBlocks: 0, IndexEvents: make([]string, 0), - IAVLCacheSize: 781250, // 50 MB + IAVLCacheSize: iavl.DefaultIAVLCacheSize, IAVLDisableFastNode: false, IAVLLazyLoading: false, AppDBBackend: "", diff --git a/server/config/toml.go b/server/config/toml.go index 920201b330e4..06f1a53420dd 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -63,6 +63,12 @@ min-retain-blocks = {{ .BaseConfig.MinRetainBlocks }} # InterBlockCache enables inter-block caching. inter-block-cache = {{ .BaseConfig.InterBlockCache }} +# InterBlockCacheSize set the size (the number of cache items) of interblock cache item +# Each item consumes 128 bytes, so the value should be dividend by 128 +# Default cache size is 10mb. +# Ex) 100mb = 10,000,000 / 128 = 78,125 +inter-block-cache-size = {{ .BaseConfig.InterBlockCacheSize }} + # IndexEvents defines the set of events in the form {eventType}.{attributeKey}, # which informs Tendermint what to index. If empty, all events will be indexed. # @@ -70,8 +76,10 @@ inter-block-cache = {{ .BaseConfig.InterBlockCache }} # ["message.sender", "message.recipient"] index-events = [{{ range .BaseConfig.IndexEvents }}{{ printf "%q, " . }}{{end}}] -# IavlCacheSize set the size of the iavl tree cache. -# Default cache size is 50mb. +# IAVLCacheSize set the cache size (the number of cache items) of the iavl tree. +# Each item size consumes 128 bytes, so the value should be dividend by 128 +# Default cache size is 100mb. +# Ex) 100mb = 100,000,000 / 128 = 781,250 iavl-cache-size = {{ .BaseConfig.IAVLCacheSize }} # IavlDisableFastNode enables or disables the fast node feature of IAVL. diff --git a/server/start.go b/server/start.go index 2ea63c5fe1a9..d92ea4279e57 100644 --- a/server/start.go +++ b/server/start.go @@ -32,24 +32,27 @@ import ( "github.com/cosmos/cosmos-sdk/server/rosetta" crgserver "github.com/cosmos/cosmos-sdk/server/rosetta/lib/server" "github.com/cosmos/cosmos-sdk/server/types" + "github.com/cosmos/cosmos-sdk/store/cache" + "github.com/cosmos/cosmos-sdk/store/iavl" "github.com/cosmos/cosmos-sdk/telemetry" sdktypes "github.com/cosmos/cosmos-sdk/types" ) const ( // Tendermint full-node start flags - flagWithTendermint = "with-tendermint" - flagAddress = "address" - flagTransport = "transport" - flagTraceStore = "trace-store" - flagCPUProfile = "cpu-profile" - FlagMinGasPrices = "minimum-gas-prices" - FlagHaltHeight = "halt-height" - FlagHaltTime = "halt-time" - FlagInterBlockCache = "inter-block-cache" - FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" - FlagTrace = "trace" - FlagInvCheckPeriod = "inv-check-period" + flagWithTendermint = "with-tendermint" + flagAddress = "address" + flagTransport = "transport" + flagTraceStore = "trace-store" + flagCPUProfile = "cpu-profile" + FlagMinGasPrices = "minimum-gas-prices" + FlagHaltHeight = "halt-height" + FlagHaltTime = "halt-time" + FlagInterBlockCache = "inter-block-cache" + FlagInterBlockCacheSize = "inter-block-cache-size" + FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" + FlagTrace = "trace" + FlagInvCheckPeriod = "inv-check-period" FlagPruning = "pruning" FlagPruningKeepRecent = "pruning-keep-recent" @@ -166,6 +169,7 @@ is performed. Note, when enabled, gRPC will also be automatically enabled. cmd.Flags().Uint64(FlagHaltHeight, 0, "Block height at which to gracefully halt the chain and shutdown the node") cmd.Flags().Uint64(FlagHaltTime, 0, "Minimum block time (in Unix seconds) at which to gracefully halt the chain and shutdown the node") cmd.Flags().Bool(FlagInterBlockCache, true, "Enable inter-block caching") + cmd.Flags().Uint(FlagInterBlockCacheSize, cache.DefaultCommitKVStoreCacheSize, "The size of inter-block caching store") cmd.Flags().String(flagCPUProfile, "", "Enable CPU profiling and write to the provided file") cmd.Flags().Bool(FlagTrace, false, "Provide full stack traces for errors in ABCI Log") cmd.Flags().String(FlagPruning, pruningtypes.PruningOptionDefault, "Pruning strategy (default|nothing|everything|custom)") @@ -173,6 +177,7 @@ is performed. Note, when enabled, gRPC will also be automatically enabled. cmd.Flags().Uint64(FlagPruningInterval, 0, "Height interval at which pruned heights are removed from disk (ignored if pruning is not 'custom')") cmd.Flags().Uint(FlagInvCheckPeriod, 0, "Assert registered invariants every N blocks") cmd.Flags().Uint64(FlagMinRetainBlocks, 0, "Minimum block height offset during ABCI commit to prune Tendermint blocks") + cmd.Flags().Uint64(FlagIAVLCacheSize, iavl.DefaultIAVLCacheSize, "The size of iavl caching store") cmd.Flags().Bool(FlagAPIEnable, false, "Define if the API server should be enabled") cmd.Flags().Bool(FlagAPISwagger, false, "Define if swagger documentation should automatically be registered (Note: the API must also be enabled)") diff --git a/store/cache/cache.go b/store/cache/cache.go index 62bed91d978e..c7dbb89d3ec3 100644 --- a/store/cache/cache.go +++ b/store/cache/cache.go @@ -13,9 +13,11 @@ var ( _ types.CommitKVStore = (*CommitKVStoreCache)(nil) _ types.MultiStorePersistentCache = (*CommitKVStoreCacheManager)(nil) - // DefaultCommitKVStoreCacheSize defines the persistent ARC cache size for a - // CommitKVStoreCache. - DefaultCommitKVStoreCacheSize uint = 1000 + // DefaultCommitKVStoreCacheSize defines the number of persistent ARC cache item for a + // CommitKVStoreCache, which is supposed to be 10MB size. + // Each cache item consumes 128 bytes, 64 bytes for the left sibling, and 64 bytes for the right sibling. + // The number of cache item is calculated as 10 MB = 10,000,000 / 128 = 78_125 + DefaultCommitKVStoreCacheSize uint = 78_125 ) type ( @@ -59,6 +61,11 @@ func NewCommitKVStoreCacheManager(size uint) *CommitKVStoreCacheManager { } } +// SetCacheSize sets the cache size of the CommitKVStore. +func (cmgr *CommitKVStoreCacheManager) SetCacheSize(size uint) { + cmgr.cacheSize = size +} + // GetStoreCache returns a Cache from the CommitStoreCacheManager for a given // StoreKey. If no Cache exists for the StoreKey, then one is created and set. // The returned Cache is meant to be used in a persistent manner. diff --git a/store/iavl/store.go b/store/iavl/store.go index 7517f934f4de..7ccea9007767 100644 --- a/store/iavl/store.go +++ b/store/iavl/store.go @@ -23,7 +23,10 @@ import ( ) const ( - DefaultIAVLCacheSize = 500000 + // DefaultIAVLCacheSize defines the number of iavl cache item, which is supposed to be 100MB size. + // Each cache item consumes 128 bytes, 64 bytes for the left sibling, and 64 bytes for the right sibling. + // The number of cache item is calculated as 100 MB = 10,000,000 / 128 = 781_250 + DefaultIAVLCacheSize = 781_250 ) var ( diff --git a/store/types/store.go b/store/types/store.go index 7ad4da2cc0a3..399695923564 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -458,6 +458,9 @@ type MultiStorePersistentCache interface { // cache. GetStoreCache(key StoreKey, store CommitKVStore) CommitKVStore + // Sets the cache size of the provided CommitKVStore + SetCacheSize(size uint) + // Return the underlying CommitKVStore for a StoreKey. Unwrap(key StoreKey) CommitKVStore diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 2c6de7a59d66..9256907f60d7 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -641,6 +641,29 @@ func (k Keeper) Delegate( delegatorAddress := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress) + // If Delegations are allowed again, limit validator power to 20% + if ctx.ChainID() == ColumbusChainID { + // Get the last Total Power of the validator set + lastPower := k.GetLastTotalPower(ctx) + + // Get the power of the current validator power + validatorLastPower := sdk.TokensToConsensusPower(validator.Tokens, k.PowerReduction(ctx)) + + // Get the new power of the validator if delegated the bond amount + validatorNewPower := validatorLastPower + sdk.TokensToConsensusPower(bondAmt, k.PowerReduction(ctx)) + + // Compute what the Total Consensus Power would be if this Delegation goes through + newTotalPower := lastPower.Int64() + sdk.TokensToConsensusPower(bondAmt, k.PowerReduction(ctx)) + + // Compute what the new Validator voting power would be in relation to the new total power + // validatorIncreasedDelegationPercent := float32(validatorNewPower) / float32(newTotalPower) + validatorIncreasedDelegationPercent := sdk.NewDec(validatorNewPower).QuoInt64(newTotalPower) + + // If Delegations are allowed, and the Delegation would have increased the Validator to over 20% of the staking power, do not allow the Delegation to proceed + if validatorIncreasedDelegationPercent.GT(sdk.NewDecWithPrec(20, 2)) { + panic("validator power is over the allowed limit") + } + } // if subtractAccount is true then we are // performing a delegation and not a redelegation, thus the source tokens are // all non bonded diff --git a/x/staking/keeper/msg_server.go b/x/staking/keeper/msg_server.go index cf74b61ea02f..020f6bdcc41b 100644 --- a/x/staking/keeper/msg_server.go +++ b/x/staking/keeper/msg_server.go @@ -17,6 +17,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) +const ColumbusChainID = "columbus-5" + type msgServer struct { Keeper }