Skip to content

Conversation

beer-1
Copy link
Member

@beer-1 beer-1 commented Oct 13, 2025

Description

This PR is related with initia-labs/cometbft#50 PR.

  • Update AddValidator to add attestor with voting power 3
  • Update RemoveValidator to allow to remove only attestor not sequencer

Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

  • New Features
    • Introduced role-based consensus power for validators (attestors vs. sequencers) with automatic assignment on creation.
    • Enforced removal permissions: only attestors can be removed; attempts to remove sequencers are rejected with clear errors.
  • Tests
    • Expanded and adjusted test coverage for validator addition/removal flows and post-update state.
  • Documentation
    • Minor wording/capitalization improvement in an error comment.
  • Chores
    • Updated ignore rules to exclude generated cache files.

@beer-1 beer-1 self-assigned this Oct 13, 2025
@beer-1 beer-1 requested a review from a team as a code owner October 13, 2025 08:09
Copy link

coderabbitai bot commented Oct 13, 2025

Walkthrough

Updates introduce consensus power roles for validators (attestor vs. sequencer), modify add/remove validator flows to set and check ConsPower, adjust tests to reflect the new removal authorization behavior, fix a comment typo, and add .gocache/ to .gitignore.

Changes

Cohort / File(s) Summary
Repo housekeeping
\.gitignore
Ignore Go build cache directory .gocache/.
Validator roles and defaults
x/opchild/types/validator.go
Add constants AttestorConsPower=3, SequencerConsPower=1. Initialize new validators with SequencerConsPower.
Msg server validator flow
x/opchild/keeper/msg_server.go
AddValidator: set new validator’s ConsPower to AttestorConsPower before persisting. RemoveValidator: require ConsPower == AttestorConsPower or return invalid request; on success set ConsPower=0 and proceed.
Tests updated for new rules
x/opchild/keeper/msg_server_test.go
Rework add/remove sequences: ensure only attestors can be removed, attempt failing sequencer removal, promote/register attestor, then remove validator; adjust expected validator set and monikers.
Comment typo fix
x/opchild/types/errors.go
Change comment wording “Antehandler” → “AnteHandler”; no logic changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant MS as MsgServer
  participant K as Keeper/Store
  participant ABCI as ABCI Updates

  rect rgb(240,248,255)
  note over C,MS: Add validator flow
  C->>MS: MsgAddValidator
  MS->>MS: Construct Validator (default SequencerConsPower)
  MS->>MS: Override ConsPower = AttestorConsPower
  MS->>K: Save validator
  K-->>MS: OK
  MS->>ABCI: Request validator set update
  ABCI-->>MS: Applied
  end

  rect rgb(250,240,230)
  note over C,MS: Remove validator flow with role check
  C->>MS: MsgRemoveValidator{valAddr}
  MS->>K: Get validator by address
  alt ConsPower != AttestorConsPower
    MS-->>C: Error (invalid request: only attestor removable)
  else ConsPower == AttestorConsPower
    MS->>MS: Set ConsPower = 0
    MS->>K: Remove/mark validator
    K-->>MS: OK
    MS->>ABCI: Request validator set update
    ABCI-->>MS: Applied
    MS-->>C: Success
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

A whisk of code, a hop of power,
Sequencers nibble, attestors flower.
Remove with care—check the role!
ConsPower carrots take their toll.
Tests now burrow, green and bright—
Cache ignored, all bytes alight.
Thump-thump—ship it right! 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly summarizes the key changes to the AddValidator and RemoveValidator functions to support adding and removing attestors, matching the PR’s intent on adjusting consensus power and removal behavior.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/attestor

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

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: 0

🧹 Nitpick comments (2)
x/opchild/keeper/msg_server.go (2)

211-217: Consider initializing ConsPower during construction.

The current implementation creates a validator with SequencerConsPower (line 211) then immediately overwrites it with AttestorConsPower (line 217). This two-step approach works but creates a momentary inconsistency.

Consider one of these alternatives:

Option 1: Set ConsPower directly after construction

 validator, err := types.NewValidator(valAddr, pk, req.Moniker)
 if err != nil {
   return nil, err
 }
-
-// attestor consensus power is always 3
-validator.ConsPower = types.AttestorConsPower
+validator.ConsPower = types.AttestorConsPower  // AddValidator always creates attestors

Option 2: Add a constructor variant
Add a NewAttestorValidator helper in types/validator.go:

func NewAttestorValidator(operator sdk.ValAddress, pubKey cryptotypes.PubKey, moniker string) (Validator, error) {
    v, err := NewValidator(operator, pubKey, moniker)
    if err != nil {
        return Validator{}, err
    }
    v.ConsPower = AttestorConsPower
    return v, nil
}

216-217: Consider adding documentation for the attestor/sequencer distinction.

The code introduces a critical architectural distinction between attestors (power 3, removable) and sequencers (power 1, permanent), but this is not documented. This could lead to confusion about:

  1. When to use AddValidator (creates attestors) vs direct SetValidator (creates sequencers)
  2. Why some validators can't be removed
  3. The purpose of the two power levels

Consider adding:

1. Package-level documentation in types/validator.go:

// Validator Roles:
//
// Sequencers (ConsPower=1): Core validators that cannot be removed via RemoveValidator.
// These are typically bootstrap validators or system-critical validators.
//
// Attestors (ConsPower=3): Dynamically managed validators that can be added and removed
// via AddValidator/RemoveValidator messages. These provide additional validation capacity.

2. Function-level documentation:

// AddValidator creates a new attestor validator with ConsPower=AttestorConsPower.
// Attestors can later be removed via RemoveValidator.
func (ms MsgServer) AddValidator(ctx context.Context, req *types.MsgAddValidator) (*types.MsgAddValidatorResponse, error) {

// RemoveValidator removes an attestor validator. Only validators with ConsPower=AttestorConsPower
// can be removed. Sequencers (ConsPower=SequencerConsPower) cannot be removed via this method.
func (ms MsgServer) RemoveValidator(ctx context.Context, req *types.MsgRemoveValidator) (*types.MsgRemoveValidatorResponse, error) {

Also applies to: 255-257

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 78a468b and 6bbe27a.

📒 Files selected for processing (5)
  • .gitignore (1 hunks)
  • x/opchild/keeper/msg_server.go (2 hunks)
  • x/opchild/keeper/msg_server_test.go (3 hunks)
  • x/opchild/types/errors.go (1 hunks)
  • x/opchild/types/validator.go (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: golangci-lint
  • GitHub Check: Run test and upload codecov
  • GitHub Check: Analyze (go)
🔇 Additional comments (7)
.gitignore (1)

56-56: LGTM!

Adding .gocache/ to .gitignore is appropriate for excluding Go build cache artifacts.

x/opchild/types/validator.go (2)

29-33: LGTM! Clear role distinction introduced.

The new constants AttestorConsPower and SequencerConsPower establish a clear distinction between validator roles based on consensus power. The documentation is helpful.


51-51: LGTM! Constructor updated to use constant.

Replacing the hardcoded 1 with SequencerConsPower improves maintainability and makes the default role explicit.

x/opchild/types/errors.go (1)

37-37: LGTM! Typo fixed.

Correcting "Antehandler" to "AnteHandler" aligns with standard Cosmos SDK terminology.

x/opchild/keeper/msg_server.go (1)

255-257: Authorization check correctly enforces attestor-only removal.

The logic correctly restricts removal to validators with AttestorConsPower, preventing accidental removal of sequencers. The error message clearly communicates the restriction.

However, consider enhancing the error message to be more explicit:

-} else if val.ConsPower != types.AttestorConsPower {
-  return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "only attestor can be removed")
+} else if val.ConsPower != types.AttestorConsPower {
+  return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "only attestor can be removed; validator has ConsPower=%d, expected %d", val.ConsPower, types.AttestorConsPower)
 }

This would help developers debug issues when removal fails unexpectedly.

x/opchild/keeper/msg_server_test.go (2)

71-110: LGTM! Test correctly validates attestor add/remove flow.

The test updates properly verify the new validator role model:

  1. Initial state: Sequencer val1 created via direct SetValidator (power 1)
  2. Add attestor: addMsg creates attestor val2 via AddValidator (power 3) → 2 validators
  3. Remove attestor: removeMsg removes val2 → 1 validator remains (val1)

The assertions correctly verify:

  • Line 94: 2 validators after add
  • Line 109-110: 1 validator remains with Moniker "val1" after removal

226-249: LGTM! Comprehensive test coverage for removal authorization.

This test correctly validates both success and failure cases:

  1. Lines 226-231: Verifies that attempting to remove a sequencer (ConsPower = 1) fails with an error
  2. Lines 233-236: Creates an attestor with explicit ConsPower = types.AttestorConsPower
  3. Lines 242-249: Verifies that the attestor can be successfully removed

The explicit setting of ConsPower on line 236 clearly demonstrates the distinction between sequencers and attestors in the test.

Copy link

codecov bot commented Oct 13, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 51.73%. Comparing base (1c8ee7f) to head (6bbe27a).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #165      +/-   ##
==========================================
+ Coverage   51.69%   51.73%   +0.03%     
==========================================
  Files          62       62              
  Lines        5186     5190       +4     
==========================================
+ Hits         2681     2685       +4     
  Misses       1977     1977              
  Partials      528      528              
Files with missing lines Coverage Δ
x/opchild/keeper/msg_server.go 64.06% <100.00%> (+0.21%) ⬆️
x/opchild/types/validator.go 33.06% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

OperatorAddress: operator.String(),
ConsensusPubkey: pkAny,
ConsPower: 1,
ConsPower: SequencerConsPower,
Copy link
Contributor

Choose a reason for hiding this comment

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

it might be good to implement both NewSequencer and NewAttestor

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