Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat!: max-event-size config to limit size of events stored #614

Closed
wants to merge 8 commits into from

Conversation

czarcas7ic
Copy link
Member

@czarcas7ic czarcas7ic commented Jun 17, 2024

Description

Closes: #XXXX

We have recently had issues with massive IBC events being persisted in block results, resulting in slowed down block syncing / consensus. Even after we upgrade to IBC v8, it's likely a matter of time before some other massive events exploit occurs that will bog down nodes once again. We should allow nodes to specify how large events they want to store, and if an event is greater than this size, a placeholder is set.

This PR introduces a max-event-size config to the app.toml. If an event attribute's size is greater than this value, it gets replaced by a placeholder. I think this implies a client breaking change since the expectation of events is now changed, but if it's not considered breaking than I will remove the "!" from the title.

@czarcas7ic czarcas7ic changed the title feat: max event size config feat!: max-event-size config to limit size of events stored Jun 18, 2024
@czarcas7ic czarcas7ic marked this pull request as ready for review June 18, 2024 00:19
Copy link

coderabbitai bot commented Jun 18, 2024

Walkthrough

The recent update introduces a new configuration parameter max-event-size to manage the maximum size of events stored in the server. This feature involves updates to configuration files, functions, and logic in various parts of the application, ensuring oversized event attributes are appropriately handled and restricted by the defined limit.

Changes

File Change Summary
CHANGELOG.md, .../config/toml.go Added max-event-size to configuration files for controlling event size.
baseapp/abci.go Enhanced DeliverTx to check and replace event attributes exceeding sdk.MaxEventSize.
server/config/config.go Updated BaseConfig struct and related functions to incorporate MaxEventSize field.
types/events.go Introduced a new global variable MaxEventSize with an initial value of 0.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AppConfig as App Config
    participant BaseApp as BaseApp
    participant SDK

    User->>AppConfig: Set max-event-size in app.toml
    AppConfig->>SDK: Initialize MaxEventSize
    BaseApp->>SDK: DeliverTx request
    SDK->>SDK: Check event attribute size
    alt Event size exceeds MaxEventSize
        SDK->>SDK: Replace with default behavior
    else Event size is within limit
        SDK->>SDK: Process normally
    end
    SDK->>BaseApp: Return response
    BaseApp->>User: DeliverTx response
Loading

Poem

Out in the fields, the code does change,
With limits set, events arrange,
Size constraints to keep things neat,
A milestone in tasks complete.

🐇✨

Configured bytes, the rabbit's feat,
In toml files, success we greet!


Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between df7a478 and 9d78cb4.

Files selected for processing (5)
  • CHANGELOG.md (1 hunks)
  • baseapp/abci.go (1 hunks)
  • server/config/config.go (3 hunks)
  • server/config/toml.go (2 hunks)
  • types/events.go (1 hunks)
Files skipped from review due to trivial changes (1)
  • types/events.go
Additional context used
LanguageTool
CHANGELOG.md

[uncategorized] ~148-~148: Possible missing comma found. (AI_HYDRA_LEO_MISSING_COMMA)
Context: ...itive to the genesis migrate command. However in v0.50+, adding custom migrations to ...


[grammar] ~153-~153: Did you mean “combining”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ...s/cosmos-sdk/pull/17284) Properly allow to combine depinject-enabled modules and non-depin...


[grammar] ~156-~156: Probably a preposition is missing after ‘try’. (ATD_VERBS_TO_COLLOCATION)
Context: ...om/cosmos/pull/17220) Do not try validate msgURL as web URL in draft-proposal...


