Skip to content

fix(consensus): use Locale.ROOT for case-insensitive operations#128

Closed
halibobo1205 wants to merge 1 commit intodevelopfrom
fix/locale-sensitive-case
Closed

fix(consensus): use Locale.ROOT for case-insensitive operations#128
halibobo1205 wants to merge 1 commit intodevelopfrom
fix/locale-sensitive-case

Conversation

@halibobo1205
Copy link
Copy Markdown
Owner

@halibobo1205 halibobo1205 commented Apr 18, 2026

User description

String.toLowerCase()/toUpperCase() without an explicit Locale uses Locale.getDefault(), which on Turkish (tr) or Azerbaijani (az) systems folds 'I' to dotless-ı (U+0131) instead of 'i' (U+0069). Changes:

  • Fix all toLowerCase()/toUpperCase() calls to use Locale.ROOT
  • Enable the ErrorProne StringCaseLocaleUsage checker at ERROR level to prevent future regressions at compile time
  • Add one-time data migration (MigrateTurkishKeyHelper) to normalize all Turkish legacy keys (ı → i) at startup.

CodeAnt-AI Description

Make case handling consistent across locales and migrate old Turkish keys

What Changed

  • Case-insensitive checks now use the same rules on every system, so database engine selection, account type matching, disabled API checks, command handling, and hex formatting are no longer affected by the server language.
  • Account ID lookup keys created under Turkish locale settings are migrated once at startup, so existing accounts still resolve after upgrade.
  • Added test coverage for locale-safe matching and the Turkish key migration path.

Impact

✅ Fewer lookup failures on Turkish and Azerbaijani systems
✅ Existing account IDs still resolve after upgrade
✅ More consistent command and API matching across locales

🔄 Retrigger CodeAnt AI Review

Details

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 18, 2026

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Apr 18, 2026
@halibobo1205
Copy link
Copy Markdown
Owner Author

@codex: review

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 18, 2026

CodeAnt AI finished reviewing your PR.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 813385b420

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@halibobo1205 halibobo1205 force-pushed the fix/locale-sensitive-case branch from 813385b to 8793848 Compare April 18, 2026 13:44
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 879384827e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +73 to +76
if (ArrayUtils.isEmpty(existing)) {
revokingDB.put(rootKey, entry.getValue());
}
keysToDelete.add(entry.getKey());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Handle colliding Turkish keys before deleting legacy entries

This migration still drops mappings when multiple legacy Turkish keys normalize to the same ROOT key (even if no ROOT key existed before migration). For example, two historical IDs like IIIIIIII and IIIIIIIi can produce distinct Turkish-lower keys (ı... variants) that both map to the same ROOT key; the first one wins, later ones are skipped by the existing check, and then all legacy keys are deleted, making at least one account ID permanently unresolvable after startup.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@lxcmyf lxcmyf left a comment

Choose a reason for hiding this comment

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

Leaving one inline comment for the migration conflict case.

Comment on lines +71 to +81
// Only write if ROOT key doesn't already exist
byte[] existing = revokingDB.getUnchecked(rootKey);
if (ArrayUtils.isEmpty(existing)) {
revokingDB.put(rootKey, entry.getValue());
}
keysToDelete.add(entry.getKey());
}

// Phase 3: delete old Turkish keys
for (byte[] key : keysToDelete) {
revokingDB.delete(key);
Copy link
Copy Markdown

@lxcmyf lxcmyf Apr 21, 2026

Choose a reason for hiding this comment

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

This migration still needs an explicit collision path before deleting the Turkish legacy key. A fixed-locale node should reject conflicting SetAccountId transactions, but the risky case is a DB that has already been run under different default locales over time: an old Turkish-locale index entry can remain stored under a dotless-ı key, and after the node later runs under a ROOT-style locale a new transaction can pass has(accountId) against the new canonical key and write a second mapping there. In that state getUnchecked(rootKey) is non-empty, we skip the migration write, and then delete the only legacy index entry for the first account. Please detect that mismatch explicitly and fail or reconcile it instead of deleting silently.

@halibobo1205 halibobo1205 force-pushed the fix/locale-sensitive-case branch from 8793848 to 9c9acc5 Compare April 22, 2026 08:47
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 22, 2026

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Apr 22, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 22, 2026

CodeAnt AI Incremental review completed.

String.toLowerCase()/toUpperCase() without an explicit Locale uses
Locale.getDefault(), which on Turkish (tr) or Azerbaijani (az) systems
folds 'I' to dotless-ı (U+0131) instead of 'i' (U+0069).
Changes:
- Fix all toLowerCase()/toUpperCase() calls to use Locale.ROOT
- Enable the ErrorProne StringCaseLocaleUsage checker at ERROR level
  to prevent future regressions at compile time
- Add one-time data migration (MigrateTurkishKeyHelper) to normalize
  all Turkish legacy keys (ı → i) at startup.
@halibobo1205 halibobo1205 force-pushed the fix/locale-sensitive-case branch from 9c9acc5 to 1c3e5c1 Compare April 23, 2026 03:07
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 23, 2026

CodeAnt AI is running Incremental review


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Apr 23, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 23, 2026

CodeAnt AI Incremental review completed.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1c3e5c1349

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +10 to +11
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid non-exported javac APIs in the new checker

This checker imports com.sun.tools.javac.* internals, which are encapsulated by the jdk.compiler module on Java 11+ and are not exported to unnamed modules by default. Because this commit does not add any --add-exports compiler args for :errorprone, :errorprone:compileJava will fail before the build can run the new check. Please switch to public Error Prone APIs for type inspection (or add explicit module exports in the build).

Useful? React with 👍 / 👎.

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 23, 2026

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Apr 23, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 23, 2026

Sequence Diagram

This PR adds a one-time startup migration that normalizes Turkish legacy account ID index keys to locale-independent lowercase and records completion in dynamic properties to ensure consistent lookups across all locales.

sequenceDiagram
    participant Node
    participant DynamicPropertiesStore
    participant MigrateTurkishKeyHelper
    participant AccountIdIndexStore

    Node->>DynamicPropertiesStore: Read Turkish key migration flag
    DynamicPropertiesStore-->>Node: Flag value

    alt Migration not done
        Node->>MigrateTurkishKeyHelper: Start Turkish key migration
        MigrateTurkishKeyHelper->>AccountIdIndexStore: Scan for legacy Turkish keys
        MigrateTurkishKeyHelper->>AccountIdIndexStore: Write normalized keys and delete legacy keys
        MigrateTurkishKeyHelper->>DynamicPropertiesStore: Mark Turkish key migration done
    else Migration already done
        Node->>Node: Skip Turkish key migration
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 23, 2026

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 25, 2026

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Apr 25, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 25, 2026

Sequence Diagram

This diagram shows how, during node startup, the manager checks a migration flag and, if needed, runs a one time job that normalizes legacy Turkish account id index keys and then marks the migration as completed.

sequenceDiagram
    participant Node
    participant Manager
    participant DynamicProps as DynamicPropertiesStore
    participant MigrateHelper as MigrateTurkishKeyHelper
    participant AccountIndex as AccountIdIndexStore
    participant RevokingDB

    Node->>Manager: init at startup
    Manager->>DynamicProps: getTurkishKeyMigrationDone

    alt Migration not yet done
        Manager->>MigrateHelper: create helper with ChainBaseManager
        Manager->>MigrateHelper: doWork
        MigrateHelper->>AccountIndex: getRevokingDB
        MigrateHelper->>RevokingDB: scan and migrate Turkish keys to root keys
        MigrateHelper->>DynamicProps: saveTurkishKeyMigrationDone
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 25, 2026

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 27, 2026

CodeAnt AI is running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@codeant-ai codeant-ai Bot added size:XL This PR changes 500-999 lines, ignoring generated files and removed size:XL This PR changes 500-999 lines, ignoring generated files labels Apr 27, 2026
@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 27, 2026

Sequence Diagram

This PR adds a one-time startup migration that normalizes legacy AccountIdIndexStore keys created under Turkish or Azerbaijani locales and marks completion in DynamicPropertiesStore to avoid rerunning.

sequenceDiagram
    participant Node
    participant Manager
    participant DynamicProps as DynamicPropertiesStore
    participant Migrator as MigrateTurkishKeyHelper
    participant AccountIndex as AccountIdIndexStore

    Node->>Manager: start init
    Manager->>DynamicProps: getTurkishKeyMigrationDone
    DynamicProps-->>Manager: returns 0 if not migrated

    alt migration not done
        Manager->>Migrator: doWork
        Migrator->>AccountIndex: scan keys for dotless i
        AccountIndex-->>Migrator: legacy keys with dotless i
        Migrator->>AccountIndex: write normalized keys and delete legacy keys
        Migrator->>DynamicProps: saveTurkishKeyMigrationDone 1
    end
Loading

Generated by CodeAnt AI

@codeant-ai
Copy link
Copy Markdown

codeant-ai Bot commented Apr 27, 2026

CodeAnt AI finished running the review.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants