Skip to content

fix(config): refactor the config - #40

Merged
Federico2014 merged 10 commits into
Federico2014:feature/pqc-signature-v4.8.2from
317787106:fix/optimize_RelayService
Jun 16, 2026
Merged

fix(config): refactor the config #40
Federico2014 merged 10 commits into
Federico2014:feature/pqc-signature-v4.8.2from
317787106:fix/optimize_RelayService

Conversation

@317787106

@317787106 317787106 commented Jun 16, 2026

Copy link
Copy Markdown

What does this PR do?

Four related cleanups on the PQC-signature feature line, all in the witness/PQ area:

1. Restructure PQ witness config into a localwitness_pq section

  • The PQ section is now auto-bound through ConfigBeanFactory into a new LocalWitnessPqConfig bean (with a nested PqEntryConfig), replacing the field-by-field reads in LocalWitnessConfig.fromConfig. The standalone common/.../PqEntryConfig.java is removed.
  • The top-level localPqWitnessAccountAddress key is replaced by localwitness_pq.accountAddress. Setting both localWitnessAccountAddress and localwitness_pq.accountAddress is now rejected at startup (PARAMETER_INIT).
  • Structural validation moves up front into LocalWitnessPqConfig.postProcess(): every entry must name a scheme and define exactly one of key/seed. Crypto-level validation (scheme support, hex length, public-key recovery) stays in WitnessInitializer.
  • buildPqWitnesses and the keypair-building logic move from Args into WitnessInitializer, decomposed into focused helpers (resolveScheme, keypairFromKey, keypairFromSeed, decodeHex). Args sheds its crypto-module imports.
  • reference.conf / config.conf updated to document the new section.

2. Tighten PQ signature error handling

  • TransactionCapsule.validatePQSignatureGetWeight now throws SignatureFormatException (length mismatch) and SignatureException (invalid sig) instead of a generic PermissionException, for more precise diagnostics. approveList is now treated as required (null-guard dropped).
  • TransactionUtil.getTransactionSignWeight rejects pq_auth_sig immediately when no PQ scheme is activated.

3. Simplify PQSchemeRegistry

  • SchemeInfo uses @AllArgsConstructor; the unused resolve() pass-through and a redundant UNKNOWN_PQ_SCHEME check in require() are removed (the existing SCHEMES.get(...) == null path already covers it). Doc reflow only otherwise.

4. Optimize RelayService

  • scheduledHere() -> isAnyLocalWitnessActive(), verifyLegacySignature -> verifyEcdsaSignature (clearer intent).
  • Extract resolveExpectedSignerAddress() to unify the multi-sign expected-address resolution shared by the ECDSA and PQ verification paths (single source of truth, returns null + logs when the witness account is missing under multi-sign).
  • isFastForwardPeer rewritten as a stream and no longer short-circuits on an empty fastForwardNodes; clearer "exactly one of signature/pq_auth_sig" diagnostic that includes the observed flags.

Why are these changes required?

  • The flat localPqWitnessAccountAddress + manually-parsed localwitness_pq.keys shape didn't match the *Config bean pattern used elsewhere and scattered validation across Args. Binding the section to a bean centralizes structural validation and removes crypto coupling from Args.
  • Generic PermissionException for malformed/invalid PQ signatures masked the real failure cause; precise exception types improve diagnostics and match the ECDSA path.
  • The duplicated expected-signer resolution in the ECDSA and PQ relay paths was easy to let drift; extracting it removes that risk.

Behavior changes worth flagging for reviewers

  • Config migration (breaking): localPqWitnessAccountAddress is gone — move it to localwitness_pq.accountAddress. Do not set both ECDSA and PQ account-address overrides.
  • FN_DSA_512 seeds are now accepted with a warning rather than rejected (the fnDsa512SeedRejected test was removed). Falcon keygen is not bit-stable, so key is still recommended for production.

This PR has been tested by:

  • Unit Tests: LocalWitnessConfigTest (both-address rejection, missing-scheme, missing/both key-seed), ConfigParityGateTest (allowlist for localwitness_pq), ArgsPqConfigTest, PQSchemeRegistryTest.
  • Manual Testing

Follow up

Extra details

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2a95fe7b-26a3-42d4-8cb3-1cf227249977

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 issues found across 16 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="common/src/main/resources/reference.conf">

<violation number="1" location="common/src/main/resources/reference.conf:789">
P2: Commented PQ key examples contradict the "exactly one of `key`/`seed`" rule by showing both fields with one empty string. If a user uncomments these examples, startup will fail because validation treats any non-null value as present.</violation>
</file>

<file name="framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java">

<violation number="1" location="framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java:291">
P2: Hex prefix validation for PQ witness config fields should reject uppercase `0X` and enforce the strict lowercase `0x` prefix policy per project validation rules. The `stripHexPrefix` helper silently normalizes `0X`, allowing inconsistent config formats to pass validation.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

@@ -764,36 +764,34 @@ localwitness = [
# "localwitnesskeystore.json"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Commented PQ key examples contradict the "exactly one of key/seed" rule by showing both fields with one empty string. If a user uncomments these examples, startup will fail because validation treats any non-null value as present.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At common/src/main/resources/reference.conf, line 789:

<comment>Commented PQ key examples contradict the "exactly one of `key`/`seed`" rule by showing both fields with one empty string. If a user uncomments these examples, startup will fail because validation treats any non-null value as present.</comment>

<file context>
@@ -764,36 +764,34 @@ localwitness = [
+   # accountAddress =
+
+   keys = [
+     # { scheme = "FN_DSA_512", seed = "", key  = "<4352 hex chars>" },
+     # { scheme = "ML_DSA_44",  seed = "", key  = "<7744 hex chars>" },
+     # { scheme = "FN_DSA_512", seed = "<96 hex chars>", key = "" },   # drift risk — see above
</file context>
Suggested change
# "localwitnesskeystore.json"
+ # { scheme = "FN_DSA_512", key = "<4352 hex chars>" },
+ # { scheme = "ML_DSA_44", key = "<7744 hex chars>" },
+ # { scheme = "FN_DSA_512", seed = "<96 hex chars>" }, # drift risk — see above
+ # { scheme = "ML_DSA_44", seed = "<64 hex chars>" }

return new TronError(String.format(format, args), TronError.ErrCode.WITNESS_INIT);
}

private static String stripHexPrefix(String hex) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Hex prefix validation for PQ witness config fields should reject uppercase 0X and enforce the strict lowercase 0x prefix policy per project validation rules. The stripHexPrefix helper silently normalizes 0X, allowing inconsistent config formats to pass validation.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At framework/src/main/java/org/tron/core/config/args/WitnessInitializer.java, line 291:

<comment>Hex prefix validation for PQ witness config fields should reject uppercase `0X` and enforce the strict lowercase `0x` prefix policy per project validation rules. The `stripHexPrefix` helper silently normalizes `0X`, allowing inconsistent config formats to pass validation.</comment>

<file context>
@@ -175,4 +177,121 @@ static byte[] resolveWitnessAddress(
+    return new TronError(String.format(format, args), TronError.ErrCode.WITNESS_INIT);
+  }
+
+  private static String stripHexPrefix(String hex) {
+    if (hex.startsWith("0x") || hex.startsWith("0X")) {
+      return hex.substring(2);
</file context>
Suggested change
private static String stripHexPrefix(String hex) {
private static String stripHexPrefix(String hex) {
if (hex.startsWith("0x")) {
return hex.substring(2);
}
if (hex.startsWith("0X")) {
throw witnessError("hex prefix must be lowercase '0x', found '0X'");
}
return hex;
}

@Federico2014
Federico2014 merged commit ff6e24c into Federico2014:feature/pqc-signature-v4.8.2 Jun 16, 2026
1 check passed
@317787106
317787106 deleted the fix/optimize_RelayService branch July 13, 2026 03:47
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