[misspelling] ~201-~201: Did you mean the phrasal verb “clean up” instead of the noun ‘cleanup’? (CLEAN_UP)
Context: ...method toBaseApp` for custom app to cleanup resource in graceful shutdown. ### Bug...


[uncategorized] ~213-~213: Possible missing comma found. (AI_HYDRA_LEO_MISSING_COMMA)
Context: .... Chains will not notice this breaking change as this package contains testing utilit...


[style] ~220-~220: Consider a shorter alternative to avoid wordiness. (IN_ORDER_TO_PREMIUM)
Context: ...' pubkey check in the signature handler in order to work with ICS. * (deps) [cosmos#15957](https:...


[uncategorized] ~223-~223: Possible missing comma found. (AI_HYDRA_LEO_MISSING_COMMA)
Context: ...w be set. Note, when querying against a node it must be re-synced in order to be abl...


[style] ~223-~223: Consider a shorter alternative to avoid wordiness. (IN_ORDER_TO_PREMIUM)
Context: ...ing against a node it must be re-synced in order to be able to automatically populate the b...


[grammar] ~272-~272: The verb ‘helps’ is used with an infinitive. (ADVISE_VBG)
Context: ...elper func in x/auth module which helps adding accounts to genesis state. * (x/authz) ...


[style] ~281-~281: Consider a shorter alternative to avoid wordiness. (IN_ORDER_TO_PREMIUM)
Context: ...stead of x/param. Legacy types remain in order to facilitate parameter migration from the...


[style] ~292-~292: Although a hyphen is possible, it is not necessary in a compound modifier in which the first word is an adverb that ends in ‘ly’. (HYPHENATED_LY_ADVERB_ADJECTIVE)
Context: ...t path (i.e. the OS path) matches their fully-qualified package name. For example, proto files ...


[style] ~293-~293: Consider a shorter alternative to avoid wordiness. (IN_ORDER_TO_PREMIUM)
Context: ...ow use deliverState for the first block in order to access changes made in InitChain. * (x/...


[uncategorized] ~304-~304: Possible missing comma found. (AI_HYDRA_LEO_MISSING_COMMA)
Context: ...ims`. These takes an extra genesisState argument which is the default state of the app. ...


[misspelling] ~315-~315: This word is normally spelled as one. (EN_COMPOUNDS_SUB_MODULE)
Context: ...le` API to support module addresses and sub-module addresses in a backward compatible way....


[uncategorized] ~315-~315: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL)
Context: ...addresses and sub-module addresses in a backward compatible way. * (snapshots) [cosmos#14608](https://git...


[duplication] ~324-~324: Possible typo: you repeated a word (ENGLISH_WORD_REPEAT_RULE)
Context: .../cosmos/pull/14163) Refactor (coins Coins) Validate() to avoid unnecessary map. ...


[uncategorized] ~340-~340: Possible missing comma found. (AI_HYDRA_LEO_MISSING_COMMA)
Context: ...dParamsfrom theAppModuleSimulation` interface which is no longer needed. * (ci) [#128...


[misspelling] ~359-~359: This word is normally spelled as one. (EN_COMPOUNDS_BOILER_PLATE)
Context: ...appOptions(appopts)` function to reduce boiler plate in root.go. ### State Machine Breakin...


[uncategorized] ~379-~379: “It’s” is the contracted form of “it is”. Did you mean to use the possessive determiner “its”? (AI_HYDRA_LEO_SCY_IT_S)
Context: ...o self-managed parameters and deprecate it's usage of x/params. * (x/distribution)...


[uncategorized] ~382-~382: “It’s” is the contracted form of “it is”. Did you mean to use the possessive determiner “its”? (AI_HYDRA_LEO_SCY_IT_S)
Context: ...o self-managed parameters and deprecate it's usage of x/params. * (x/staking) [#12...


[uncategorized] ~383-~383: “It’s” is the contracted form of “it is”. Did you mean to use the possessive determiner “its”? (AI_HYDRA_LEO_SCY_IT_S)
Context: ...o self-managed parameters and deprecate it's usage of x/params. * (x/bank) [cosmos#11859...


[uncategorized] ~392-~392: A comma may be missing after the conjunctive/linking adverb ‘Additionally’. (SENT_START_CONJUNCTIVE_LINKING_ADVERB_COMMA)
Context: ...tentsinsimulation.SimulationState. Additionally it adds a ProposalMsgsfield tosimu...


[uncategorized] ~431-~431: “It’s” is the contracted form of “it is”. Did you mean to use the possessive determiner “its”? (AI_HYDRA_LEO_SCY_IT_S)
Context: ...o self-managed parameters and deprecate it's usage of x/params. * (x/bank) [cosmos#12630...


[typographical] ~461-~461: Usually, there’s no comma before “when”. (IF_NO_COMMA)
Context: ...dled error for vesting account transfers, when total vesting amount exceeds total bala...


[misspelling] ~464-~464: This word is normally spelled as one. (EN_COMPOUNDS_DEAD_LOCK)
Context: ...com/cosmos/pull/13116) Fix a dead-lock in the Group-TotalWeight x/group in...

Markdownlint
CHANGELOG.md

148-148: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


291-291: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


312-312: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


315-315: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


397-397: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


398-398: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


399-399: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


400-400: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


401-401: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


402-402: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


251-251: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


359-359: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


371-371: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


447-447: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


448-448: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


459-459: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


471-471: Expected: 0 or 2; Actual: 1 (MD009, no-trailing-spaces)
Trailing spaces


420-420: null (MD038, no-space-in-code)
Spaces inside code span elements

Additional comments not posted (5)
server/config/toml.go (1)

99-101: The addition of the max-event-size configuration parameter is well-documented and correctly implemented in the TOML configuration template.

server/config/config.go (3)

111-114: The MaxEventSize field has been correctly added to the BaseConfig struct with appropriate struct tags and documentation.


323-323: Setting the default value for MaxEventSize to 1MB in the DefaultConfig function is appropriate and aligns with the intended functionality of limiting event sizes.


389-389: Correctly assigning the MaxEventSize from the BaseConfig to sdk.MaxEventSize in the GetConfig function ensures that the configuration is effectively utilized throughout the SDK.

CHANGELOG.md (1)

48-48: The changelog entry for the new max-event-size configuration is clear and concise.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Comment on lines +415 to +426
// If the application has set a maximum event size, check the size of each event attribute.
// If the size of any attribute exceeds the maximum, set the attribute value to a placeholder.
if sdk.MaxEventSize > 0 {
for i, event := range result.Events {
for j, attr := range event.Attributes {
if len([]byte(attr.Key))+len([]byte(attr.Value)) > sdk.MaxEventSize {
result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
}
}
}
}

Copy link

@coderabbitai coderabbitai bot Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider optimizing the event size checking logic for efficiency.

The current implementation checks each attribute's size individually against sdk.MaxEventSize. This could be optimized by calculating the total size of all attributes in an event first, and then checking if the total exceeds sdk.MaxEventSize. This would reduce the number of comparisons and potentially improve performance, especially for events with many attributes.

-	if sdk.MaxEventSize > 0 {
-		for i, event := range result.Events {
-			for j, attr := range event.Attributes {
-				if len([]byte(attr.Key))+len([]byte(attr.Value)) > sdk.MaxEventSize {
-					result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
-				}
-			}
-		}
-	}
+	if sdk.MaxEventSize > 0 {
+		for i, event := range result.Events {
+			totalSize := 0
+			for _, attr := range event.Attributes {
+				totalSize += len([]byte(attr.Key)) + len([]byte(attr.Value))
+			}
+			if totalSize > sdk.MaxEventSize {
+				for j := range event.Attributes {
+					result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
+				}
+			}
+		}
+	}
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// If the application has set a maximum event size, check the size of each event attribute.
// If the size of any attribute exceeds the maximum, set the attribute value to a placeholder.
if sdk.MaxEventSize > 0 {
for i, event := range result.Events {
for j, attr := range event.Attributes {
if len([]byte(attr.Key))+len([]byte(attr.Value)) > sdk.MaxEventSize {
result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
}
}
}
}
// If the application has set a maximum event size, check the size of each event attribute.
// If the size of any attribute exceeds the maximum, set the attribute value to a placeholder.
if sdk.MaxEventSize > 0 {
for i, event := range result.Events {
totalSize := 0
for _, attr := range event.Attributes {
totalSize += len([]byte(attr.Key)) + len([]byte(attr.Value))
}
if totalSize > sdk.MaxEventSize {
for j := range event.Attributes {
result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
}
}
}
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are instances where we want the smaller attributes of an event but remove the larger instances, and this would not work in that way

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@czarcas7ic, thank you for your feedback. I understand your requirement for a more nuanced approach where only the attributes that exceed the sdk.MaxEventSize limit are replaced, while smaller ones are preserved.

Here's a revised approach that checks each attribute individually and replaces only those that exceed the maximum allowed size:

// If the application has set a maximum event size, check the size of each attribute individually.
// If the size of an attribute exceeds the maximum, set the attribute value to a placeholder.
if sdk.MaxEventSize > 0 {
    for i, event := range result.Events {
        for j, attr := range event.Attributes {
            if len([]byte(attr.Key))+len([]byte(attr.Value)) > sdk.MaxEventSize {
                result.Events[i].Attributes[j].Value = "evt val too large, inc max-event-size in config.toml"
            }
        }
    }
}

This implementation ensures that only the attributes which are too large are affected, and it aligns with your need to selectively manage event attributes based on their size. Please let me know if this adjustment suits your scenario, or if further modifications are required!

@czarcas7ic czarcas7ic closed this Jun 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants