Skip to content

Conversation

@Pitasi
Copy link
Contributor

@Pitasi Pitasi commented Aug 8, 2025

Changes:

  • removes depinject (it's not going to supported by cosmos/evm, and even the Cosmos SDK team is slowly moving away from it)
  • updates cosmos/evm

This PR is blocked by: cosmos/evm#416 (one integration test currently fails)

Closes ENG-448

@vercel
Copy link

vercel bot commented Aug 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Preview Comments Updated (UTC)
warden-help-center Ignored Ignored Preview Aug 28, 2025 10:31am

@Pitasi Pitasi force-pushed the remove-depinject branch from ebf7caa to 6eb7335 Compare August 8, 2025 17:29
@Pitasi Pitasi force-pushed the remove-depinject branch 5 times, most recently from c06fd62 to 62bf372 Compare August 25, 2025 16:17
@github-actions
Copy link

github-actions bot commented Aug 25, 2025

The latest Buf updates on your PR. Results from workflow Buf CI / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed⏩ skipped✅ passedAug 28, 2025, 10:31 AM

@Pitasi Pitasi marked this pull request as ready for review August 26, 2025 09:06
@Pitasi Pitasi requested a review from a team as a code owner August 26, 2025 09:06
@github-actions

This comment has been minimized.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 26, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Removed DI-based CLI and many legacy app wiring files; introduced an explicit CLI bootstrap using a temporary in-memory app encoding, a new NewApp ModuleManager-style constructor and antecedent routing for EVM/sched/Cosmos, bank-aware precompiles, testnet tooling, consolidated Wardend config and EVM app options, widespread dependency upgrades, and multiple test/util deletions.

Changes

Cohort / File(s) Summary
CLI bootstrap & root
cmd/wardend/cmd/root.go, cmd/wardend/main.go, cmd/wardend/cmd/commands.go, cmd/wardend/cmd/config.go, cmd/wardend/cmd/wait.go*
Removed DI-based CLI wiring and legacy command/config/wait implementations; added explicit bootstrap using a temp in-memory app for encoding, initClientCtx, PersistentPreRunE, newApp and appExport implementations.
Testnet CLI & fixtures
cmd/wardend/cmd/testnet.go
Added testnet CLI with init-files and start subcommands and NewTestNetworkFixture to create in-process testnets and per-validator genesis/gentx generation.
Cmd config additions
cmd/wardend/config/chain_id.go, cmd/wardend/config/config.go, cmd/wardend/config/wardend_config.go, cmd/wardend/config/evm_app_options.go
Added GetChainIDFromHome, EVMChainID const, MustGetDefaultNodeHome, BlockedAddresses/macc perms, WardenAppConfig + InitAppConfig, and EvmAppOptions (EVM coin/chain config and denom registration).
App core rewrite
warden/app/app.go, warden/app/export.go, warden/app/legacy.go, warden/app/app_config.go
Replaced DI/runtime wiring with a ModuleManager-style NewApp; exposed many getters and NewTxConfig; converted export/zero-height code to return errors; removed legacy app_config and legacy wiring files.
Ante handler refactor
warden/app/ante/ante.go, warden/app/ante/options.go, warden/app/ante/cosmos.go, warden/app/ante/evm_handler.go, warden/app/ante/sched_handler.go
Introduced ante.HandlerOptions, Validate, and NewAnteHandler that routes transactions by extension options to Cosmos/EVM/sched ante chains and builds per-path decorator chains.
Precompiles: BankKeeper wiring
precompiles/precompiles.go, precompiles/act/act.go, precompiles/async/async.go, precompiles/sched/sched.go, precompiles/warden/warden.go
Added evmcmn.BankKeeper parameter across precompile constructors and NewWardenPrecompiles; wired SetBalanceHandler(bankKeeper) into precompiles and updated signatures.
Precompile runtime simplifications
precompiles/json/json.go, precompiles/slinky/slinky.go
Removed Before/After balance-change hooks and ignored unused stateDB in JSON precompile; retained gas error handling.
Precompiles options & defaults
warden/app/precompiles.go
Introduced Optionals and functional options for address/validator/consensus codecs; changed NewAvailableStaticPrecompiles signature (opts ...Option) and removed evidenceKeeper param.
Oracle / mempool / vemanager tweaks
warden/app/oracle.go, warden/app/vemanager/vemanager.go
Adjusted proposal handler mempool/signer-extraction wiring and added panic stack-printing/recovery in pre-block and vote-extension wrapper.
Export / zero-height fixes
warden/app/export.go
Converted prepForZeroHeightGenesis to return errors (no panics), adjusted ExportAppStateAndValidators signature, and switched to tmproto header.
Sched keeper minor change
warden/x/sched/keeper/abci.go
Call to FromEthereumTx made unconditional and tx.From set from privkey-derived pubkey address; minor comment fix.
Test utilities & snapshots
tests/framework/exec/warden_eth.go, tests/framework/snapshot/snapshots.go, cmd/wardend/cmd/testnet.go, warden/testutil/**
Adjusted gas/timeouts and WaitMined usage, added feemarket.no_base_fee in snapshots, added testnet tooling; removed many test helpers (network, nullify, sample) and simulation benchmarks/tests.
Module scaffolding & minor edits
warden/x/*/..., proto/warden/act/v1beta1/query.proto
Removed Ignite/Starport scaffolding comments across many modules, deleted several module genesis tests, added async StoreKey const.
Dependency & tooling updates
go.mod, justfile, localnet.just, CHANGELOG.md, tests/slinky/go.mod, tests/slinky/slinky_test.go
Updated dependencies (cosmos/evm/evmd, wasmvm→v3, many version bumps), adjusted justfile checksums and deploy flags, removed evm_chain_id from localnet.just, updated CHANGELOG.

Files marked with * were deleted or had their contents removed.

Sequence Diagram(s)

%%{init: {"theme": "base", "themeVariables": {"primaryColor":"#0B6E99","noteBkg":"#F2F8FB","actorBorder":"#0B6E99"}}}%%
sequenceDiagram
  autonumber
  actor User
  participant CLI as wardend CLI
  participant TempApp as tempApp (encoding)
  participant Viper as Viper (config)
  participant App as newApp
  participant Comet as CometBFT

  User->>CLI: invoke wardend <command>
  CLI->>TempApp: construct temp app to derive encodingConfig
  CLI->>Viper: read client & app config (home, chain-id)
  Viper-->>CLI: clientCtx & templates
  CLI->>App: newApp(logger, db, appOpts)
  App-->>CLI: server.Application instance
  CLI->>Comet: serve/start/status/genesis/tx/query
Loading
%%{init: {"theme": "base", "themeVariables": {"primaryColor":"#0B6E99","noteBkg":"#F2F8FB"}}}%%
sequenceDiagram
  autonumber
  participant BaseApp as BaseApp
  participant Router as Ante Router
  participant Cosmos as Cosmos Ante Chain
  participant EVM as EVM Mono Ante
  participant Sched as Sched Ante Chain
  participant Tx as Transaction

  BaseApp->>Router: deliverTx/checkTx(Tx)
  alt Tx has extension options
    Router->>Router: inspect first extension option TypeUrl
    alt sched callbacks
      Router->>Sched: execute sched ante
    else ethereum tx extension
      Router->>EVM: execute mono-EVM ante
    else dynamic fee ext
      Router->>Cosmos: execute cosmos ante
    else unknown ext
      Router-->>BaseApp: return ErrUnknownExtensionOptions
    end
  else no extension options
    Router->>Cosmos: execute cosmos ante
  end
  Router-->>BaseApp: return (ctx, err)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120+ minutes

Possibly related PRs

  • Migration to Cosmos/EVM #1519 — Overlaps on CLI/app bootstrap and EVM setup refactor (cmd/wardend bootstrapping, NewApp and EVM options changes).
  • Cosmos EVM 1.0.0 rc2 #1571 — Related Cosmos‑EVM integration and precompile/run behavior changes (evm/evmd versioning and precompile adjustments).
  • Added async precompile #1160 — Related async/precompile wiring and precompile constructor signature changes (async precompile & bankKeeper wiring).
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch remove-depinject

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit 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:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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
Contributor

@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: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (9)
go.mod (1)

19-21: Security: upgrade gin to ≥ v1.7.7 to address GHSA-h395-qcrw-5vmq

The GitHub advisory GHSA-h395-qcrw-5vmq (CVE-2020-28483) affects all github.com/gin-gonic/gin versions below 1.7.7; v1.7.0 remains vulnerable and does not include the patch (osv.dev, miggo.io).
Please bump the module requirement in go.mod to at least v1.7.7—or better yet, to the latest stable release—to fully remediate this issue.

• File: go.mod (lines 19–21)
Update the gin replacement line as follows:

- github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.0
+ github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.7.7
warden/app/export.go (2)

61-71: Allowed-addresses map uses non-canonical keys; may jail allowed validators

You validate each bech32 address but store the original string as the map key, later checking with addr.String() (canonical form). If inputs vary in case/format, lookups fail and validators get jailed unintentionally.

Apply:

-allowedAddrsMap := make(map[string]bool)
+allowedAddrsMap := make(map[string]bool)

 for _, addr := range jailAllowedAddrs {
-  _, err := sdk.ValAddressFromBech32(addr)
+  va, err := sdk.ValAddressFromBech32(addr)
   if err != nil {
-    log.Fatal(err)
+    return fmt.Errorf("invalid validator address in allowlist %q: %w", addr, err)
   }
-
-  allowedAddrsMap[addr] = true
+  // Use canonical representation to match addr.String() later
+  allowedAddrsMap[va.String()] = true
 }

Also prefer returning an error instead of process exit; see next comment.

Also applies to: 214-216


65-69: Avoid panic/log.Fatal; propagate errors to caller

This function is now error-returning, but several paths still panic or call log.Fatal, which aborts the process and undermines graceful export handling.

Replace panics/log.Fatal with error returns:

-    if err != nil {
-      log.Fatal(err)
-    }
+    if err != nil {
+      return fmt.Errorf("invalid validator address in allowlist %q: %w", addr, err)
+    }
-    if err != nil {
-      panic(err)
-    }
+    if err != nil {
+      return fmt.Errorf("invalid validator address %q in delegation: %w", delegation.ValidatorAddress, err)
+    }
-    if err != nil {
-      panic(err)
-    }
+    if err != nil {
+      return fmt.Errorf("invalid validator address %q in delegation: %w", del.ValidatorAddress, err)
+    }
-    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
-      // never called as BeforeDelegationCreated always returns nil
-      panic(fmt.Errorf("error while incrementing period: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("before-delegation-created hook failed: %w", err)
+    }
-    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
-      // never called as AfterDelegationModified always returns nil
-      panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("after-delegation-modified hook failed: %w", err)
+    }
-  if err != nil {
-    log.Fatal(err)
-  }
+  if err != nil {
+    return fmt.Errorf("apply validator set updates: %w", err)
+  }

Also applies to: 92-93, 104-105, 111-117, 231-233

precompiles/async/async.go (1)

50-64: Fail fast if bankKeeper is nil to avoid runtime panics in balance hooks

NewPrecompile now depends on a working BankKeeper. Add a guard so we don’t wire a nil handler and later crash at Before/AfterBalanceChange.

Apply this diff:

 func NewPrecompile(
 	asynckeeper asyncmodulekeeper.Keeper,
 	bankKeeper evmcmn.BankKeeper,
 	er *common.EthEventsRegistry,
 ) (*Precompile, error) {
 	abi, err := LoadABI()
 	if err != nil {
 		return nil, err
 	}
 
+	if bankKeeper == nil {
+		return nil, fmt.Errorf("async precompile: bankKeeper must not be nil")
+	}
+
 	p := Precompile{
 		Precompile: evmcmn.Precompile{
 			ABI:                  abi,
 			KvGasConfig:          storetypes.KVGasConfig(),
 			TransientKVGasConfig: storetypes.TransientGasConfig(),
 		},
 		asyncmodulekeeper: asynckeeper,
 		eventsRegistry:    er,
 		queryServer:       asyncmodulekeeper.NewQueryServerImpl(asynckeeper),
 	}
precompiles/sched/sched.go (2)

143-148: Bug: IsTransaction() always returns false; ExecuteCallbacksMethod must be treated as a transaction

This breaks gas/tx semantics and can misclassify state-changing calls as queries.

Apply this diff:

 func (p *Precompile) IsTransaction(method *abi.Method) bool {
-	switch method.Name {
-	default:
-		return false
-	}
+	switch method.Name {
+	// transactions
+	case ExecuteCallbacksMethod:
+		return true
+	// queries
+	case CallbackByIdMethod, CallbacksMethod, GetAddressMethod:
+		return false
+	default:
+		return false
+	}
 }

52-56: Validate bankKeeper is provided before wiring the balance handler

Mirror the async/act/warden constructors and fail fast on nil to avoid later crashes.

Apply this diff:

 	abi, err := LoadABI()
 	if err != nil {
 		return nil, err
 	}
 
+	if bankKeeper == nil {
+		return nil, fmt.Errorf("sched precompile: bankKeeper must not be nil")
+	}

Add the missing import:

// at the top import block
import (
    "embed"
+   "fmt"
    ...
)
warden/app/precompiles.go (2)

82-104: Validate codec parameter is non-nil.

The function should validate that the codec parameter is not nil before using it.

 func NewAvailableStaticPrecompiles(
 	stakingKeeper stakingkeeper.Keeper,
 	distributionKeeper distributionkeeper.Keeper,
 	bankKeeper cmn.BankKeeper,
 	erc20Keeper erc20Keeper.Keeper,
 	transferKeeper transferkeeper.Keeper,
 	channelKeeper *channelkeeper.Keeper,
 	evmKeeper *evmkeeper.Keeper,
 	govKeeper govkeeper.Keeper,
 	slashingKeeper slashingkeeper.Keeper,
 	wardenKeeper wardenkeeper.Keeper,
 	actKeeper actkeeper.Keeper,
 	oracleKeeper *oraclekeeper.Keeper,
 	asyncKeeper asynckeeper.Keeper,
 	schedKeeper schedkeeper.Keeper,
 	codec codec.Codec,
 	opts ...Option,
 ) map[common.Address]vm.PrecompiledContract {
+	if codec == nil {
+		panic("codec cannot be nil")
+	}
+
 	options := defaultOptionals()
 	for _, opt := range opts {
 		opt(&options)
 	}

188-209: Add nil check for bankKeeper parameter.

The bankKeeper is a critical dependency that should be validated.

 wardenprecompiles, err := wardenprecompiles.NewWardenPrecompiles(
 	bankKeeper,
 	wardenKeeper,
 	actKeeper,
 	*oracleKeeper,
 	asyncKeeper,
 	schedKeeper,
 	evmKeeper,
 )
 if err != nil {
-	panic(err)
+	panic(fmt.Errorf("failed to create warden precompiles: %w", err))
 }
precompiles/precompiles.go (1)

36-44: Validate bankKeeper parameter.

The bankKeeper is now a critical dependency for all precompiles and should be validated.

 func NewWardenPrecompiles(
 	bankKeeper evmcmn.BankKeeper,
 	wardenkeeper wardenkeeper.Keeper,
 	actkeeper actkeeper.Keeper,
 	oraclekeeper oraclekeeper.Keeper,
 	asynckeeper asynckeeper.Keeper,
 	schedkeeper schedkeeper.Keeper,
 	evmKeeper *evmkeeper.Keeper,
 ) (map[ethcmn.Address]vm.PrecompiledContract, error) {
+	if bankKeeper == nil {
+		return nil, fmt.Errorf("bankKeeper cannot be nil")
+	}
+
 	precompiles := make(map[ethcmn.Address]vm.PrecompiledContract)
 	eventsRegistry := cmn.NewEthEventsRegistry()
🧹 Nitpick comments (58)
warden/x/act/module/simulation.go (1)

52-54: Empty slice return for ProposalMsgs — LGTM; align ProposalContents for consistency

Returning an empty slice here is good practice (stable JSON marshalling and fewer nil checks). For consistency across the module, consider also returning an empty slice from ProposalContents instead of nil.

Suggested change outside the selected lines:

 func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg {
-	return nil
+	return []simtypes.WeightedProposalMsg{}
 }
warden/x/async/module/simulation.go (1)

65-67: Good switch to empty slice; mirror the pattern in ProposalContents

The explicit empty slice avoids nil-vs-empty edge cases downstream. To keep the API style uniform in this file, mirror this in ProposalContents.

Suggested change outside the selected lines:

 func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg {
-	return nil
+	return []simtypes.WeightedProposalMsg{}
 }
warden/x/sched/module/simulation.go (1)

46-49: Empty slice for ProposalMsgs — LGTM; minor cleanup in WeightedOperations

Change looks good. As a small cleanup, WeightedOperations currently allocates an empty slice via make(...) and then returns it. You can return the empty literal directly to avoid the intermediate variable.

Suggested change outside the selected lines:

 func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
-	operations := make([]simtypes.WeightedOperation, 0)
-
-	return operations
+	return []simtypes.WeightedOperation{}
 }
warden/x/warden/module/simulation.go (1)

51-54: LGTM on empty slice; make ProposalContents consistent

Returning []simtypes.WeightedProposalMsg{} is a sensible default. Consider switching ProposalContents to return an empty slice too for consistency with this method and with WeightedOperations’ empty slice style.

Suggested change outside the selected lines:

 func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalMsg {
-	return nil
+	return []simtypes.WeightedProposalMsg{}
 }
tests/framework/exec/warden_eth.go (2)

69-71: Avoid hard-coding GasLimit; let the backend estimate per tx

Dropping the limit from 10,000,000,000 to 10,000,000 is sane, but keeping a fixed limit is still brittle across networks and tx types. Prefer estimation so calls don’t silently pass with too much headroom or fail on networks with tighter per-block limits.

  • Let bind/backend estimate gas by setting GasLimit to 0.
  • Keep legacy GasPrice only if the target EVM doesn’t support 1559; otherwise prefer GasFeeCap/GasTipCap. Verify what cosmos/evm exposes in your target version.

Apply this minimal change:

-  auth.GasLimit = uint64(10_000_000) // in units
+  auth.GasLimit = 0 // let the backend estimate per call

88-92: 5s mining timeout is likely too aggressive; increase or derive from test deadline to avoid flakes

Under CI load or slower block times, 5 seconds can cause intermittent failures. Bump to a safer default (e.g., 30s) and include the tx hash in the failure message for faster triage.

Minimal, low-risk tweak:

-  ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
+  ctx, cancel := context.WithTimeout(t.Context(), 30*time.Second)
   defer cancel()

   receipt, err := bind.WaitMined(ctx, c.Client, tx)
-  require.NoError(t, err)
+  require.NoError(t, err, "tx %s", tx.Hash())

If you want a more robust approach, derive the timeout from t.Deadline() with a sane fallback and a small headroom; I can provide a helper for that on request.

warden/x/async/types/v1beta1/keys.go (2)

16-22: Consider adding RouterKey and MemStoreKey for completeness and future-proofing.

These are commonly used alongside StoreKey in module wiring (routing msgs and mounting in-memory stores). Adding them now prevents ad-hoc literals later.

Apply within this const block:

 const (
   // ModuleName defines the module name.
   ModuleName = "async"

   // StoreKey defines the primary module store key.
   StoreKey = ModuleName
+
+  // RouterKey defines the message routing key.
+  RouterKey = ModuleName
+  // MemStoreKey defines the in-memory store key.
+  MemStoreKey = "mem_" + ModuleName
 )

24-24: Minor consistency improvement: derive ParamsKey from ModuleName.

Avoids accidental drift if ModuleName changes and keeps keys colocated.

Example:

var ParamsKey = []byte("p_" + ModuleName)
warden/x/act/types/v1beta1/genesis_test.go (2)

29-33: Optional: run subtests in parallel

If Validate() is pure and does not touch global state, add t.Parallel() inside the subtest to speed up the suite.

-    t.Run(tc.desc, func(t *testing.T) {
-      err := tc.genState.Validate()
+    t.Run(tc.desc, func(t *testing.T) {
+      t.Parallel()
+      err := tc.genState.Validate()

24-26: Clarify intent of zero-value genesis validity in TestGenesisState_Validate

The test in warden/x/act/types/v1beta1/genesis_test.go currently asserts that both the default and an empty (&GenesisState{}) genesis pass validation. That’s correct given that Validate() simply returns nil, but the intent could be clearer. Consider the following optional refinements:

  • In the second test case, rename the description to explicitly call out a zero-value state:
    • File: warden/x/act/types/v1beta1/genesis_test.go
    • Change
    {
      desc:     "valid genesis state",
      genState: &types.GenesisState{},
      valid:    true,
    },
    to
    {
      desc:     "zero-value genesis is valid",
      genState: &types.GenesisState{},
      valid:    true,
    },
  • If it was unintentional to treat a completely empty GenesisState as valid, adjust valid to false (or remove this case) so that only DefaultGenesis() is accepted.
  • Although Params.Validate() currently always returns nil, review whether you intend to enforce non-zero defaults in future (e.g., require MaxPendingTime > 0) rather than silently accepting an empty Params struct.

Diff suggestion:

--- a/warden/x/act/types/v1beta1/genesis_test.go
+++ b/warden/x/act/types/v1beta1/genesis_test.go
@@ -24,7 +24,7 @@ func TestGenesisState_Validate(t *testing.T) {
         {
             desc:     "default is valid",
             genState: types.DefaultGenesis(),
-            valid:    true,
+            valid:    true,
         },
         {
-            desc:     "valid genesis state",
+            desc:     "zero-value genesis is valid",
             genState: &types.GenesisState{},
             valid:    true,
         },
warden/x/sched/types/v1beta1/genesis_test.go (1)

29-33: Optional: parallelize subtests

Same note as above; add t.Parallel() within the subtest if safe.

-    t.Run(tc.desc, func(t *testing.T) {
-      err := tc.genState.Validate()
+    t.Run(tc.desc, func(t *testing.T) {
+      t.Parallel()
+      err := tc.genState.Validate()
warden/x/warden/types/v1beta3/genesis_test.go (2)

29-33: Optional: subtest parallelization

Consider t.Parallel() at the start of the subtest body if no shared mutable state is involved.

-    t.Run(tc.desc, func(t *testing.T) {
-      err := tc.genState.Validate()
+    t.Run(tc.desc, func(t *testing.T) {
+      t.Parallel()
+      err := tc.genState.Validate()

24-26: Confirm zero-value genesis is intentionally valid

The Validate() method only invokes Params.Validate() (which is currently a no-op), so both the default genesis and a zero-value GenesisState return no error. The existing tests already cover these two scenarios. For clarity, you may optionally rename the second test’s description:

• In warden/x/warden/types/v1beta3/genesis_test.go, update the second case:

   {
-    desc:     "valid genesis state",
+    desc:     "zero-value genesis is valid",
    genState: &types.GenesisState{},
    valid:    true,
   },

No functional changes are required.

tests/framework/snapshot/snapshots.go (1)

91-95: Make no_base_fee configurable via BuildOptions (default stays true).

Hard-coding no_base_fee=true is fine for most tests, but we’ll likely want scenarios that exercise base-fee behavior. Expose it via an option so callers can flip it without a custom EditGenesis. This keeps the current default behavior while improving flexibility.

Apply within this hunk:

-	genesis.Set("app_state.feemarket.params.no_base_fee", true)
+	genesis.Set("app_state.feemarket.params.no_base_fee", opts.NoBaseFee)

And add this field to BuildOptions (outside this hunk):

 type BuildOptions struct {
   Name           string
   ChainID        string
   Denom          string
   KeyringBackend string
   Accounts       []AccountOptions
   Spaces         []SpaceOptions
   Keychains      []KeychainOptions
   Plugins        []string
   Precompiles    []string
   EditSnapshot   func(Builder)
   EditGenesis    func(*GenesisBuilder)
+  // NoBaseFee controls app_state.feemarket.params.no_base_fee (default true to preserve existing behavior).
+  // Callers can set it explicitly when needed.
+  NoBaseFee      bool
 }

If you prefer to preserve the current default without touching all call sites, introduce a small defaulting shim:

// before genesis.Set(...)
noBaseFee := opts.NoBaseFee
if !optsProvided { // e.g., if you add a pointer field instead: *bool
    noBaseFee = true
}
genesis.Set("app_state.feemarket.params.no_base_fee", noBaseFee)
warden/x/sched/keeper/abci.go (1)

19-22: Alias geth crypto import to avoid ambiguity with stdlib crypto packages.

Minor readability nit: importing github.com/ethereum/go-ethereum/crypto as crypto alongside crypto/ecdsa can confuse readers and IDEs. Prefer an explicit alias.

-	"github.com/ethereum/go-ethereum/crypto"
+	gethcrypto "github.com/ethereum/go-ethereum/crypto"

…and update usages:

-	tx.From = crypto.PubkeyToAddress(privkey.PublicKey).Bytes()
+	tx.From = gethcrypto.PubkeyToAddress(privkey.PublicKey).Bytes()
warden/app/upgrades.go (1)

3-5: Use pointer receiver for RegisterUpgradeHandlers to avoid copying App.

This method will eventually mutate registries/keepers; using a value receiver would mutate a copy. Switch to a pointer receiver preemptively to prevent subtle bugs when you add handlers.

-func (app App) RegisterUpgradeHandlers() {
+func (app *App) RegisterUpgradeHandlers() {
 	// No upgrades registered yet
 }
warden/app/vemanager/vemanager.go (1)

44-50: Log panic value and stack with the SDK logger before re-panicking.

Printing to stderr works but is easy to miss and lacks chain context. Log via ctx.Logger() with the panic value and stack; then re-panic to preserve consensus behavior. This aids debugging in production setups.

-		defer func() {
-			if err := recover(); err != nil {
-				debug.PrintStack()
-				panic(err)
-			}
-		}()
+		defer func() {
+			if r := recover(); r != nil {
+				ctx.Logger().Error("panic in VoteExtensionManager.ExtendVoteHandler",
+					"panic", r,
+					"stack", string(debug.Stack()),
+					"height", ctx.BlockHeight(),
+				)
+				panic(r)
+			}
+		}()

Optional follow-up: add the same guard in VerifyVoteExtensionHandler for symmetry.

cmd/wardend/config/chain_id.go (1)

3-9: Wrap errors with context and validate the returned chain ID.

Improve diagnosability when the file is missing/malformed and fail fast on empty chain IDs.

 package config
 
 import (
+	"fmt"
 	"path/filepath"
 
 	"github.com/cosmos/cosmos-sdk/client/config"
 	"github.com/spf13/viper"
 )
 
 // GetChainIDFromHome returns the chain ID from the client configuration
 // in the given home directory.
 func GetChainIDFromHome(home string) (string, error) {
 	v := viper.New()
 	v.AddConfigPath(filepath.Join(home, "config"))
 	v.SetConfigName("client")
 	v.SetConfigType("toml")
 
-	if err := v.ReadInConfig(); err != nil {
-		return "", err
+	if err := v.ReadInConfig(); err != nil {
+		return "", fmt.Errorf("reading client config from %s: %w", filepath.Join(home, "config", "client.toml"), err)
 	}
 
 	conf := new(config.ClientConfig)
 
-	if err := v.Unmarshal(conf); err != nil {
-		return "", err
+	if err := v.Unmarshal(conf); err != nil {
+		return "", fmt.Errorf("unmarshalling client config: %w", err)
 	}
 
-	return conf.ChainID, nil
+	if conf.ChainID == "" {
+		return "", fmt.Errorf("chain ID is empty in %s", filepath.Join(home, "config", "client.toml"))
+	}
+	return conf.ChainID, nil
 }

Also applies to: 18-29

prophet/registry.go (4)

41-46: Return plugin names in deterministic order

Iteration order over maps is randomized; returning unsorted names can produce flakey tests and nondeterministic UX. Sort before returning.

-import (
-	"fmt"
-	"sync"
-)
+import (
+	"fmt"
+	"sort"
+	"sync"
+)
@@
-	plugins := make([]string, 0, len(registry.plugins))
-	for name := range registry.plugins {
+	plugins := make([]string, 0, len(registry.plugins))
+	for name := range registry.plugins {
 		plugins = append(plugins, name)
 	}
 
-	return plugins
+	sort.Strings(plugins)
+	return plugins

23-25: Use a plain formatted string in panic to avoid wrapping an error

Panicking with an error is fine, but using a string reduces cognitive overhead and avoids an extra allocation for the error value.

-	if _, found := registry.plugins[name]; found {
-		panic(fmt.Errorf("plugin %s registered twice", name))
-	}
+	if _, found := registry.plugins[name]; found {
+		panic(fmt.Sprintf("plugin %s registered twice", name))
+	}

8-8: Fix stale comment: “tasks plugins” → “plugins”

Aligns the comment with the rename from tasks to plugins.

-// registry is a global registry of tasks plugins.
+// registry is a global registry of plugins.

30-35: Consider surfacing “not found” explicitly

getPlugin returns nil when missing, which can hide configuration errors until a later method call panics. If you can change call sites, prefer returning (Plugin, bool).

-func getPlugin(name string) Plugin {
+func getPlugin(name string) (Plugin, bool) {
 	registry.rw.RLock()
 	defer registry.rw.RUnlock()
 
-	return registry.plugins[name]
+	p, ok := registry.plugins[name]
+	return p, ok
}
warden/app/oracle.go (2)

259-265: Improve recovered panic logging in PreBlocker

debug.PrintStack() prints to stderr and re-panicking may lose the original stack in some setups. Log the stack via ctx.Logger() and rethrow the original value for better observability.

 return func(ctx sdk.Context, req *cometabci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) {
-		defer func() {
-			if err := recover(); err != nil {
-				debug.PrintStack()
-				panic(err)
-			}
-		}()
+		defer func() {
+			if r := recover(); r != nil {
+				ctx.Logger().Error("preblock panic", "err", r, "stack", string(debug.Stack()))
+				panic(r)
+			}
+		}()

317-319: Clarify the purpose of TxSelector or remove until used

TxSelector embeds App but has no methods or interface conformance in this file. If it’s a placeholder for mempool selection, add a doc comment and its intended interface, or drop until it’s actually used.

Would you like me to wire this to the EVM mempool interfaces (e.g., provide selection/filter funcs) in a follow-up?

warden/app/ante/options.go (2)

13-23: Doc string says IBC/Wasm keepers are required; Validate only enforces wasm config/store service

Either adjust the doc or enforce presence of the keepers that are marked as “required”.

-// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
-//
-// channel keeper, wasm keeper and evm keepers.
+// HandlerOptions extends the SDK/EVM AnteHandler options and includes IBC and
+// CosmWasm-specific knobs needed by Wardend’s ante chain.

25-40: Enforce non-nil WasmKeeper/IBCKeeper if they are truly required

If your ante chain depends on these keepers, fail fast here.

 func (options HandlerOptions) Validate() error {
 	if err := options.HandlerOptions.Validate(); err != nil {
 		return err
 	}
 
 	if options.NodeConfig == nil {
 		return errors.New("wasm config is required for ante builder")
 	}
 
 	if options.TXCounterStoreService == nil {
 		return errors.New("wasm store service is required for ante builder")
 	}
 
+	if options.WasmKeeper == nil {
+		return errors.New("wasm keeper is required for ante builder")
+	}
+
+	// If IBC ante steps are wired, enforce IBCKeeper as well.
+	// Remove this check if truly optional in your wiring.
+	if options.IBCKeeper == nil {
+		return errors.New("ibc keeper is required for ante builder")
+	}
+
 	return nil
 }

If IBCKeeper/WasmKeeper are optional in your current ante path, ignore this and align the comment instead (previous note).

justfile (1)

28-30: Harden jq extraction and drop quotes from variables

  • Use -r for raw output to avoid quoted strings.
  • Handle both “_contract_address” and “contract_address” keys for broader wasm versions.
-    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas 10000000 --fees 1award | wardend q wait-tx -o json | jq '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value | tonumber')
-    ADDR=$(wardend tx wasm instantiate $CODE_ID '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees 1award -y | wardend q wait-tx -o json | jq '.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address") | .value')
+    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas 10000000 --fees 1award \
+      | wardend q wait-tx -o json \
+      | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' )
+    ADDR=$(wardend tx wasm instantiate "$CODE_ID" '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees 1award -y \
+      | wardend q wait-tx -o json \
+      | jq -r '.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address" or .key == "contract_address") | .value' )
go.mod (2)

55-57: Track the evm/evmd RC and pseudo-version pinning

You’re on cosmos/evm v0.5.0-rc.0 and a pseudo-version for evmd (likely a commit from the pending PR). Once cosmos/evm#416 lands, please move to a tagged release for both to reduce supply-chain churn.

Would you like a follow-up patch that bumps these to the first stable release once the PR merges?


11-25: Consolidate Pebble Version Pinning in go.mod

I’ve confirmed that your go.mod both:

  • Pins Pebble to the older commit v0.0.0-20230928194634-aa077af62593 via a replace at line 12, and
  • Still lists an indirect require for Pebble v1.1.5 at line 187.

While the replace override makes this safe, having both can be confusing for future maintainers. To tidy this up, please consider one of the following:

  • Run go mod tidy to remove the now-redundant indirect require github.com/cockroachdb/pebble v1.1.5.
  • Or, if you intentionally want to keep the indirect entry as documentation, add a brief comment above it explaining that the replace is required to satisfy Geth’s build constraints.

Optional: update the in-file comment on the replace to reference why exactly this commit is chosen (e.g., “pin to this commit to avoid breaking changes in Geth’s build”).

warden/app/export.go (2)

75-81: Ignored errors when withdrawing rewards/commission

WithdrawValidatorCommission and WithdrawDelegationRewards errors are ignored. If distribution state is inconsistent, you’ll silently proceed with an invalid export.

Handle and aggregate errors:

-_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator()))
+if _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+  return fmt.Errorf("withdraw validator commission %s: %w", val.GetOperator(), err)
+}
-_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
+if _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr); err != nil {
+  return fmt.Errorf("withdraw delegation rewards %s->%s: %w", delAddr, valAddr, err)
+}

Also applies to: 97-98


133-153: Reduce err shadowing inside closure to improve clarity

Multiple short declarations with err (scraps, feePool, Set, Hooks) shadow outer err, which can be confusing. It’s correct but brittle.

Refactor to use distinct names or a single scoped err to avoid shadowing.

precompiles/json/json.go (1)

96-104: Optional: guard against unknown method names in Run

Currently, an unknown method name yields bz=nil, err=nil if not matched. Consider a default branch returning a clear error.

 switch method.Name {
   // queries
   case BuildMethod:
     bz, err = p.Build(ctx, method, args)
   case ParseMethod:
     bz, err = p.Parse(ctx, method, args)
+  default:
+    return nil, fmt.Errorf("json precompile: unsupported method %s", method.Name)
 }
precompiles/act/act.go (2)

96-149: Defensive nil-guard around balance handler calls

If future refactors forget to set the handler, these calls will panic.

- p.GetBalanceHandler().BeforeBalanceChange(ctx)
+ if h := p.GetBalanceHandler(); h != nil {
+   h.BeforeBalanceChange(ctx)
+ }
...
- if err = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB); err != nil {
+ if h := p.GetBalanceHandler(); h != nil {
+   if err = h.AfterBalanceChange(ctx, stateDB); err != nil {
+     return nil, err
+   }
+ }

119-121: Intentional difference between evm.Origin and contract.Caller()?

VoteForActionMethod uses contract.Caller() while other tx paths use evm.Origin. If this is intentional (e.g., voting by caller vs origin), add a short comment to prevent regressions.

- bz, err = p.VoteForActionMethod(ctx, evm.Origin, contract.Caller(), stateDB, method, args)
+ // Use contract.Caller() to attribute votes to the immediate caller (not necessarily tx origin).
+ bz, err = p.VoteForActionMethod(ctx, evm.Origin, contract.Caller(), stateDB, method, args)
cmd/wardend/config/config.go (2)

41-45: SetFullFundraiserPath: LGTM; keep nolint but reference rationale

Using types.BIP44HDPath with nolint is deliberate. Add a brief comment linking to the SDK deprecation note to reduce churn for future maintainers.

- config.SetFullFundraiserPath(types.BIP44HDPath) //nolint:staticcheck
+ //nolint:staticcheck -- SetFullFundraiserPath is deprecated in SDK, maintained for hd path compatibility.
+ config.SetFullFundraiserPath(types.BIP44HDPath)

29-31: Make EVMChainID Configurable Across All Commands

The hard-coded constant

// cmd/wardend/config/config.go:30
EVMChainID = uint64(1337)

is currently pulled in by multiple entry points and configuration constructors:

  • cmd/wardend/cmd/testnet.go
    • Lines ~250–254:
    evm := cosmosevmserverconfig.DefaultEVMConfig()
    evm.EVMChainID = evmdconfig.EVMChainID
    • Lines ~646–658: passed into the simulated‐app builder via evmdconfig.EVMChainID
  • cmd/wardend/cmd/root.go
    • Line 68: passed to simtestutil.NewApp as wardendconfig.EVMChainID
    • Lines 139–142: overridden when a --chain-id flag is provided and parsed by parseEVMChainID
  • cmd/wardend/config/wardend_config.go
    • Line 141–142:
    evmCfg := cosmosevmserverconfig.DefaultEVMConfig()
    evmCfg.EVMChainID = evmChainID

To allow non-dev networks to override the chain ID safely:

  • Expose an evmChainID field in your application’s config struct (backed by Viper/TOML, environment or CLI flag).
  • Default that field to 1337 when unspecified.
  • In all call sites above, drop direct references to the constant and instead read from the new config field.
  • Hook up a CLI flag (e.g. --evm-chain-id) to parseEVMChainID so it flows into the shared config used by both the root and testnet commands, as well as the wardend_config builder.

This preserves the local/dev default while enabling easy overrides for testnet and mainnet.

warden/app/ante/evm_handler.go (1)

9-22: Guard TxListener decorator behind a nil check

Some environments won’t provide a PendingTxListener; adding it unconditionally risks a nil deref inside the decorator.

Apply this diff:

 func newMonoEVMAnteHandler(options HandlerOptions) sdk.AnteHandler {
-	decorators := []sdk.AnteDecorator{
-		evmante.NewEVMMonoDecorator(
-			options.AccountKeeper,
-			options.FeeMarketKeeper,
-			options.EvmKeeper,
-			options.MaxTxGasWanted,
-		),
-		ante.NewTxListenerDecorator(options.PendingTxListener),
-	}
+	decorators := []sdk.AnteDecorator{
+		evmante.NewEVMMonoDecorator(
+			options.AccountKeeper,
+			options.FeeMarketKeeper,
+			options.EvmKeeper,
+			options.MaxTxGasWanted,
+		),
+	}
+	if options.PendingTxListener != nil {
+		decorators = append(decorators, ante.NewTxListenerDecorator(options.PendingTxListener))
+	}
 
 	return sdk.ChainAnteDecorators(decorators...)
 }
localnet.just (1)

76-76: Use readiness loop instead of fixed sleep for contract deployment

A fixed 5s delay is flaky on slower machines/CI. Poll the RPC to ensure the node is up before deploying.

Apply this diff:

-      sleep 5
+      # Wait up to 60s for RPC to become available
+      for i in {1..60}; do
+        if command -v curl >/dev/null && curl -sf http://127.0.0.1:26657/status >/dev/null; then
+          break
+        fi
+        sleep 1
+      done
precompiles/warden/warden.go (4)

53-76: Guard against a nil BankKeeper in NewPrecompile.

If a nil bankKeeper bubbles in, balance handling will panic later at runtime. Fail fast in the constructor.

Apply this diff:

 func NewPrecompile(
 	wardenkeeper wardenmodulekeeper.Keeper,
 	actkeeper actmodulekeeper.Keeper,
-	bankKeeper evmcmn.BankKeeper,
+	bankKeeper evmcmn.BankKeeper,
 	e *precommon.EthEventsRegistry,
 ) (*Precompile, error) {
+	if bankKeeper == nil {
+		return nil, fmt.Errorf("warden precompile: bankKeeper must not be nil")
+	}
@@
-	p.SetAddress(common.HexToAddress(PrecompileAddress))
+	p.SetAddress(p.Address())
 	p.SetBalanceHandler(bankKeeper)

200-235: Avoid panicking on unknown ABI method in IsTransaction.

Even if “should never happen”, a panic in a precompile can take down the VM. Return false instead; Run will still fail gracefully when method dispatch doesn’t match.

Apply this diff:

 	default:
-		panic(fmt.Errorf("warden precompile: method not exists: %s", method))
+		return false
 	}

85-103: RequiredGas override is fine; keep an eye on ABI desync.

The override and call into embedded Precompile.RequiredGas look right. If ABI changes but IsTransaction isn’t updated, gas classification may drift. Consider a small unit test that iterates ABI methods and asserts IsTransaction covers all names.


111-116: Standardize conditional AfterBalanceChange across all precompiles

Verified that each of the four precompiles invokes

p.GetBalanceHandler().BeforeBalanceChange(ctx)
…  
if err = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB); err != nil {  
    return nil, err  
}

in symmetric positions. To guarantee that AfterBalanceChange still runs on every successful path (including early returns) and always after HandleGasError (LIFO defer order), we should replace the explicit call with a conditional defer in each precompile.

Affected locations:

  • precompiles/warden/warden.go (Before: L111–116; After: L188–190)
  • precompiles/sched/sched.go (Before: L106; After: L136)
  • precompiles/act/act.go (Before: L103; After: L144)
  • precompiles/async/async.go (Before: L103; After: L134)

Example diff for warden.go:

 	p.GetBalanceHandler().BeforeBalanceChange(ctx)

 	// This handles any out of gas errors that may occur during the execution of a precompile tx or query.
 	// It avoids panics and returns the out of gas error so the EVM can continue gracefully.
+	// Defer balance finalization; will only run if err stays nil and will execute after HandleGasError
+	// since this defer is registered before it (LIFO).
+	defer func() {
+		if err == nil {
+			_ = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB)
+		}
+	}()
 	defer evmcmn.HandleGasError(ctx, contract, initialGas, &err)()
@@
-	if err = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB); err != nil {
-		return nil, err
-	}

Please apply this pattern to the other three precompiles to maintain consistency.

cmd/wardend/main.go (1)

24-28: Minor: make setupSDKConfig idempotent-safe across multiple invocations.

SDK config is a singleton; SetBech32Prefixes is benign but you could guard with a sync.Once if setupSDKConfig might be reused in tests.

warden/app/config.go (2)

19-22: Prefer sync.Once over a package-scoped boolean for thread-safety and testability.

While current init is single-threaded, sync.Once clarifies intent and avoids races in concurrent test runners. Expose a test-only reset if needed.

Example refactor (outside the selected lines, illustrative):

// at top of file
var setupEVMOnce sync.Once

func (app *App) setupEVM(evmChainID uint64) error {
	var setupErr error
	setupEVMOnce.Do(func() {
		eip712.SetEncodingConfig(app.legacyAmino, app.interfaceRegistry, evmChainID)

		if err := setBaseDenom(coinInfo); err != nil {
			setupErr = err
			return
		}

		ethCfg := evmtypes.DefaultChainConfig(evmChainID)
		setupErr = evmtypes.NewEVMConfigurator().
			WithChainConfig(ethCfg).
			WithEVMCoinInfo(coinInfo).
			Configure()
	})
	return setupErr
}

24-37: Validate legacyAmino/interfaceRegistry non-nil before SetEncodingConfig.

A defensive check can surface mis-ordered app wiring early with a clear error.

Proposed guard (within the function body):

if app.legacyAmino == nil || app.interfaceRegistry == nil {
	return fmt.Errorf("setupEVM: codec/registry not initialized")
}
warden/app/ante/ante.go (3)

13-17: Typo: “it's respective handler” → “its respective handler”.

Apply this diff:

-// transaction-level processing (e.g. fee payment, signature verification) before
-// being passed onto it's respective handler.
+// transaction-level processing (e.g. fee payment, signature verification) before
+// being passed onto its respective handler.

17-22: Add early validation of HandlerOptions in NewAnteHandler

To ensure required keepers are wired and to fail fast, invoke the existing Validate() method on HandlerOptions at the start of the ante handler closure.

• File: warden/app/ante/ante.go
• Location: inside NewAnteHandler, immediately before any further logic

Suggested diff:

 func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
     return func(
         ctx sdk.Context, tx sdk.Tx, sim bool,
     ) (newCtx sdk.Context, err error) {
+        // Fail fast on invalid/missing options
+        if err := options.Validate(); err != nil {
+            return ctx, err
+        }
         var anteHandler sdk.AnteHandler
         // … rest of handler setup …

The Validate() method is already implemented on HandlerOptions (see warden/app/ante/options.go:26), so this simple invocation provides early error detection.


31-37: Use proto.MessageName for ExtensionOptions to avoid hard-coded URLs

To make the code resilient to upstream changes, derive the full type URL from the proto message types instead of embedding string literals. Based on our search, the two extension options are defined in:

  • wardenjs/proto/ethermint/evm/v1/tx.proto
    • message ExtensionOptionsEthereumTx
  • wardenjs/proto/ethermint/types/v1/dynamic_fee.proto
    • message ExtensionOptionDynamicFeeTx

We can replace the hard-coded cases with:

-import (
-   // … other imports
-)
+import (
+   "google.golang.org/protobuf/proto"
+   vmv1 "your/module/path/wardenjs/proto/ethermint/evm/v1"
+   typesv1 "your/module/path/wardenjs/proto/ethermint/types/v1"
+)

 // …
 switch extOpt.TypeUrl {
-  case "/cosmos.evm.vm.v1.ExtensionOptionsEthereumTx":
+  case "/" + proto.MessageName(&vmv1.ExtensionOptionsEthereumTx{}):
     // handle as *evmtypes.MsgEthereumTx
     anteHandler = newMonoEVMAnteHandler(options)
-  case "/cosmos.evm.types.v1.ExtensionOptionDynamicFeeTx":
+  case "/" + proto.MessageName(&typesv1.ExtensionOptionDynamicFeeTx{}):
     // cosmos-sdk tx with dynamic fee extension
     anteHandler = newCosmosAnteHandler(options)
  default:
     // …
 }

Points to verify:

  • Confirm the Go module path and package aliases (vmv1, typesv1) match the go_package option in each .proto.
  • Update imports in warden/app/ante/ante.go to reference the correct generated Go packages.
  • Run go build ./warden/app/ante to ensure nothing breaks.
warden/app/ante/sched_handler.go (2)

25-28: Comment clarity.

Tighten the warning to avoid contractions in docs.

Apply this diff:

-		// This transaction will bypass normal authentication checks such as signature and nonce.
-		// It's dangerous and should only be allowed if built by the x/sched module.
+		// This transaction bypasses normal authentication checks such as signature and nonce.
+		// It is dangerous and should only be allowed if built by the x/sched module.

39-51: Defense-in-depth: restrict messages to EVM messages only (already enforced) and consider empty-tx guard.

You already unpack each msg via UnpackEthMsg which enforces EVM messages. Optionally add a guard to reject empty txs early for clearer errors.

Example:

if len(tx.GetMsgs()) == 0 {
	return ctx, errorsmod.Wrapf(errortypes.ErrInvalidRequest, "empty system transaction")
}
cmd/wardend/config/wardend_config.go (2)

43-61: Consider documenting the module account permissions.

The maccPerms variable contains critical security permissions for module accounts. Consider adding documentation for each permission to explain why specific permissions are granted to each module.

Add comments explaining the rationale for each module's permissions:

 // module account permissions.
 var maccPerms = map[string][]string{
+	// FeeCollector receives transaction fees
 	authtypes.FeeCollectorName:     nil,
+	// Distribution module needs no special permissions
 	distrtypes.ModuleName:          nil,
+	// IBC transfer needs minter/burner for cross-chain token transfers
 	ibctransfertypes.ModuleName:    {authtypes.Minter, authtypes.Burner},
 	// ... continue for other modules

120-186: Consider extracting magic values as constants.

The configuration initialization contains several hardcoded values (timeout durations, ports, etc.). Consider extracting these as named constants for better maintainability.

+const (
+	defaultOracleTimeout = time.Second * 2
+	defaultOracleAddress = "localhost:8080"
+)

 func InitAppConfig(denom string, evmChainID uint64) (string, any) {
 	// ...
 	oracleCfg := oracleconfig.AppConfig{
 		Enabled:        true,
-		OracleAddress:  "localhost:8080",
-		ClientTimeout:  time.Second * 2,
+		OracleAddress:  defaultOracleAddress,
+		ClientTimeout:  defaultOracleTimeout,
 		MetricsEnabled: true,
 	}
cmd/wardend/cmd/root.go (1)

161-164: Handle potential error from EnhanceRootCommand.

While panicking might be acceptable during initialization, consider logging more context.

 if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
-	panic(err)
+	panic(fmt.Errorf("failed to enhance root command with AutoCLI: %w", err))
 }
warden/app/app.go (5)

915-918: Hard-coded BlockGasLimit for EVMMempool; should sync with consensus params

BlockGasLimit: 100_000_000 is a static value and may diverge from the actual consensus block gas limit, leading to admission discrepancies.

Consider one of:

  • Read the current block gas limit from consensus params at BeginBlock and update the mempool configuration accordingly.
  • Source the limit from a single config (e.g., app options or FeeMarket/EVM params) to keep it in sync with consensus.

1425-1431: Local variable name shadows the imported url package

url, err := url.Parse(u) shadows the net/url import, reducing readability and increasing risk of mistakes in adjacent code.

Rename the local variable:

-    url, err := url.Parse(u)
+    ppURL, err := url.Parse(u)
     if err != nil {
       panic(fmt.Errorf("invalid pricepred url: %s", u))
     }
 
-    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(url))
+    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(ppURL))

1318-1337: Minor: unnecessary zero-length hint in map construction

make(map[string]appmodule.AppModule, 0) doesn’t need the zero capacity. Prefer make(map[string]appmodule.AppModule) for idiomatic Go.

-  modules := make(map[string]appmodule.AppModule, 0)
+  modules := make(map[string]appmodule.AppModule)

1282-1306: Close() should tolerate nil mempool without calling GetMempool() method chain

app.GetMempool() may be nil if EVM chain config was not set or mempool wasn’t initialized; your type assertion guards usage, which is good. Consider adding a fast path nil check to avoid the method call altogether (micro-optimization, optional).


1126-1131: GetMemKey returns from a nil map (memKeys is never initialized)

memKeys is declared on the struct but not initialized. Reads from a nil map return zero values, so this is safe, but confusing. Either initialize memKeys or remove it if unused.

Copy link
Contributor

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
warden/app/config.go (1)

10-17: Avoid silent no-op and detect EVM chain ID mismatches after first initialization

setupEVM returns nil on repeated calls. If a subsequent call passes a different evmChainID, the function silently does nothing, leaving a stale EIP-155 chain ID for EIP-712 and EVM config. This can lead to signing/verification inconsistencies and hard-to-debug behavior in multi-app test runs or tooling that constructs multiple App instances.

Introduce a sealedChainID guard and error on mismatch so misconfiguration is surfaced early.

Apply this diff:

 var sealed = false
+var sealedChainID uint64

 func (app *App) setupEVM(evmChainID uint64) error {
   if sealed {
-    return nil
+    if evmChainID != sealedChainID {
+      return fmt.Errorf("setupEVM already initialized with chain ID %d (got %d)", sealedChainID, evmChainID)
+    }
+    return nil
   }
@@
   sealed = true
+  sealedChainID = evmChainID

Also applies to: 19-22

warden/app/export.go (4)

65-71: Do not abort the process; return errors instead of log.Fatal

In prepForZeroHeightGenesis, encountering an invalid validator address logs a fatal and exits the process. This defeats callers’ error handling and can kill nodes/tools unexpectedly.

Apply this diff:

 for _, addr := range jailAllowedAddrs {
   _, err := sdk.ValAddressFromBech32(addr)
   if err != nil {
-    log.Fatal(err)
+    return fmt.Errorf("invalid validator address %q: %w", addr, err)
   }
   allowedAddrsMap[addr] = true
 }

90-98: Avoid panics when parsing addresses; propagate errors

The current code panics on malformed bech32 addresses. Return errors instead so the caller can handle them.

Apply this diff:

-  valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
-  if err != nil {
-    panic(err)
-  }
-  delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
+  valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
+  if err != nil {
+    return fmt.Errorf("invalid validator address in delegation: %w", err)
+  }
+  delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
+  if err != nil {
+    return fmt.Errorf("invalid delegator address in delegation: %w", err)
+  }

And similarly for the re-initialization loop:

-  valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
-  if err != nil {
-    panic(err)
-  }
-  delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress)
+  valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
+  if err != nil {
+    return fmt.Errorf("invalid validator address in delegation: %w", err)
+  }
+  delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress)
+  if err != nil {
+    return fmt.Errorf("invalid delegator address in delegation: %w", err)
+  }

Also applies to: 102-108


109-117: Hooks: replace panics with error propagation

Both BeforeDelegationCreated and AfterDelegationModified error paths panic. Keep the function error-returning and propagate failures.

Apply this diff:

-  if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
-    // never called as BeforeDelegationCreated always returns nil
-    panic(fmt.Errorf("error while incrementing period: %w", err))
-  }
+  if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
+    return fmt.Errorf("before-delegation-created hook: %w", err)
+  }
@@
-  if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
-    // never called as AfterDelegationModified always returns nil
-    panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
-  }
+  if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
+    return fmt.Errorf("after-delegation-modified hook: %w", err)
+  }

230-233: Avoid log.Fatal on ApplyAndReturnValidatorSetUpdates

log.Fatal exits the process; propagate the error instead.

Apply this diff:

 _, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
 if err != nil {
-  log.Fatal(err)
+  return fmt.Errorf("apply validator set updates: %w", err)
 }
♻️ Duplicate comments (7)
warden/app/export.go (1)

225-228: Iterator close error is swallowed; return it

The error from iter.Close() is logged and the function returns nil, losing the error. Return the Close() error wrapped with context.

Apply this diff:

 if err := iter.Close(); err != nil {
   app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
-  return nil
+  return fmt.Errorf("closing validator reverse iterator: %w", err)
 }
cmd/wardend/cmd/root.go (3)

434-441: Fix temp directory prefix name

Prefix should reflect the binary (“wardend”), not “wasmd”.

Apply this diff:

-var tempDir = func() string {
-  dir, err := os.MkdirTemp("", "wasmd")
+var tempDir = func() string {
+  dir, err := os.MkdirTemp("", "wardend")
   if err != nil {
     panic("failed to create temp dir: " + err.Error())
   }
   return dir
 }

134-146: Replace panics with returned errors in PreRunE

PreRunE should never panic on flag parsing. Return errors so Cobra can render them.

Apply this diff:

  chainID, err := cmd.Flags().GetString(flags.FlagChainID)
  if err != nil {
-   panic(err)
+   return fmt.Errorf("failed to get chain ID: %w", err)
  }

  evmChainID := wardendconfig.EVMChainID
  if chainID != "" {
-   var err error
-   evmChainID, err = parseEVMChainID(chainID)
-   if err != nil {
-     panic(err)
-   }
+   var pErr error
+   evmChainID, pErr = parseEVMChainID(chainID)
+   if pErr != nil {
+     return fmt.Errorf("failed to parse EVM chain ID from %q: %w", chainID, pErr)
+   }
  }

422-431: Validate chain ID format before slicing; clearer error messages

parseEVMChainID assumes the presence and order of '_' and '-'. Add validation to avoid out-of-range slicing and produce clearer errors.

Apply this diff:

 func parseEVMChainID(chainID string) (uint64, error) {
   from := strings.LastIndexByte(chainID, '_')
   to := strings.LastIndexByte(chainID, '-')
-
-  evmChainID, err := strconv.ParseUint(chainID[from+1:to], 10, 64)
+  if from == -1 || to == -1 || from >= to {
+    return 0, fmt.Errorf("invalid chain ID format (expected '<prefix>_<number>-<suffix>'): %s", chainID)
+  }
+  part := chainID[from+1 : to]
+  if part == "" {
+    return 0, fmt.Errorf("empty numeric section in chain ID: %s", chainID)
+  }
+  evmChainID, err := strconv.ParseUint(part, 10, 64)
   if err != nil {
     return 0, fmt.Errorf("can't parse evm chain id from %s: %w", chainID, err)
   }
   return evmChainID, nil
 }
warden/app/app.go (3)

801-841: PreBlockers ordering is configured but never wired into BaseApp

You set SetOrderPreBlockers, but BaseApp never gets a PreBlocker. Without app.SetPreBlocker, pre-blockers won’t execute at all during FinalizeBlock.

Apply this wiring alongside Begin/End blocker registration:

-  app.SetInitChainer(app.InitChainer)
-  app.SetBeginBlocker(app.BeginBlocker)
-  app.SetEndBlocker(app.EndBlocker)
+  app.SetInitChainer(app.InitChainer)
+  app.SetPreBlocker(app.PreBlocker)
+  app.SetBeginBlocker(app.BeginBlocker)
+  app.SetEndBlocker(app.EndBlocker)

Also applies to: 973-977


912-927: EVM mempool is constructed before AnteHandler is set, leading to a nil/old ante in mempool

The EVMMempool is created using AnteHandler: app.GetAnteHandler() before app.SetAnteHandler(...) runs. This captures a nil/incorrect handler and may bypass ante checks in mempool.

  • Remove the premature initialization:
-  // mempool initialization (EVM priority nonce mempool)
-  if evmtypes.GetChainConfig() != nil {
-    // TODO: Get the actual block gas limit from consensus parameters
-    mempoolConfig := &evmmempool.EVMMempoolConfig{
-      AnteHandler:   app.GetAnteHandler(),
-      BlockGasLimit: 100_000_000,
-    }
-
-    evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-    app.EVMMempool = evmMempool
-
-    app.SetMempool(evmMempool)
-    checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
-    app.SetCheckTxHandler(checkTxHandler)
-  }
  • Re-create the mempool after ante/post handlers are configured (right after app.setPostHandler()):
@@
   app.setPostHandler()
+
+  // mempool initialization (EVM priority nonce mempool)
+  if evmtypes.GetChainConfig() != nil {
+    // TODO: derive the block gas limit from consensus parameters
+    mempoolConfig := &evmmempool.EVMMempoolConfig{
+      AnteHandler:   app.GetAnteHandler(), // now set by setAnteHandler
+      BlockGasLimit: 100_000_000,
+    }
+    evmMempool := evmmempool.NewExperimentalEVMMempool(
+      app.CreateQueryContext, logger,
+      app.EVMKeeper, app.FeeMarketKeeper,
+      app.txConfig, app.clientCtx,
+      mempoolConfig,
+    )
+    app.EVMMempool = evmMempool
+    app.SetMempool(evmMempool)
+    app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
+  }

Follow-ups:

  • If EVMMempool caches the ante handler internally by value, prefer re-instantiating on handler changes or exposing a setter.
  • Ensure app.clientCtx is initialized before mempool construction or pass a minimal default client.Context.

Also applies to: 973-1006


1045-1057: InitChainer unmarshals the entire app genesis into an EVM-only struct; InitGenesis gets the wrong payload

req.AppStateBytes contains the full genesis map (module name → raw JSON). It must be unmarshaled into map[string]json.RawMessage and passed to ModuleManager.InitGenesis.

Apply this fix:

 func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
-  var genesisState cosmosevmtypes.GenesisState
-  if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
+  var genesisState map[string]json.RawMessage
+  if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
     panic(err)
   }
 
   if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
     panic(err)
   }
 
-  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
+  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
 }
🧹 Nitpick comments (12)
warden/app/oracle.go (3)

259-265: Recover + re-panic resets the original stack; log context before re-panicking

The current recover prints the current stack and then re-panics, which loses the original panic stack in the re-panic. Prefer logging rich context (height, proposer, etc.) and the debug.Stack() bytes, then re-panicking.

Apply this diff to improve observability:

-        defer func() {
-            if err := recover(); err != nil {
-                debug.PrintStack()
-                panic(err)
-            }
-        }()
+        defer func() {
+            if r := recover(); r != nil {
+                // Log with context before re-panicking so we keep block info in logs.
+                stack := debug.Stack()
+                ctx.Logger().Error(
+                    "panic during PreBlock",
+                    "panic", r,
+                    "height", ctx.BlockHeight(),
+                    "stack", string(stack),
+                )
+                panic(r)
+            }
+        }()

Additionally, consider guarding against nil responses below when combining results:

-        return &sdk.ResponsePreBlock{
-            ConsensusParamsChanged: respA.ConsensusParamsChanged || respB.ConsensusParamsChanged,
-        }, nil
+        cpChanged := (respA != nil && respA.ConsensusParamsChanged) || (respB != nil && respB.ConsensusParamsChanged)
+        return &sdk.ResponsePreBlock{ConsensusParamsChanged: cpChanged}, nil

317-319: TxSelector is currently unused – remove or document its intended role

Confirmed via rg -nP '\bTxSelector\b' that TxSelector only appears at its declaration in warden/app/oracle.go (lines 317–319), with no other references.

Suggestions:

  • If this stub is reserved for future wiring of custom transaction selectors, add a doc comment above it, for example:
    +// TxSelector is a forward-compatibility stub for plugging in custom transaction selection logic.
    +// It will satisfy the `oracle.TxSelectorInterface` once that interface is defined.
    type TxSelector struct {
        App
    }
  • Otherwise, eliminate the type to prevent unneeded API surface:
    -type TxSelector struct {
    -    App
    -}

57-62: Document EVM Mempool Fallback in baseProposalHandler

The application’s EVM mempool is correctly wired during initialization (see app.go:921–923, where app.SetMempool(evmMempool) is called), so passing nil into NewDefaultProposalHandler(nil, app) will fall back to the EVM mempool rather than the SDK default. To make this explicit for future maintainers, please add a comment above the handler construction:

 func (app *App) baseProposalHandler() *baseapp.DefaultProposalHandler {
-	abciProposalHandler := baseapp.NewDefaultProposalHandler(nil, app)
+	// By passing nil here, DefaultProposalHandler will use the mempool set on the app
+	// (the EVM mempool is configured in app.go via app.SetMempool(evmMempool))
+	abciProposalHandler := baseapp.NewDefaultProposalHandler(nil, app)

 	abciProposalHandler.SetSignerExtractionAdapter(
 		evmmempool.NewEthSignerExtractionAdapter(
 			sdkmempool.NewDefaultSignerExtractionAdapter(),
 		),
 	)

 	return abciProposalHandler
 }

Alternatively (though not strictly necessary), you may pass app.EVMMempool explicitly instead of nil to remove any ambiguity.

warden/x/sched/keeper/abci.go (1)

21-21: Alias go-ethereum crypto for clarity and to avoid stdlib confusion

Minor readability nit: alias the go-ethereum crypto import (and the call site) to avoid ambiguity with the standard library packages and to make grepping easier.

Apply:

@@
-	"github.com/ethereum/go-ethereum/crypto"
+	ethcrypto "github.com/ethereum/go-ethereum/crypto"
@@
-	tx.From = crypto.PubkeyToAddress(privkey.PublicKey).Bytes()
+	tx.From = ethcrypto.PubkeyToAddress(privkey.PublicKey).Bytes()

Also applies to: 169-169

warden/app/precompiles.go (2)

40-76: Option pattern is solid; minor naming and shadowing nits

The Optionals pattern is clean and extensible. Two small improvements:

  • Rename Optionals to Options (conventional).
  • Avoid parameter names that shadow imported package identifiers (e.g., codec).

Apply this diff:

-type Optionals struct {
+type Options struct {
@@
-func defaultOptionals() Optionals {
-  return Optionals{
+func defaultOptionals() Options {
+  return Options{
@@
-type Option func(opts *Optionals)
+type Option func(opts *Options)
@@
-func WithAddressCodec(codec address.Codec) Option {
-  return func(opts *Optionals) {
-    opts.AddressCodec = codec
+func WithAddressCodec(addrCodec address.Codec) Option {
+  return func(opts *Options) {
+    opts.AddressCodec = addrCodec
   }
 }
@@
-func WithValidatorAddrCodec(codec address.Codec) Option {
-  return func(opts *Optionals) {
-    opts.ValidatorAddrCodec = codec
+func WithValidatorAddrCodec(valCodec address.Codec) Option {
+  return func(opts *Options) {
+    opts.ValidatorAddrCodec = valCodec
   }
 }
@@
-func WithConsensusAddrCodec(codec address.Codec) Option {
-  return func(opts *Optionals) {
-    opts.ConsensusAddrCodec = codec
+func WithConsensusAddrCodec(consCodec address.Codec) Option {
+  return func(opts *Options) {
+    opts.ConsensusAddrCodec = consCodec
   }
 }

154-161: Rename function parameter to avoid shadowing codec package

The parameter codec codec.Codec shadows the imported "codec" package identifier, which is mildly confusing. Prefer cdc.

Apply this diff:

-  codec codec.Codec,
+  cdc codec.Codec,
@@
-  govPrecompile, err := govprecompile.NewPrecompile(
+  govPrecompile, err := govprecompile.NewPrecompile(
@@
-    codec,
+    cdc,
cmd/wardend/cmd/root.go (3)

100-109: Avoid shadowing initClientCtx inside PreRunE

Using := re-declares initClientCtx and can be confusing. Use = to keep a single variable in scope inside the closure.

Apply this diff:

-      initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
+      initClientCtx, err = client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())

155-163: AutoCLI config: redundant ReadFromClientConfig

You call ReadFromClientConfig inside PreRunE and again here. The second call is likely redundant.

Apply this diff to remove the duplicate invocation:

-  initClientCtx, _ = clientcfg.ReadFromClientConfig(initClientCtx)
-  autoCliOpts.ClientCtx = initClientCtx
+  autoCliOpts.ClientCtx = initClientCtx

297-315: newApp: Prefer returning errors over panics where feasible

I realize the signature imposed by Cosmosevm server expects a constructor, but consider minimizing panics (e.g., parseEVMChainID failures) by validating earlier (PreRunE) and setting a sane default if missing. Not a blocker.

I can thread validated evmChainID via appOpts to avoid re-parsing here.

warden/app/app.go (2)

1425-1431: Avoid shadowing the imported url package with a local variable name

Using url := url.Parse(...) shadows the imported package, which reduces readability and risks mistakes in future edits.

Apply a tiny rename:

-    url, err := url.Parse(u)
+    parsedPricepredURL, err := url.Parse(u)
     if err != nil {
         panic(fmt.Errorf("invalid pricepred url: %s", u))
     }
 
-    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(url))
+    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(parsedPricepredURL))

1494-1501: Handle potential error from NewInterfaceRegistryWithOptions in NewTxConfig

types.NewInterfaceRegistryWithOptions returns (InterfaceRegistry, error). You currently ignore the error; if the registry fails to build, returning a TxConfig will mask the root cause.

Consider:

-  interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
+  interfaceRegistry, err := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
       ProtoFiles:     proto.HybridResolver,
       SigningOptions: signingOptions,
   })
+  if err != nil {
+      panic(fmt.Errorf("failed to create interface registry: %w", err))
+  }
   codec := codec.NewProtoCodec(interfaceRegistry)
   return authtx.NewTxConfig(codec, authtx.DefaultSignModes)
justfile (1)

28-29: Parameterize gas/fees, emit raw values, and support both contract address keys

Hard-coding gas and fees can break across networks and testnets. Also, jq without -r returns quoted strings, which is awkward for reuse. Finally, some CosmWasm versions emit contract_address instead of _contract_address. Suggest the following targeted tweaks:

  • Make gas/fees configurable via env with sane defaults.
  • Use jq -r to return raw values.
  • Accept either _contract_address or contract_address.
  • Quote $CODE_ID during reuse.
-    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas 10000000 --fees 1award | wardend q wait-tx -o json | jq '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value | tonumber')
-    ADDR=$(wardend tx wasm instantiate $CODE_ID '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees 1award -y | wardend q wait-tx -o json | jq '.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address") | .value')
+    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas "${GAS:-10000000}" --fees "${FEES:-1award}" \
+        | wardend q wait-tx -o json \
+        | jq -r '.events[] | select(.type=="store_code") | .attributes[] | select(.key=="code_id") | .value | tonumber')
+    ADDR=$(wardend tx wasm instantiate "${CODE_ID}" '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees "${FEES:-1award}" -y \
+        | wardend q wait-tx -o json \
+        | jq -r '.events[] | select(.type=="instantiate") | .attributes[] | select(.key=="_contract_address" or .key=="contract_address") | .value')

Optional hardening outside the changed lines (no diff needed): after each assignment, fail fast if empty:

  • test -n "$CODE_ID" || { echo "Failed to extract code id"; exit 1; }
  • test -n "$ADDR" || { echo "Failed to extract contract address"; exit 1; }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ecd3266 and 7ecd4da.

⛔ Files ignored due to path filters (64)
  • go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (71)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (2 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (1 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (2 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (31)
  • warden/app/ante.go
  • warden/x/warden/module/autocli.go
  • warden/x/async/module/genesis.go
  • warden/x/warden/module/genesis.go
  • warden/app/sim_test.go
  • warden/x/async/module/genesis_test.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/sched/module/genesis.go
  • warden/x/sched/types/v1beta1/genesis.go
  • warden/x/act/module/autocli.go
  • warden/x/warden/types/v1beta3/genesis.go
  • cmd/wardend/cmd/commands.go
  • warden/testutil/network/network.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/act/types/v1beta1/genesis.go
  • warden/app/legacy.go
  • warden/x/act/module/genesis.go
  • warden/x/sched/module/genesis_test.go
  • warden/x/act/types/v1beta1/codec.go
  • warden/testutil/nullify/nullify.go
  • warden/x/async/types/v1beta1/genesis.go
  • warden/app/app_config.go
  • cmd/wardend/cmd/wait.go
  • warden/testutil/sample/sample.go
  • warden/x/act/module/genesis_test.go
  • warden/x/sched/module/autocli.go
  • warden/x/warden/module/genesis_test.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/app/sim_bench_test.go
  • cmd/wardend/cmd/config.go
  • precompiles/slinky/slinky.go
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (30)
  • warden/x/sched/module/simulation.go
  • warden/app/vemanager/vemanager.go
  • tests/framework/snapshot/snapshots.go
  • warden/x/sched/types/v1beta1/genesis_test.go
  • warden/x/async/types/v1beta1/keys.go
  • precompiles/sched/sched.go
  • warden/app/ante/options.go
  • cmd/wardend/config/chain_id.go
  • precompiles/async/async.go
  • precompiles/act/act.go
  • precompiles/json/json.go
  • warden/app/upgrades.go
  • warden/x/act/module/simulation.go
  • tests/framework/exec/warden_eth.go
  • warden/app/ante/evm_handler.go
  • cmd/wardend/cmd/testnet.go
  • cmd/wardend/config/config.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • warden/x/async/module/simulation.go
  • warden/app/ante/sched_handler.go
  • warden/app/ante/ante.go
  • go.mod
  • warden/app/ante/cosmos.go
  • cmd/wardend/config/wardend_config.go
  • precompiles/warden/warden.go
  • warden/x/warden/module/simulation.go
  • prophet/registry.go
  • warden/x/warden/types/v1beta3/genesis_test.go
  • cmd/wardend/main.go
  • localnet.just
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-11-21T11:35:35.678Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#1095
File: warden/app/oracle.go:0-0
Timestamp: 2024-11-21T11:35:35.678Z
Learning: In the Go file `warden/app/oracle.go`, it is acceptable to panic inside the goroutine that starts the oracle client, because an error here indicates a misconfiguration (e.g., the address was misconfigured), and the application should exit.

Applied to files:

  • warden/app/oracle.go
📚 Learning: 2024-10-16T16:01:11.241Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-10-16T16:01:11.241Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
📚 Learning: 2025-02-06T08:48:57.285Z
Learnt from: mn13
PR: warden-protocol/wardenprotocol#1216
File: warden/x/async/keeper/abci.go:212-216
Timestamp: 2025-02-06T08:48:57.285Z
Learning: In the collections package from Cosmos SDK, calling Keys() on an iterator fully consumes and closes the iterator, making an explicit Close() call unnecessary.

Applied to files:

  • warden/app/export.go
🧬 Code graph analysis (7)
warden/app/config.go (1)
warden/app/app.go (1)
  • App (183-254)
warden/app/oracle.go (1)
warden/app/app.go (1)
  • App (183-254)
cmd/wardend/cmd/root.go (4)
warden/app/app.go (2)
  • NewApp (256-1022)
  • App (183-254)
cmd/wardend/config/config.go (2)
  • EVMChainID (30-30)
  • BaseDenom (26-26)
cmd/wardend/config/wardend_config.go (2)
  • MustGetDefaultNodeHome (34-41)
  • InitAppConfig (122-186)
cmd/wardend/config/chain_id.go (1)
  • GetChainIDFromHome (12-29)
warden/app/export.go (1)
warden/app/app.go (1)
  • App (183-254)
precompiles/precompiles.go (6)
warden/x/async/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (31-35)
warden/x/sched/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (18-22)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
warden/app/precompiles.go (5)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
precompiles/slinky/slinky.go (1)
  • NewPrecompile (47-70)
warden/app/app.go (8)
warden/x/act/keeper/keeper.go (2)
  • Keeper (21-38)
  • NewKeeper (48-91)
warden/x/async/keeper/keeper.go (2)
  • Keeper (34-61)
  • NewKeeper (79-145)
warden/x/warden/keeper/keeper.go (2)
  • Keeper (18-45)
  • NewKeeper (62-122)
warden/x/sched/keeper/keeper.go (2)
  • Keeper (22-34)
  • NewKeeper (44-76)
warden/app/oracle.go (1)
  • SlinkyClient (64-74)
cmd/wardend/config/wardend_config.go (2)
  • GetMaccPerms (98-100)
  • BlockedAddresses (69-95)
warden/app/precompiles.go (1)
  • NewAvailableStaticPrecompiles (82-211)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
⏰ 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). (9)
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (15)
warden/app/oracle.go (2)

3-17: LGTM on new imports for signer extraction and stack tracing

  • Bringing in sdkmempool and evmmempool to wire the ETH signer extraction adapter is appropriate.
  • runtime/debug is justified by the new recover block in combinePreBlocker.

107-120: Confirmed: panic on oracle client start error is acceptable here

This aligns with our prior decision for warden/app/oracle.go: a failure to connect indicates misconfiguration and should abort startup. No change requested.

warden/x/sched/keeper/abci.go (1)

168-170: Derive and validate the sender from the signed tx; confirm FromEthereumTx() signature

We ran a local search and confirmed:

  • No local definition of MsgEthereumTx.FromEthereumTx that returns an error.
  • No call sites in this repo expect or check an error from FromEthereumTx.
  • All precompile methods authorize via evm.Origin or contract.Caller(), never tx.From, so overriding tx.From has no immediate privilege impact.

⚠️ FromEthereumTx is implemented in the external x/evm/types module (pinned in your go.mod). Please manually verify that in the exact version you’ve vendored or tagged, FromEthereumTx still does not return an error and that its behavior matches expectations.

File: warden/x/sched/keeper/abci.go (around lines 168–170)

Suggested optional refactor:

-   tx.FromEthereumTx(signedEthTx)
-   tx.From = crypto.PubkeyToAddress(privkey.PublicKey).Bytes()
+   tx.FromEthereumTx(signedEthTx)
+   signer := ethtypes.LatestSignerForChainID(signedEthTx.ChainId())
+   sender, err := ethtypes.Sender(signer, signedEthTx)
+   if err != nil {
+       return nil, fmt.Errorf("derive sender from signedEthTx: %w", err)
+   }
+   // Defensive: ensure the derived sender matches the key we used to sign.
+   expected := crypto.PubkeyToAddress(privkey.PublicKey)
+   if sender != expected {
+       return nil, fmt.Errorf("sender mismatch: got %s, expected %s", sender.Hex(), expected.Hex())
+   }
+   tx.From = sender.Bytes()
warden/app/config.go (1)

24-29: Ensure codecs are initialized before calling eip712.SetEncodingConfig

SetEncodingConfig uses app.legacyAmino and app.interfaceRegistry. If setupEVM is invoked before these are initialized, it will panic. Verify the call order in NewApp guarantees both are non-nil before setupEVM is called; alternatively, add a defensive check and return a descriptive error.

Would you like me to wire a small nil-check here with a unit test that fails when called too early?

warden/app/export.go (1)

239-254: LGTM: error propagation for signing infos

This section correctly accumulates iterErr via SetValidatorSigningInfo and propagates it after iteration.

warden/app/precompiles.go (2)

97-104: Initialize options: OK; verify bech32 prefixes are set before defaultOptionals()

defaultOptionals pulls bech32 prefixes from sdk.GetConfig(). Ensure those prefixes are configured before NewAvailableStaticPrecompiles is called; otherwise codecs will be built with empty/incorrect prefixes.

If needed, I can add an assertion here to fail fast when prefixes are empty.


165-171: Slashing precompile wiring: LGTM

Validator and consensus address codecs are injected via options; good separation of concerns.

precompiles/precompiles.go (1)

36-44: BankKeeper injection across warden precompiles: LGTM

Constructor signatures and SetBalanceHandler usage look consistent. Centralized events registry is a nice touch.

Also applies to: 48-53, 65-71, 101-106, 121-127

cmd/wardend/cmd/root.go (5)

51-70: Temporary app bootstrap for encoding config: LGTM

Pre-instantiating the app to derive encoding, then cleaning up the temp directory, is a pragmatic approach.


110-128: Textual sign mode setup: LGTM

Conditionally enabling SIGN_MODE_TEXTUAL when online and wiring TextualCoinMetadataQueryFn is correct.


168-178: initTendermintConfig: LGTM

Returning defaults with clearly commented optional overrides is fine.


180-234: Root command assembly: LGTM

Command composition, start options, and tx flags wiring look consistent with Cosmos EVM server patterns.


403-421: getChainIDFromOpts: LGTM

Flag-first, fallback to client.toml from home is reasonable.

warden/app/app.go (1)

716-736: Ensure correct BankKeeper type for NewAvailableStaticPrecompiles

The third parameter of NewAvailableStaticPrecompiles in warden/app/precompiles.go is declared as

func NewAvailableStaticPrecompiles(
    stakingKeeper stakingkeeper.Keeper,
    distributionKeeper distributionkeeper.Keeper,
    bankKeeper    cmn.BankKeeper,
    // …
)

Please confirm that app.PreciseBankKeeper (passed on lines 716–736 of warden/app/app.go) satisfies the cmn.BankKeeper interface. If it does not, replace it with app.BankKeeper:

   app.EVMKeeper.WithStaticPrecompiles(
     NewAvailableStaticPrecompiles(
       *app.StakingKeeper,
       app.DistrKeeper,
-      app.PreciseBankKeeper,
+      app.BankKeeper,
       app.Erc20Keeper,
       app.TransferKeeper,
       app.IBCKeeper.ChannelKeeper,
       app.EVMKeeper,
       app.GovKeeper,
       app.SlashingKeeper,
       app.WardenKeeper,
       app.ActKeeper,
       app.OracleKeeper,
       app.AsyncKeeper,
       app.SchedKeeper,
       app.AppCodec(),
     ),
   )
justfile (1)

27-27: Good call enabling strict bash modes

Adding set -euxo pipefail will surface failures early, including in pipelines. Solid improvement for determinism in CI and local runs.

Copy link
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
warden/x/warden/module/simulation.go (1)

25-28: Fix compile error: unused variable 'accs'.

'accs' is declared and populated but never used; this will fail to compile.

Apply this diff to remove it:

-	accs := make([]string, len(simState.Accounts))
-	for i, acc := range simState.Accounts {
-		accs[i] = acc.Address.String()
-	}
warden/app/config.go (1)

10-17: Global sealed prevents correct EVM config across multiple App instances; guard against chain-ID mismatch

NewRootCmd spins a temporary App before the real node. With a package-level sealed, the real App may silently skip setupEVM and inherit the temp App’s chain config. At minimum, return an error if a different evmChainID is passed after sealing.

Apply:

@@
-import (
+import (
+  "fmt"
   "cosmossdk.io/math"
   sdk "github.com/cosmos/cosmos-sdk/types"
   "github.com/cosmos/evm/ethereum/eip712"
   evmtypes "github.com/cosmos/evm/x/vm/types"
 )
@@
-var sealed = false
+var sealed = false
+var configuredEVMChainID uint64
@@
 func (app *App) setupEVM(evmChainID uint64) error {
   if sealed {
-    return nil
+    if configuredEVMChainID != evmChainID {
+      return fmt.Errorf("EVM already configured with chain ID %d; requested %d", configuredEVMChainID, evmChainID)
+    }
+    return nil
   }
@@
   if err := evmtypes.NewEVMConfigurator().
     WithChainConfig(ethCfg).
     WithEVMCoinInfo(coinInfo).
     Configure(); err != nil {
     return err
   }
 
-  sealed = true
+  configuredEVMChainID = evmChainID
+  sealed = true

Also applies to: 19-25

warden/app/export.go (1)

61-71: Replace panic/log.Fatal with error returns in export paths

Export code should not terminate the process. Convert panics/log.Fatal to returned errors.

@@
-    _, err := sdk.ValAddressFromBech32(addr)
-    if err != nil {
-      log.Fatal(err)
-    }
+    if _, err := sdk.ValAddressFromBech32(addr); err != nil {
+      return fmt.Errorf("invalid validator address %q: %w", addr, err)
+    }
@@
-    valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
-    if err != nil {
-      panic(err)
-    }
+    valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
+    if err != nil {
+      return fmt.Errorf("invalid validator address %q: %w", delegation.ValidatorAddress, err)
+    }
@@
-    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
-      // never called as BeforeDelegationCreated always returns nil
-      panic(fmt.Errorf("error while incrementing period: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("error while incrementing period: %w", err)
+    }
@@
-    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
-      // never called as AfterDelegationModified always returns nil
-      panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("error while creating a new delegation period record: %w", err)
+    }
@@
-  _, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
-  if err != nil {
-    log.Fatal(err)
-  }
+  if _, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx); err != nil {
+    return err
+  }

Also applies to: 89-97, 109-117, 229-233

precompiles/warden/warden.go (1)

105-116: Call balance hooks only for transactions (avoid state changes on queries).

BeforeBalanceChange/AfterBalanceChange are invoked unconditionally, which can run on read-only queries. Guard them with IsTransaction(method).

Apply this diff:

 func (p *Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz []byte, err error) {
-  ctx, stateDB, method, initialGas, args, err := p.RunSetup(evm, contract, readOnly, p.IsTransaction)
+  ctx, stateDB, method, initialGas, args, err := p.RunSetup(evm, contract, readOnly, p.IsTransaction)
   if err != nil {
     return nil, err
   }
-
-  p.GetBalanceHandler().BeforeBalanceChange(ctx)
+  isTx := p.IsTransaction(method)
+  if isTx {
+    p.GetBalanceHandler().BeforeBalanceChange(ctx)
+  }
@@
-  if err = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB); err != nil {
-    return nil, err
-  }
+  if isTx {
+    if err = p.GetBalanceHandler().AfterBalanceChange(ctx, stateDB); err != nil {
+      return nil, err
+    }
+  }

Also applies to: 111-112, 188-193

♻️ Duplicate comments (4)
warden/app/export.go (2)

130-156: IterateValidators: closure errors are lost; capture and return iterErr

Errors inside the closure stop iteration but are dropped. Capture them and return after IterateValidators.

-// reinitialize all validators
-err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
+// reinitialize all validators
+var iterErr error
+err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
   // donate any unwithdrawn outstanding reward fraction tokens to the community pool
-  scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
-  if err != nil {
-    return true
-  }
+  scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
+  if err != nil { iterErr = err; return true }
 
-  feePool, err := app.DistrKeeper.FeePool.Get(ctx)
-  if err != nil {
-    return true
-  }
+  feePool, err := app.DistrKeeper.FeePool.Get(ctx)
+  if err != nil { iterErr = err; return true }
 
   feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
 
-  err = app.DistrKeeper.FeePool.Set(ctx, feePool)
-  if err != nil {
-    return true
-  }
+  if err = app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil { iterErr = err; return true }
 
-  err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator()))
-  // this lets us stop in case there's an error
-  return err != nil
+  if err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+    iterErr = err
+    return true
+  }
+  return false
 })
 if err != nil {
   return err
 }
+if iterErr != nil {
+  return iterErr
+}

225-228: Iterator Close error is swallowed; return it

Return the Close() error instead of logging and returning nil.

 if err := iter.Close(); err != nil {
   app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
-  return nil
+  return fmt.Errorf("closing validator reverse iterator: %w", err)
 }
warden/app/app.go (2)

912-927: EVMMempool captures AnteHandler before it is set

Mempool is initialized with AnteHandler before app.setAnteHandler runs, so it likely gets nil/old handler.

Move initialization to after setAnteHandler (and setPostHandler). Example:

-  // mempool initialization (EVM priority nonce mempool)
-  if evmtypes.GetChainConfig() != nil {
-    // TODO: Get the actual block gas limit from consensus parameters
-    mempoolConfig := &evmmempool.EVMMempoolConfig{
-      AnteHandler:   app.GetAnteHandler(),
-      BlockGasLimit: 100_000_000,
-    }
-    evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-    app.EVMMempool = evmMempool
-    app.SetMempool(evmMempool)
-    checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
-    app.SetCheckTxHandler(checkTxHandler)
-  }
@@
   app.setAnteHandler(app.txConfig, nodeConfig, app.GetKey(wasmtypes.StoreKey), maxGasWanted)
+  // mempool initialization (EVM priority nonce mempool)
+  if evmtypes.GetChainConfig() != nil {
+    mempoolConfig := &evmmempool.EVMMempoolConfig{
+      AnteHandler:   app.GetAnteHandler(),
+      BlockGasLimit: 100_000_000, // TODO: derive from consensus params
+    }
+    evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
+    app.EVMMempool = evmMempool
+    app.SetMempool(evmMempool)
+    app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
+  }

Also applies to: 973-1000


1046-1058: InitChainer unmarshals genesis into wrong type

req.AppStateBytes is a map of module JSON. Unmarshal into map[string]json.RawMessage, not cosmosevmtypes.GenesisState.

-func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
-  var genesisState cosmosevmtypes.GenesisState
+func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
+  var genesisState map[string]json.RawMessage
   if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
     panic(err)
   }
   if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
     panic(err)
   }
   return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
 }
🧹 Nitpick comments (15)
prophet/registry.go (6)

3-6: Add sort import if we stabilize RegisteredPlugins output.

If you adopt the sorting suggestion below, include sort in the imports.

Apply:

 import (
-	"fmt"
-	"sync"
+	"fmt"
+	"sort"
+	"sync"
 )

8-8: Update stale comment (“tasks plugins”).

Change to “plugins” to match the rename.

-// registry is a global registry of tasks plugins.
+// registry is a global registry of plugins.

13-16: Type name ‘r’ reduces readability.

Consider a clearer type (e.g., registryT or pluginRegistry).


23-24: Duplicate registration handling: keep panic, add nil guard and simplify message.

Also avoid creating an error just to panic; use Sprintf.

-	if _, found := registry.plugins[name]; found {
-		panic(fmt.Errorf("plugin %s registered twice", name))
-	}
+	if task == nil {
+		panic(fmt.Sprintf("plugin %q is nil", name))
+	}
+	if _, found := registry.plugins[name]; found {
+		panic(fmt.Sprintf("plugin %q registered twice", name))
+	}

41-46: Make RegisteredPlugins deterministic (sort names).

Map iteration order is random; sorting removes flakiness in tests/CLI.

-	plugins := make([]string, 0, len(registry.plugins))
+	plugins := make([]string, 0, len(registry.plugins))
 	for name := range registry.plugins {
 		plugins = append(plugins, name)
 	}
 
+	sort.Strings(plugins)
 	return plugins

Remember to add the sort import (see earlier diff).


30-35: Consider updating getPlugin to return a presence flag

To avoid callers mistaking a legitimately registered nil plugin for “not found,” change the signature of getPlugin in prophet/registry.go to return (Plugin, bool), and update its two call sites accordingly:

• In prophet/registry.go

-func getPlugin(name string) Plugin {
+func getPlugin(name string) (Plugin, bool) {
     registry.rw.RLock()
     defer registry.rw.RUnlock()

-    return registry.plugins[name]
+    p, ok := registry.plugins[name]
+    return p, ok
 }

• In prophet/plugins.go, at the two call sites (around lines 30–31 and 66–67):

-    s := getPlugin(f.Plugin)
-    if s == nil {
+    s, ok := getPlugin(f.Plugin)
+    if !ok {
         // handle missing plugin
     }

Please update both call sites so they properly check the ok flag rather than relying on s == nil.

warden/x/warden/module/simulation.go (3)

3-13: Remove leftover scaffolding imports and the sentinel var block.

These imports and the "avoid unused import" block are no longer needed; trimming them reduces noise and avoids accidental dependencies.

 import (
-	"math/rand"
-
-	sdk "github.com/cosmos/cosmos-sdk/types"
 	"github.com/cosmos/cosmos-sdk/types/module"
 	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
-	"github.com/cosmos/cosmos-sdk/x/simulation"
-
-	wardensimulation "github.com/warden-protocol/wardenprotocol/warden/x/warden/simulation"
 	types "github.com/warden-protocol/wardenprotocol/warden/x/warden/types/v1beta3"
 )
 
-// avoid unused import issue.
-var (
-	_ = wardensimulation.FindAccount
-	_ = rand.Rand{}
-	_ = sdk.AccAddress{}
-	_ = simulation.MsgEntryKind
-)

Also applies to: 15-21


45-49: Return nil instead of allocating an empty slice.

No operations are registered; returning nil avoids a needless allocation and matches common SDK style.

 func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
-	operations := make([]simtypes.WeightedOperation, 0)
-
-	return operations
+	return nil
 }

51-54: Prefer nil slice for consistency with ProposalContents.

Keep both governance helpers consistent and avoid an empty-slice allocation.

 func (am AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
-	return []simtypes.WeightedProposalMsg{}
+	return nil
 }
warden/app/config.go (1)

24-35: Confirm eip712 encoding reconfiguration story

setupEVM configures eip712 with the passed chain ID. If the CLI later derives a different evmChainID (from flags/home), it must not be silently ignored. The above guard enforces this; alternatively, consider making sealing per-App (see app.go suggestion).

warden/app/export.go (1)

75-81: Handle reward withdrawal errors explicitly (optional)

Ignore-result withdrawals can mask state issues. Consider propagating errors.

-  _, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator()))
+  if _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+    return fmt.Errorf("withdraw validator commission: %w", err)
+  }
@@
-  _, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
+  if _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr); err != nil {
+    return fmt.Errorf("withdraw delegation rewards: %w", err)
+  }

Also applies to: 95-99

cmd/wardend/cmd/root.go (1)

157-160: Duplicate client config read (nit)

initClientCtx is already read from client config in PersistentPreRunE. This extra read can be dropped unless needed for AutoCLI side-effects.

warden/app/app.go (2)

183-206: Make EVM encoding seal per-App (optional)

To fully avoid cross-App leakage from tempApp, consider moving the seal state into App (e.g., fields evmEncodingSealed, evmEncodingChainID) and have setupEVM use those instead of package-level vars. This makes configuration robust under multiple App instances in one process.

Example field additions:

 type App struct {
   *baseapp.BaseApp
   ...
+  // EVM encoding state (per-App)
+  evmEncodingSealed  bool
+  evmEncodingChainID uint64
 }

And adjust setupEVM to read/write these fields.


915-919: Derive BlockGasLimit from consensus params (optional)

Hardcoding 100_000_000 risks drift from network config. Read from app.GetConsensusParams(ctx) or server opts and plumb it here.

precompiles/warden/warden.go (1)

195-205: Outdated doc block.

The “Available warden transactions are: -” comment is stale; either enumerate or remove.

Apply this diff:

-// Available warden transactions are:
-//
-//	-
+// Transactions: AddKeychainAdmin, AddKeychainWriter, FulfilKeyRequest, RejectKeyRequest,
+// FulfilSignRequest, RejectSignRequest, NewKeychain, NewSpace, RemoveKeychainAdmin,
+// UpdateKeychain, AddSpaceOwner, RemoveSpaceOwner, NewKeyRequest, NewSignRequest,
+// UpdateKey, UpdateSpace.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7ecd4da and 6d237cc.

⛔ Files ignored due to path filters (64)
  • go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (71)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (2 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (1 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (2 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (31)
  • warden/app/sim_bench_test.go
  • warden/x/warden/types/v1beta3/genesis.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/x/warden/module/autocli.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/async/types/v1beta1/genesis.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/sched/module/genesis_test.go
  • warden/x/async/module/genesis.go
  • warden/x/act/module/genesis_test.go
  • warden/testutil/network/network.go
  • warden/x/warden/module/genesis.go
  • warden/x/sched/module/genesis.go
  • warden/x/act/module/autocli.go
  • warden/x/act/types/v1beta1/genesis.go
  • warden/x/async/module/genesis_test.go
  • warden/app/legacy.go
  • warden/x/sched/types/v1beta1/genesis.go
  • warden/testutil/nullify/nullify.go
  • warden/testutil/sample/sample.go
  • precompiles/slinky/slinky.go
  • warden/x/sched/module/autocli.go
  • warden/x/warden/module/genesis_test.go
  • warden/app/app_config.go
  • cmd/wardend/cmd/wait.go
  • warden/app/sim_test.go
  • cmd/wardend/cmd/commands.go
  • warden/x/act/module/genesis.go
  • warden/x/act/types/v1beta1/codec.go
  • cmd/wardend/cmd/config.go
  • warden/app/ante.go
🚧 Files skipped from review as they are similar to previous changes (31)
  • warden/app/upgrades.go
  • precompiles/sched/sched.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • warden/app/ante/options.go
  • warden/x/async/module/simulation.go
  • cmd/wardend/config/wardend_config.go
  • tests/framework/exec/warden_eth.go
  • CHANGELOG.md
  • tests/framework/snapshot/snapshots.go
  • cmd/wardend/main.go
  • warden/x/sched/types/v1beta1/genesis_test.go
  • cmd/wardend/config/chain_id.go
  • warden/x/async/types/v1beta1/keys.go
  • warden/app/ante/cosmos.go
  • precompiles/act/act.go
  • warden/app/oracle.go
  • warden/app/ante/evm_handler.go
  • warden/x/sched/keeper/abci.go
  • cmd/wardend/cmd/testnet.go
  • cmd/wardend/config/config.go
  • warden/x/sched/module/simulation.go
  • warden/x/warden/types/v1beta3/genesis_test.go
  • warden/app/ante/sched_handler.go
  • warden/app/ante/ante.go
  • warden/app/vemanager/vemanager.go
  • precompiles/async/async.go
  • warden/app/precompiles.go
  • warden/x/act/module/simulation.go
  • justfile
  • go.mod
  • localnet.just
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-10-16T16:01:11.241Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-10-16T16:01:11.241Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
📚 Learning: 2024-11-02T10:21:03.096Z
Learnt from: backsapc
PR: warden-protocol/wardenprotocol#975
File: warden/app/app.go:562-562
Timestamp: 2024-11-02T10:21:03.096Z
Learning: In `warden/app/app.go`, suggestions to handle errors from `ParamsKeeper.GetSubspace()` may be considered out of scope.

Applied to files:

  • warden/app/app.go
📚 Learning: 2025-02-06T08:48:57.285Z
Learnt from: mn13
PR: warden-protocol/wardenprotocol#1216
File: warden/x/async/keeper/abci.go:212-216
Timestamp: 2025-02-06T08:48:57.285Z
Learning: In the collections package from Cosmos SDK, calling Keys() on an iterator fully consumes and closes the iterator, making an explicit Close() call unnecessary.

Applied to files:

  • warden/app/export.go
🧬 Code graph analysis (7)
cmd/wardend/cmd/root.go (4)
warden/app/app.go (2)
  • NewApp (256-1023)
  • App (183-254)
cmd/wardend/config/wardend_config.go (2)
  • MustGetDefaultNodeHome (34-41)
  • InitAppConfig (122-186)
cmd/wardend/cmd/testnet.go (1)
  • NewTestnetCmd (111-124)
cmd/wardend/config/chain_id.go (1)
  • GetChainIDFromHome (12-29)
warden/app/config.go (1)
warden/app/app.go (1)
  • App (183-254)
precompiles/warden/warden.go (4)
precompiles/act/act.go (3)
  • Precompile (31-37)
  • LoadABI (41-43)
  • NewPrecompile (45-70)
precompiles/async/async.go (3)
  • Precompile (31-37)
  • LoadABI (41-43)
  • NewPrecompile (45-70)
precompiles/json/json.go (3)
  • Precompile (29-33)
  • LoadABI (37-39)
  • NewPrecompile (41-59)
precompiles/sched/sched.go (3)
  • Precompile (31-38)
  • LoadABI (42-44)
  • NewPrecompile (46-73)
prophet/registry.go (1)
prophet/plugins.go (1)
  • Plugin (12-19)
precompiles/precompiles.go (6)
warden/x/async/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (31-35)
warden/x/sched/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (18-22)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
warden/app/app.go (8)
warden/x/act/keeper/keeper.go (2)
  • Keeper (21-38)
  • NewKeeper (48-91)
warden/x/async/keeper/keeper.go (2)
  • Keeper (34-61)
  • NewKeeper (79-145)
warden/x/warden/keeper/keeper.go (2)
  • Keeper (18-45)
  • NewKeeper (62-122)
warden/x/sched/keeper/keeper.go (2)
  • Keeper (22-34)
  • NewKeeper (44-76)
prophet/prophet.go (2)
  • P (22-31)
  • New (34-51)
warden/app/precompiles.go (1)
  • NewAvailableStaticPrecompiles (82-211)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
warden/app/ante/ante.go (1)
  • NewAnteHandler (17-58)
warden/app/export.go (1)
warden/app/app.go (1)
  • App (183-254)
⏰ 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). (9)
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (10)
prophet/registry.go (2)

10-11: Rename tasks → plugins — LGTM.

Consistent with file intent; initialization is correct.


27-28: Write under Lock — LGTM.

Safe write to the map under the mutex.

precompiles/json/json.go (1)

87-87: LGTM: stateDB intentionally unused in JSON precompile Run.

JSON precompile is query-only (Build/Parse), so ignoring stateDB and dropping balance hooks is appropriate.

precompiles/warden/warden.go (3)

35-36: Constructor refactor looks good; BankKeeper wiring is correct.

Embedding evmcmn.Precompile, switching LoadABI/HandleGasError to evmcmn, and calling SetBalanceHandler(bankKeeper) are consistent with the new pattern.

Also applies to: 47-48, 50-56, 62-67, 74-76


115-116: LGTM: switched to evmcmn.HandleGasError.

Matches the dependency refactor and centralizes gas error handling.


118-176: Mixed use of evm.Origin vs contract.Caller() is intentional and consistent across precompiles

All methods in precompiles/warden/warden.go use only evm.Origin except the space- and request-related transactions, which correctly take both evm.Origin and contract.Caller():

  • AddSpaceOwnerMethod, RemoveSpaceOwnerMethod, NewKeyRequestMethod, NewSignRequestMethod, UpdateKeyMethod, UpdateSpaceMethod

This mirrors the pattern in other precompiles (e.g., VoteForActionMethod in precompiles/act/act.go), so no changes are needed.

precompiles/precompiles.go (4)

3-8: LGTM: import evmcmn solely for BankKeeper.

Keeps types explicit without leaking aliases elsewhere.


48-53: LGTM: BankKeeper plumbed into act/warden/async/sched constructors.

Consistent with SetBalanceHandler in each precompile.

Also applies to: 65-70, 101-106, 121-121


114-120: Intentional: JSON precompile remains bank-agnostic.

It’s query-only; no balance handler needed. Confirm no tx methods will be added here without revisiting this.


35-44: All call sites updated with bankKeeper

I’ve verified that the only invocation of NewWardenPrecompiles (in warden/app/precompiles.go around line 188) now passes bankKeeper as its first parameter. No other calls exist in the codebase, so the signature change has been fully propagated.

Copy link
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
warden/app/export.go (1)

61-71: Replace panic/log.Fatal with error returns in prepForZeroHeightGenesis

This function already returns error; panicking or exiting the process is hostile to callers and tooling.

Apply:

@@
-  if err != nil {
-    log.Fatal(err)
-  }
+  if err != nil {
+    return fmt.Errorf("invalid jailed address %q: %w", addr, err)
+  }
@@
-    panic(err)
+    return fmt.Errorf("invalid validator address %q: %w", delegation.ValidatorAddress, err)
@@
-    panic(err)
+    return fmt.Errorf("invalid validator address %q: %w", del.ValidatorAddress, err)
@@
-    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
-      // never called as BeforeDelegationCreated always returns nil
-      panic(fmt.Errorf("error while incrementing period: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("incrementing period: %w", err)
+    }
@@
-    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
-      // never called as AfterDelegationModified always returns nil
-      panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
-    }
+    if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
+      return fmt.Errorf("creating new delegation period record: %w", err)
+    }
@@
-  if err != nil {
-    log.Fatal(err)
-  }
+  if err != nil {
+    return fmt.Errorf("apply validator set updates: %w", err)
+  }

Also applies to: 90-117, 230-233

♻️ Duplicate comments (9)
justfile (1)

33-35: Avoid checksum drift: verify checksums match the resolved wasmvm_version (or pin both together)

wasmvm_version is dynamic while checksums are hard-coded; they can diverge and break release images (used in lines 53–55 and 74–76). This was flagged earlier; please verify and gate CI on it.

Run from repo root:

#!/usr/bin/env bash
set -euo pipefail

# Extract expected checksums from justfile
EXPECTED_AMD64="$(awk -F"'" '/wasmvm_amd64_checksum/ {print $2; exit}' justfile)"
EXPECTED_ARM64="$(awk -F"'" '/wasmvm_arm64_checksum/ {print $2; exit}' justfile)"

# Resolve wasmvm version (vX.Y.Z) via go, fallback to go.mod
if command -v go >/dev/null 2>&1; then
  VER="$(go list -m -f '{{ .Version }}' github.com/CosmWasm/wasmvm/v3)"
else
  VER="$(awk '/github.com\/CosmWasm\/wasmvm\/v3/ {print $2; exit}' go.mod)"
fi
[[ -n "${VER:-}" ]]

tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT

curl -fsSL "https://github.com/CosmWasm/wasmvm/releases/download/${VER}/libwasmvm_muslc.x86_64.a" -o "${tmpdir}/libwasmvm_muslc.x86_64.a"
curl -fsSL "https://github.com/CosmWasm/wasmvm/releases/download/${VER}/libwasmvm_muslc.aarch64.a" -o "${tmpdir}/libwasmvm_muslc.aarch64.a"

AMD64_ACTUAL="$(sha256sum "${tmpdir}/libwasmvm_muslc.x86_64.a" | awk '{print $1}')"
ARM64_ACTUAL="$(sha256sum "${tmpdir}/libwasmvm_muslc.aarch64.a" | awk '{print $1}')"

echo "Resolved wasmvm version: ${VER}"
echo "AMD64 expected: ${EXPECTED_AMD64}"
echo "AMD64 actual  : ${AMD64_ACTUAL}"
echo "ARM64 expected: ${EXPECTED_ARM64}"
echo "ARM64 actual  : ${ARM64_ACTUAL}"

[[ "${AMD64_ACTUAL}" == "${EXPECTED_AMD64}" && "${ARM64_ACTUAL}" == "${EXPECTED_ARM64}" ]] || { echo "❌ Checksum verification FAILED"; exit 1; }
echo "✔️ Checksum verification PASSED"

Optional hardening if you want local builds to work without Go installed:

-wasmvm_version := `go list -m -f '{{ .Version }}' github.com/CosmWasm/wasmvm/v3`
+wasmvm_version := `sh -c 'go list -m -f "{{ .Version }}" github.com/CosmWasm/wasmvm/v3 2>/dev/null || awk "/github.com\\/CosmWasm\\/wasmvm\\/v3/ { print \\$2; exit }" go.mod'`
warden/app/export.go (2)

130-156: Propagate closure errors from IterateValidators; they’re currently dropped

Errors inside the iterator closure only stop iteration (return true) and never reach the caller. Capture them in an outer iterErr and return after iteration.

Apply:

@@
- // reinitialize all validators
- err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
+ // reinitialize all validators
+ var iterErr error
+ err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
@@
-   scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
-   if err != nil {
-     return true
-   }
+   scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
+   if err != nil { iterErr = err; return true }
@@
-   feePool, err := app.DistrKeeper.FeePool.Get(ctx)
-   if err != nil {
-     return true
-   }
+   feePool, err := app.DistrKeeper.FeePool.Get(ctx)
+   if err != nil { iterErr = err; return true }
@@
-   err = app.DistrKeeper.FeePool.Set(ctx, feePool)
-   if err != nil {
-     return true
-   }
+   if err = app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil { iterErr = err; return true }
@@
-   err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator()))
-   // this lets us stop in case there's an error
-   return err != nil
+   if err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+     iterErr = err
+     return true
+   }
+   return false
 })
 if err != nil {
   return err
 }
+if iterErr != nil {
+  return iterErr
+}

225-228: Do not swallow iterator Close error; return it

Logging and returning nil hides real failures when closing the reverse iterator.

Apply:

 if err := iter.Close(); err != nil {
   app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
-  return nil
+  return fmt.Errorf("closing validator reverse iterator: %w", err)
 }
cmd/wardend/cmd/root.go (1)

61-71: Build tempApp with real EVM chain ID and close it to avoid config mismatches/leaks

Hard-coding EVMChainID here and not closing tempApp risks EIP-712 mismatches and sealed-global conflicts; also leaks resources.

Apply:

-noOpEvmAppOptions := func(_ uint64) error { return nil }
-tempApp := app.NewApp(
+evmForTemp := wardendconfig.EVMChainID
+if home := wardendconfig.MustGetDefaultNodeHome(); home != "" {
+  if cid, err := wardendconfig.GetChainIDFromHome(home); err == nil {
+    if parsed, err := parseEVMChainID(cid); err == nil {
+      evmForTemp = parsed
+    }
+  }
+}
+tempApp := app.NewApp(
   log.NewNopLogger(),
   dbm.NewMemDB(),
   nil,
   true,
   simtestutil.NewAppOptionsWithFlagHome(temp),
-  wardendconfig.EVMChainID,
-  noOpEvmAppOptions,
+  evmForTemp,
+  wardendconfig.EvmAppOptions,
 )
+defer tempApp.Close()
warden/app/app.go (3)

914-928: EVMMempool captures a nil AnteHandler due to ordering

You construct the EVM mempool before calling setAnteHandler, so AnteHandler in the mempool config is nil. This bypasses ante checks in CheckTx.

Apply (remove here; re-add after setAnteHandler):

-// mempool initialization (EVM priority nonce mempool)
-if evmtypes.GetChainConfig() != nil {
-  // TODO: Get the actual block gas limit from consensus parameters
-  mempoolConfig := &evmmempool.EVMMempoolConfig{
-    AnteHandler:   app.GetAnteHandler(),
-    BlockGasLimit: 100_000_000,
-  }
-
-  evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-  app.EVMMempool = evmMempool
-
-  app.SetMempool(evmMempool)
-  checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
-  app.SetCheckTxHandler(checkTxHandler)
-}

1049-1060: InitChainer unmarshals into the wrong type; breaks genesis initialization

req.AppStateBytes is the whole genesis map. Unmarshal into map[string]json.RawMessage and pass that to InitGenesis.

Apply:

 func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
-  var genesisState cosmosevmtypes.GenesisState
+  var genesisState map[string]json.RawMessage
   if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
     panic(err)
   }
@@
-  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
+  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
 }

981-1012: Initialize EVMMempool after ante/post handlers are set

Recreate the mempool after SetAnteHandler/SetPostHandler so it captures the final handlers.

Apply:

@@
   app.setPostHandler()
+
+  // mempool initialization (EVM priority nonce mempool)
+  if evmtypes.GetChainConfig() != nil {
+    // TODO: derive from consensus params
+    mempoolConfig := &evmmempool.EVMMempoolConfig{
+      AnteHandler:   app.GetAnteHandler(),
+      BlockGasLimit: 100_000_000,
+    }
+    evmMempool := evmmempool.NewExperimentalEVMMempool(
+      app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig,
+    )
+    app.EVMMempool = evmMempool
+    app.SetMempool(evmMempool)
+    app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
+  }
cmd/wardend/cmd/testnet.go (2)

558-569: Fix: invalid loop and last-octet overflow in calculateIP.

The current loop won’t compile and may wrap the last octet. Do a bounded addition.

 func calculateIP(ip string, i int) (string, error) {
 	ipv4 := net.ParseIP(ip).To4()
 	if ipv4 == nil {
 		return "", fmt.Errorf("%v: non ipv4 address", ip)
 	}
 
-	for range i {
-		ipv4[3]++
-	}
-
-	return ipv4.String(), nil
+	octet := int(ipv4[3]) + i
+	if octet < 0 || octet > 255 {
+		return "", fmt.Errorf("IP address overflow: starting IP %s with offset %d exceeds last-octet range 0-255", ip, i)
+	}
+	ipv4[3] = byte(octet)
+	return ipv4.String(), nil
 }

236-243: Add bounds check for validator count (fail fast).

Prevents accidental resource blowups and aligns with earlier feedback.

 	if args.chainID == "" {
 		args.chainID = "local-4221"
 	}
+
+	// sanity-check number of validators
+	if args.numValidators < 1 || args.numValidators > 100 {
+		return fmt.Errorf("invalid --%s: %d (must be between 1 and 100)", flagNumValidators, args.numValidators)
+	}
🧹 Nitpick comments (24)
justfile (1)

27-29: Harden deploy-contract: use raw jq output and tolerate SDK event key changes

  • Add jq -r to avoid quoted values in CODE_ID/ADDR.
  • Make address extraction resilient to either _contract_address or contract_address.
-    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas 10000000 --fees 1award | wardend q wait-tx -o json | jq '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value | tonumber')
-    ADDR=$(wardend tx wasm instantiate $CODE_ID '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees 1award -y | wardend q wait-tx -o json | jq '.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address") | .value')
+    CODE_ID=$(wardend tx wasm store {{contract}} --from {{from}} -y --gas 10000000 --fees 1award \
+      | wardend q wait-tx -o json \
+      | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value | tonumber')
+    ADDR=$(wardend tx wasm instantiate $CODE_ID '{}' --from {{from}} --label "{{if label == "" { "default" } else { label } }}" --no-admin --fees 1award -y \
+      | wardend q wait-tx -o json \
+      | jq -r '.events[] | select(.type == "instantiate") | .attributes[] | select(.key == "_contract_address" or .key == "contract_address") | .value' | head -n1)

Optional: parameterize gas/fees so the recipe works across chains and fee regimes:

- deploy-contract contract from="shulgin" label="":
+ deploy-contract contract from="shulgin" label="" gas="10000000" fees="1award":

and then replace the two occurrences of --gas 10000000 --fees 1award with --gas {{gas}} --fees {{fees}}.

cmd/wardend/config/evm_app_options.go (2)

16-26: Use sync.Once instead of a package-level sealed bool.

Avoid races if init is called twice (tests/CLI).

Apply:

- var sealed bool
+ // guarded one-time EVM options init
+ var evmAppOptionsOnce sync.Once
-func EvmAppOptions(evmChainID uint64) error {
-  if sealed {
-    return nil
-  }
-
-  sealed = true
+func EvmAppOptions(evmChainID uint64) error {
+  var err error
+  evmAppOptionsOnce.Do(func() {
+    // set the denom info for the chain
+    if e := setBaseDenom(coinInfo); e != nil {
+      err = e
+      return
+    }
+
+    ethCfg := evmtypes.DefaultChainConfig(evmChainID)
+    if e := evmtypes.NewEVMConfigurator().
+      WithChainConfig(ethCfg).
+      WithEVMCoinInfo(coinInfo).
+      Configure(); e != nil {
+      err = e
+      return
+    }
+  })
+  return err
-  // set the denom info for the chain
-  if err := setBaseDenom(coinInfo); err != nil {
-    return err
-  }
-
-  ethCfg := evmtypes.DefaultChainConfig(evmChainID)
-  if err := evmtypes.NewEVMConfigurator().
-    WithChainConfig(ethCfg).
-    WithEVMCoinInfo(coinInfo).
-    Configure(); err != nil {
-    return err
-  }
-
-  return nil
 }

Additional change outside this hunk:

  • add import: sync

50-52: Comment is misleading.

It’s not “overwrite the base denom”; we’re registering scale factors for two denoms. Suggest clarifying or remove.

warden/app/precompiles.go (1)

97-99: Avoid shadowing the imported codec package with a param named codec.

Rename parameter to cdc for clarity.

Apply:

-func NewAvailableStaticPrecompiles(
+func NewAvailableStaticPrecompiles(
   ...
-  codec codec.Codec,
+  cdc codec.Codec,
   opts ...Option,
 ) map[common.Address]vm.PrecompiledContract {
-  govPrecompile, err := govprecompile.NewPrecompile(
+  govPrecompile, err := govprecompile.NewPrecompile(
     govkeeper.NewMsgServerImpl(&govKeeper),
     govkeeper.NewQueryServer(&govKeeper),
     bankKeeper,
-    codec,
+    cdc,
     options.AddressCodec,
   )

Also applies to: 154-160

precompiles/precompiles.go (1)

35-36: Consider updating the function comment to mention BankKeeper injection.

Minor doc touch-up for future readers.

warden/app/export.go (2)

164-166: Avoid redeclaring iterErr; reuse the outer variable

Once you introduce iterErr above, remove this duplicate declaration to prevent shadowing.

Apply:

-var iterErr error

75-81: Ignored reward-withdrawal errors; at least surface or aggregate them

Silent failures during withdrawals may leave distribution state inconsistent. Consider capturing and returning the first error (or aggregating).

Example:

-_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator()))
+if _, err := app.DistrKeeper.WithdrawValidatorCommission(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+  return fmt.Errorf("withdraw validator commission %s: %w", val.GetOperator(), err)
+}
@@
-_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
+if _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr); err != nil {
+  return fmt.Errorf("withdraw delegation rewards %s->%s: %w", delAddr, valAddr, err)
+}

Also applies to: 95-99

cmd/wardend/cmd/root.go (2)

153-155: Handle error from ReadFromClientConfig instead of discarding it

Discarding this error can mask misconfigurations that later cause panics.

Apply:

-initClientCtx, _ = clientcfg.ReadFromClientConfig(initClientCtx)
+if cctx, err := clientcfg.ReadFromClientConfig(initClientCtx); err == nil {
+  initClientCtx = cctx
+}

160-169: Avoid panics on ChainID parsing/EVM options; log and continue

Panicking in NewRootCmd aborts the binary during CLI assembly. Prefer graceful degradation.

Apply:

 if initClientCtx.ChainID != "" {
-  evmChainID, err := parseEVMChainID(initClientCtx.ChainID)
-  if err != nil {
-    panic(err)
-  }
-
-  if err := wardendconfig.EvmAppOptions(evmChainID); err != nil {
-    panic(err)
-  }
+  if evmChainID, err := parseEVMChainID(initClientCtx.ChainID); err == nil {
+    _ = wardendconfig.EvmAppOptions(evmChainID)
+  } else {
+    fmt.Fprintf(os.Stderr, "warning: failed to configure EVM options for ChainID %q: %v\n", initClientCtx.ChainID, err)
+  }
 }
prophet/registry.go (5)

3-6: Deterministic plugin listing: import sort to enable ordered output.
If we sort RegisteredPlugins, we’ll need this import.

 import (
 	"fmt"
+	"sort"
 	"sync"
 )

14-15: Nit: clarify type name and consider embedding the mutex.
Renaming r to pluginRegistry (and embedding sync.RWMutex) improves readability.

Example:

type pluginRegistry struct {
  sync.RWMutex
  plugins map[string]Plugin
}

23-24: Nit: panic with formatted string and quote the name.
Avoid panicking with an error value; quote the plugin name for clarity.

-		panic(fmt.Errorf("plugin %s registered twice", name))
+		panic(fmt.Sprintf("plugin %q registered twice", name))

18-28: Rename parameter from task to plugin and fix doc comment.
Aligns naming with the map and public API; avoids mixed “task/plugin” terminology.

-// Register registers a new task plugin with the given unique name.
+// Register registers a new plugin with the given unique name.
-func Register(name string, task Plugin) {
+func Register(name string, plugin Plugin) {
   registry.rw.Lock()
   defer registry.rw.Unlock()

   if _, found := registry.plugins[name]; found {
     panic(fmt.Errorf("plugin %s registered twice", name))
   }

-  registry.plugins[name] = task
+  registry.plugins[name] = plugin
 }

37-47: Return plugin names in deterministic order and avoid holding the lock while sorting.
Stable order helps tests/config diffs; unlock before sort to reduce lock hold time. Add a doc comment for the exported function.

+// RegisteredPlugins returns the names of all registered plugins in lexicographic order.
 func RegisteredPlugins() []string {
-	registry.rw.RLock()
-	defer registry.rw.RUnlock()
-
-	plugins := make([]string, 0, len(registry.plugins))
-	for name := range registry.plugins {
-		plugins = append(plugins, name)
-	}
-
-	return plugins
+	registry.rw.RLock()
+	names := make([]string, 0, len(registry.plugins))
+	for name := range registry.plugins {
+		names = append(names, name)
+	}
+	registry.rw.RUnlock()
+
+	sort.Strings(names)
+	return names
 }

Note: This requires importing "sort" (see earlier comment).

cmd/wardend/cmd/testnet.go (10)

90-105: CLI polish: add -v alias and fix gas price help example.

Small UX/doc wins.

-	cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
+	cmd.Flags().IntP(flagNumValidators, "v", 4, "Number of validators to initialize the testnet with")
@@
-	cmd.Flags().String(server.FlagMinGasPrices, "0.000006"+sdk.DefaultBondDenom, "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
+	cmd.Flags().String(server.FlagMinGasPrices, "0.000006"+sdk.DefaultBondDenom, "Minimum gas prices to accept for transactions; all fees must meet this minimum (e.g. 0.01stake,0.001testtoken)")

131-142: Fix examples: binary name and flag usage.

Docs say “evmd” and “--v”; CLI here is wardend and you added -v/--validator-count.

-Example:
-	evmd testnet init-files --v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2
+Example:
+	wardend testnet init-files -v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2

195-197: Fix examples: command and flag.

-Example:
-	evmd testnet --v 4 --output-dir ./.testnets
+Example:
+	wardend testnet start -v 4 --output-dir ./.testnets

179-179: Correct port in help text (26656, not 46656).

-	cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list [email protected]:46656, [email protected]:46656, ...)")
+	cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list [email protected]:26656, [email protected]:26656, ...)")

605-611: Use filepath.Join and fix “testnests” typo in error.

-	baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID)
+	baseDir := filepath.Join(args.outputDir, networkConfig.ChainID)
 	if _, err := os.Stat(baseDir); !os.IsNotExist(err) {
 		return fmt.Errorf(
-			"testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
+			"testnets directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
 			networkConfig.ChainID, baseDir)
 	}

612-629: Defer cleanup and avoid fmt.Scanln() with no args.

Ensures cleanup even on early return; avoid Scanln pitfalls.

-	testnet, err := network.New(networkLogger, baseDir, networkConfig)
+	testnet, err := network.New(networkLogger, baseDir, networkConfig)
 	if err != nil {
 		return err
 	}
+	defer testnet.Cleanup()
@@
-	cmd.Println("press the Enter Key to terminate")
-
-	if _, err := fmt.Scanln(); err != nil { // wait for Enter Key
-		return err
-	}
-
-	testnet.Cleanup()
+	cmd.Println("press the Enter key to terminate")
+	_, _ = bufio.NewReader(os.Stdin).ReadString('\n')
 
 	return nil

178-178: Optional: default node home to “wardend” for consistency.

Matches the binary name; change only if it won’t break existing workflows.

-	cmd.Flags().String(flagNodeDaemonHome, "evmd", "Home directory of the node's daemon configuration")
+	cmd.Flags().String(flagNodeDaemonHome, "wardend", "Home directory of the node's daemon configuration")

75-75: Unused flag: --use-docker (and associated arg).

Flag is parsed but never used. Wire it up or drop it to avoid confusion.

Also applies to: 181-182, 157-158


632-639: Nit: remove temp dir creation that isn’t used.

The app uses MemDB and no home dir; the temp dir is vestigial.

 func NewTestNetworkFixture() network.TestFixture {
-	dir, err := os.MkdirTemp("", "evm")
-	if err != nil {
-		panic(fmt.Sprintf("failed creating temporary directory: %v", err))
-	}
-	defer os.RemoveAll(dir)
-
 	app := evmd.NewExampleApp(
 		log.NewNopLogger(),
 		dbm.NewMemDB(),
 		nil,

131-141: Doc comment above NewTestnetCmd mentions 3 subcommands; only 2 exist.

Trim or update the comment to reflect current commands.

Also applies to: 195-197

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6d237cc and 12fedf7.

⛔ Files ignored due to path filters (64)
  • go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (73)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (1 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/evm_app_options.go (1 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (0 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/genesis.go (0 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (2 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (33)
  • warden/x/sched/types/v1beta1/genesis.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/async/types/v1beta1/genesis.go
  • cmd/wardend/cmd/wait.go
  • precompiles/slinky/slinky.go
  • warden/x/sched/module/genesis.go
  • warden/x/async/module/genesis.go
  • warden/x/warden/types/v1beta3/genesis.go
  • warden/x/warden/module/genesis.go
  • cmd/wardend/cmd/config.go
  • warden/x/async/module/genesis_test.go
  • warden/x/sched/module/autocli.go
  • warden/x/act/types/v1beta1/genesis.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/testutil/sample/sample.go
  • warden/x/warden/module/genesis_test.go
  • warden/app/genesis.go
  • warden/x/act/module/autocli.go
  • warden/app/sim_test.go
  • warden/testutil/nullify/nullify.go
  • warden/app/config.go
  • warden/app/app_config.go
  • warden/x/sched/module/genesis_test.go
  • warden/app/sim_bench_test.go
  • warden/app/ante.go
  • warden/x/act/module/genesis.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/act/module/genesis_test.go
  • warden/x/warden/module/autocli.go
  • warden/testutil/network/network.go
  • warden/x/act/types/v1beta1/codec.go
  • warden/app/legacy.go
  • cmd/wardend/cmd/commands.go
🚧 Files skipped from review as they are similar to previous changes (29)
  • tests/framework/snapshot/snapshots.go
  • warden/app/ante/cosmos.go
  • CHANGELOG.md
  • cmd/wardend/config/wardend_config.go
  • warden/app/ante/ante.go
  • warden/app/ante/evm_handler.go
  • warden/x/warden/module/simulation.go
  • warden/x/async/types/v1beta1/keys.go
  • cmd/wardend/config/config.go
  • tests/framework/exec/warden_eth.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • warden/x/warden/types/v1beta3/genesis_test.go
  • warden/app/vemanager/vemanager.go
  • precompiles/act/act.go
  • cmd/wardend/main.go
  • cmd/wardend/config/chain_id.go
  • precompiles/async/async.go
  • warden/x/sched/types/v1beta1/genesis_test.go
  • precompiles/sched/sched.go
  • warden/x/sched/module/simulation.go
  • warden/x/act/module/simulation.go
  • precompiles/warden/warden.go
  • warden/app/ante/sched_handler.go
  • warden/app/oracle.go
  • warden/app/ante/options.go
  • warden/x/async/module/simulation.go
  • warden/x/sched/keeper/abci.go
  • go.mod
  • warden/app/upgrades.go
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-06-10T19:20:04.350Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-06-10T19:20:04.350Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
📚 Learning: 2025-02-06T08:48:57.285Z
Learnt from: mn13
PR: warden-protocol/wardenprotocol#1216
File: warden/x/async/keeper/abci.go:212-216
Timestamp: 2025-02-06T08:48:57.285Z
Learning: In the collections package from Cosmos SDK, calling Keys() on an iterator fully consumes and closes the iterator, making an explicit Close() call unnecessary.

Applied to files:

  • warden/app/export.go
🧬 Code graph analysis (8)
cmd/wardend/config/evm_app_options.go (1)
cmd/wardend/config/config.go (1)
  • DisplayDenom (24-24)
cmd/wardend/cmd/testnet.go (2)
cmd/wardend/config/config.go (1)
  • EVMChainID (30-30)
cmd/wardend/config/evm_app_options.go (1)
  • EvmAppOptions (20-41)
prophet/registry.go (1)
prophet/plugins.go (1)
  • Plugin (12-19)
cmd/wardend/cmd/root.go (5)
warden/app/app.go (2)
  • NewApp (257-1025)
  • App (184-255)
cmd/wardend/config/config.go (2)
  • EVMChainID (30-30)
  • BaseDenom (26-26)
cmd/wardend/config/wardend_config.go (2)
  • MustGetDefaultNodeHome (34-41)
  • InitAppConfig (122-186)
cmd/wardend/config/evm_app_options.go (1)
  • EvmAppOptions (20-41)
cmd/wardend/config/chain_id.go (1)
  • GetChainIDFromHome (12-29)
warden/app/export.go (1)
warden/app/app.go (1)
  • App (184-255)
precompiles/precompiles.go (6)
warden/x/async/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (31-35)
warden/x/sched/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (18-22)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
warden/app/app.go (10)
warden/x/act/keeper/keeper.go (2)
  • Keeper (21-38)
  • NewKeeper (48-91)
warden/x/async/keeper/keeper.go (2)
  • Keeper (34-61)
  • NewKeeper (79-145)
warden/x/warden/keeper/keeper.go (2)
  • Keeper (18-45)
  • NewKeeper (62-122)
warden/x/sched/keeper/keeper.go (2)
  • Keeper (22-34)
  • NewKeeper (44-76)
warden/app/oracle.go (1)
  • SlinkyClient (64-74)
cmd/wardend/config/wardend_config.go (2)
  • GetMaccPerms (98-100)
  • BlockedAddresses (69-95)
warden/app/precompiles.go (1)
  • NewAvailableStaticPrecompiles (82-211)
warden/app/genesis.go (4)
  • GenesisState (19-19)
  • NewMintGenesisState (44-48)
  • NewEVMGenesisState (22-27)
  • NewErc20GenesisState (33-39)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
warden/app/ante/ante.go (1)
  • NewAnteHandler (17-58)
warden/app/precompiles.go (4)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
⏰ 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). (8)
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: Analyze (go)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (18)
localnet.just (1)

37-41: Action Required: Generate and Verify genesis.json Parameters

It looks like the genesis.json file wasn’t found at $HOME/.warden/config/genesis.json, so the assertions couldn’t run. Please initialize the localnet to produce the genesis file and then re-verify the key parameters:

  • Run the init command to create the genesis:
    {{bin}} init localnet --chain-id {{chain_id}} --default-denom award > /dev/null
  • Ensure the file exists:
    ls -l $HOME/.warden/config/genesis.json
  • Then assert the patched values:
    #!/usr/bin/env bash
    set -euo pipefail
    GENESIS="$HOME/.warden/config/genesis.json"
    
    jq -r '.chain_id'                          "$GENESIS"
    jq '.app_state.evm.params.evm_denom'       "$GENESIS"
    jq '.app_state.feemarket.params.no_base_fee' "$GENESIS"
    jq '.consensus.params.abci.vote_extensions_enable_height' "$GENESIS"
    
    # Expect:
    # - chain_id == "warden_1337-1"
    # - evm_denom == "award"
    # - no_base_fee == true
    # - vote_extensions_enable_height == "2"
  • Verify that:
    1. chain_id matches "warden_1337-1".
    2. evm_denom is "award".
    3. no_base_fee is true.
    4. vote_extensions_enable_height is "2".

Also applies to the snippets at lines 64–70, 76, and 109—please confirm those blocks against the same checks.

warden/app/precompiles.go (7)

128-134: Potential Keeper copy; prefer pointers for server/querier like other modules.

Distribution uses value receivers in some SDK versions, but copying Keeper structs can be risky. Align with staking/gov by passing pointers unless the API explicitly requires values.

Option A (if APIs accept pointers):

- distributionkeeper.NewMsgServerImpl(distributionKeeper),
- distributionkeeper.NewQuerier(distributionKeeper),
+ distributionkeeper.NewMsgServerImpl(&distributionKeeper),
+ distributionkeeper.NewQuerier(&distributionKeeper),

If the SDK functions require values, leave as-is. Please confirm against the SDK version in go.mod.


100-104: Options pattern LGTM.

Clean, non-breaking configurability for address codecs.


116-123: Staking precompile wiring LGTM.

MsgServer, Querier, bankKeeper and codec injection are correct.


165-171: Slashing precompile wiring LGTM.

Validator/consensus codecs are configurable; good.


188-196: Passing bankKeeper into Warden precompiles aligns with new balance handler.

Good propagation.


3-6: Confirmed Go version is sufficient

  • go.mod specifies go 1.25.0, which is ≥ 1.21 (required for maps.Clone).
    No changes are needed.

49-55: It looks like we still need to confirm that setupSDKConfig() is invoked before any use of defaultOptionals() within your app initialization (i.e., before Precompiles(...) is called). Let’s verify the main function’s call order.

I’ve requested the first 200 lines of cmd/wardend/main.go to ensure:

  • wardendconfig.SetBech32Prefixes(config) and config.Seal() are called early.
  • Precompiles(...) (and thus defaultOptionals()) is invoked only afterward.

Once we confirm that ordering, we can mark this as safe. If prefixes aren’t set first, we’ll need to adjust.

precompiles/json/json.go (1)

87-95: Removed stateDB/balance-change hooks: consistent with BankKeeper-based balance handling.

Run path stays the same; gas error handling preserved. Looks good.

precompiles/precompiles.go (5)

48-52: act precompile wiring LGTM.


65-70: warden precompile wiring LGTM.


101-106: async precompile wiring LGTM.


121-121: sched precompile wiring LGTM.


37-44: All NewWardenPrecompiles call sites already include the new bankKeeper argument

I searched for all invocations of NewWardenPrecompiles and found only one caller in warden/app/precompiles.go, which already passes bankKeeper as its first parameter:

  • warden/app/precompiles.go:188–191
    wardenprecompiles, err := wardenprecompiles.NewWardenPrecompiles(
        bankKeeper,
        wardenKeeper,
        actKeeper,
        …
    )

Since this is the only usage and it’s been updated to match the new signature, no further changes are needed.

warden/app/app.go (1)

375-391: No action needed: err is already declared in this scope

The short‐variable declaration at line 333 (prophetP, err := prophet.New()) brings err into the function’s scope, so it remains visible at line 382 when calling authtx.NewTxConfigWithOptions. There is no risk of an undefined err, and no additional declaration is required.

Likely an incorrect or invalid review comment.

prophet/registry.go (2)

10-10: LGTM: explicit plugins map initialization.
Clear and thread-safe with later locking.


30-35: All getPlugin call sites already handle missing plugins

I’ve verified both usages in prophet/plugins.go:

  • At lines 30–32 and 66–68, the code checks if s == nil and returns an error.

No other call sites were found. No changes are needed.

cmd/wardend/cmd/testnet.go (1)

418-419: Persist full EVM app config using the EVM server config writer.

Using cosmos-sdk’s WriteConfigFile may omit EVM/JSON-RPC sections if the template doesn’t include them. Prefer the EVM package writer.

-		srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg)
+		cosmosevmserverconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg)

Please confirm the exact function name for your pinned cosmos/evm version (or set the EVM config template before writing if required).

Copy link
Contributor

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
warden/x/sched/module/simulation.go (2)

25-28: Fix compile error: remove unused accs in GenerateGenesisState.

accs is written but never read; Go will fail to build with “accs declared and not used”.

Apply:

-    accs := make([]string, len(simState.Accounts))
-    for i, acc := range simState.Accounts {
-        accs[i] = acc.Address.String()
-    }
+    // No account-derived state needed for x/sched genesis.

3-13: Remove leftover scaffolding imports and the “avoid unused import” var block.

These pull in unused deps (rand, sdk/types, x/simulation, sched/simulation) and obscure real dependencies.

Apply:

-import (
-	"math/rand"
-
-	sdk "github.com/cosmos/cosmos-sdk/types"
-	"github.com/cosmos/cosmos-sdk/types/module"
-	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
-	"github.com/cosmos/cosmos-sdk/x/simulation"
-
-	schedsimulation "github.com/warden-protocol/wardenprotocol/warden/x/sched/simulation"
-	types "github.com/warden-protocol/wardenprotocol/warden/x/sched/types/v1beta1"
-)
+import (
+	"github.com/cosmos/cosmos-sdk/types/module"
+	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+
+	types "github.com/warden-protocol/wardenprotocol/warden/x/sched/types/v1beta1"
+)
@@
-// avoid unused import issue.
-var (
-	_ = schedsimulation.FindAccount
-	_ = rand.Rand{}
-	_ = sdk.AccAddress{}
-	_ = simulation.MsgEntryKind
-)
+// (no-op)

Also applies to: 15-21

go.mod (1)

3-3: Fix invalid go directive: use major.minor, not patch.

go.mod requires go 1.25, not 1.25.0. Patch versions are not allowed and will break tooling.

Apply:

-go 1.25.0
+go 1.25
♻️ Duplicate comments (11)
cmd/wardend/config/evm_app_options.go (1)

46-53: Base/display denom registration is reversed (amount scaling bug).

Register base denom with factor 1; register display denom with 10^-decimals. This will mis-scale IBC/CLI amounts otherwise.

 func setBaseDenom(ci evmtypes.EvmCoinInfo) error {
-	if err := sdk.RegisterDenom(ci.DisplayDenom, math.LegacyOneDec()); err != nil {
+	if err := sdk.RegisterDenom(ci.Denom, math.LegacyOneDec()); err != nil {
 		return err
 	}
 
-	// sdk.RegisterDenom will automatically overwrite the base denom when the
-	// new setBaseDenom() are lower than the current base denom's units.
-	return sdk.RegisterDenom(ci.Denom, math.LegacyNewDecWithPrec(1, int64(ci.Decimals)))
+	// Register display denom at the correct precision factor.
+	return sdk.RegisterDenom(ci.DisplayDenom, math.LegacyNewDecWithPrec(1, int64(ci.Decimals)))
 }
justfile (1)

33-35: Checksums likely don’t match resolved wasmvm version; pin or verify.

Dynamic version with hard-coded checksums is brittle. Either pin version alongside checksums or add a verify step in CI.

Option A — pin to the verified version and matching checksums:

-wasmvm_version := `go list -m -f '{{ .Version }}' github.com/CosmWasm/wasmvm/v3`
-wasmvm_amd64_checksum := 'f2fab51ec2b393ffe6912ff31497c6f8a14c04ad2490a1a3a9fa11a37cb4ce33'
-wasmvm_arm64_checksum := 'f82e608707be7b193a78f5a7f7c6163b633a94ca6a0017a7fa3501cc8e9fbff5'
+wasmvm_version := 'v3.0.0'
+wasmvm_amd64_checksum := 'cefe73f0caa5a9eaba3733c639cdf5040c4746a93c20670ba6c9287fe39448ba'
+wasmvm_arm64_checksum := 'a04969b4f931be1d2e2f3f2313a68a20a202693f67559f7aaf1dd97250823aec'

Option B — keep dynamic version but add checksum verification in CI (preferred for drift detection).

#!/usr/bin/env bash
set -euo pipefail
VER="$(go list -m -f '{{ .Version }}' github.com/CosmWasm/wasmvm/v3)"
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
curl -fsSL "https://github.com/CosmWasm/wasmvm/releases/download/${VER}/libwasmvm_muslc.x86_64.a" -o "$tmp/a.x86_64.a"
curl -fsSL "https://github.com/CosmWasm/wasmvm/releases/download/${VER}/libwasmvm_muslc.aarch64.a" -o "$tmp/a.aarch64.a"
a="$(python3 - <<'PY'\nimport hashlib,sys\nprint(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())\nPY "$tmp/a.x86_64.a")"
b="$(python3 - <<'PY'\nimport hashlib,sys\nprint(hashlib.sha256(open(sys.argv[1],'rb').read()).hexdigest())\nPY "$tmp/a.aarch64.a")"
echo "Resolved: ${VER}"; echo "AMD64 ${a}"; echo "ARM64 ${b}"
test "${a}" = {{wasmvm_amd64_checksum}} && test "${b}" = {{wasmvm_arm64_checksum}}
cmd/wardend/cmd/testnet.go (6)

227-239: Validate numValidators early.

Fail fast to avoid resource misuse.

 func initTestnetFiles(
@@
 ) error {
+	if args.numValidators < 1 || args.numValidators > 100 {
+		return fmt.Errorf("number of validators must be between 1 and 100, got %d", args.numValidators)
+	}
 	if args.chainID == "" {
 		args.chainID = "local-4221"
 	}

317-319: Use a dialable loopback in single-machine mode.

0.0.0.0 is not dialable by peers; use 127.0.0.1.

-		if args.singleMachine {
-			ip = "0.0.0.0"
+		if args.singleMachine {
+			ip = "127.0.0.1"

534-540: Also persist CometBFT config.toml per node.

You mutate nodeConfig but never write it; external processes won’t see the changes.

 		// overwrite each validator's genesis file to have a canonical genesis time
 		if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
 			return err
 		}
+		// persist CometBFT config
+		if err := cmtconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), nodeConfig); err != nil {
+			return err
+		}

481-485: Fix compile error: cannot range over int in initGenFiles.

-	for i := range numValidators {
+	for i := 0; i < numValidators; i++ {

501-507: Fix compile error: cannot range over int in collectGenFiles.

-	for i := range numValidators {
+	for i := 0; i < numValidators; i++ {

280-299: Fix compile error: cannot range over int.

Replace with a classic for loop.

-	for i := range args.numValidators {
+	for i := 0; i < args.numValidators; i++ {
cmd/wardend/cmd/root.go (1)

56-70: Build tempApp with the real EVM chain ID and close it to avoid config mismatches and resource leaks

Temp app is created with a constant chain ID and never closed. This can cause EIP‑712/Textual mismatches and lingering sealed globals/resources across CLI invocations. Derive the chain ID from home (fallback to default) and defer Close().

   temp := tempDir()
   // cleanup temp dir after we are done with the tempApp, so we don't leave behind a
   // new temporary directory for every invocation. See https://github.com/CosmWasm/wasmd/issues/2017
   defer os.RemoveAll(temp)

-  noOpEvmAppOptions := func(_ uint64) error { return nil }
-  tempApp := app.NewApp(
+  noOpEvmAppOptions := func(_ uint64) error { return nil }
+  // try to match CLI/home chainID for correct EIP-712 config
+  evmForTemp := wardendconfig.EVMChainID
+  if home := wardendconfig.MustGetDefaultNodeHome(); home != "" {
+    if cid, err := wardendconfig.GetChainIDFromHome(home); err == nil {
+      if parsed, err := parseEVMChainID(cid); err == nil {
+        evmForTemp = parsed
+      }
+    }
+  }
+  tempApp := app.NewApp(
     log.NewNopLogger(),
     dbm.NewMemDB(),
     nil,
     true,
     simtestutil.NewAppOptionsWithFlagHome(temp),
-    wardendconfig.EVMChainID,
+    evmForTemp,
     noOpEvmAppOptions,
   )
+  defer tempApp.Close()
warden/app/app.go (2)

914-928: EVMMempool captures nil/old AnteHandler; initialize after SetAnteHandler

Mempool is built before ante/post handlers are set, so its AnteHandler is nil/incorrect.

-  // mempool initialization (EVM priority nonce mempool)
-  if evmtypes.GetChainConfig() != nil {
-    // TODO: Get the actual block gas limit from consensus parameters
-    mempoolConfig := &evmmempool.EVMMempoolConfig{
-      AnteHandler:   app.GetAnteHandler(),
-      BlockGasLimit: 100_000_000,
-    }
-
-    evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-    app.EVMMempool = evmMempool
-
-    app.SetMempool(evmMempool)
-    checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
-    app.SetCheckTxHandler(checkTxHandler)
-  }
+  // (moved below after ante/post handlers)

Add right after app.setPostHandler():

// mempool initialization (EVM priority nonce mempool)
if evmtypes.GetChainConfig() != nil {
  // TODO: derive block gas limit from consensus parameters
  mempoolConfig := &evmmempool.EVMMempoolConfig{
    AnteHandler:   app.GetAnteHandler(),
    BlockGasLimit: 100_000_000,
  }
  evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
  app.EVMMempool = evmMempool
  app.SetMempool(evmMempool)
  app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
}

Also applies to: 975-983


1048-1060: InitChainer unmarshals AppState into the wrong type; breaks genesis

AppStateBytes is the full genesis map, not the EVM-only state. Unmarshal into map[string]json.RawMessage and pass that to InitGenesis.

 func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
-  var genesisState cosmosevmtypes.GenesisState
+  var genesisState map[string]json.RawMessage
   if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
     panic(err)
   }
 
   if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
     panic(err)
   }
 
-  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
+  return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
 }
🧹 Nitpick comments (19)
warden/x/sched/module/simulation.go (2)

41-44: Avoid unnecessary allocation in WeightedOperations.

Return nil instead of allocating a zero-length slice.

-	operations := make([]simtypes.WeightedOperation, 0)
-
-	return operations
+	return nil

48-49: Use nil slice for ProposalMsgs.

nil is idiomatic and avoids an extra allocation; calling code handles len(nil)==0.

-	return []simtypes.WeightedProposalMsg{}
+	return nil
warden/x/sched/types/v1beta1/genesis_test.go (1)

11-27: Add a negative test case for invalid Params.

Increase coverage by asserting Validate() returns an error for an invalid Params configuration (whatever Params.Validate() deems invalid).

If helpful, I can propose a concrete failing case once you confirm the fields Params.Validate() checks.

cmd/wardend/config/chain_id.go (2)

12-29: Harden error handling and empty chain-id detection.

Add context to errors, guard empty home, and fail fast when chain-id is unset.

 func GetChainIDFromHome(home string) (string, error) {
+	if home == "" {
+		return "", fmt.Errorf("home directory must not be empty")
+	}
 	v := viper.New()
-	v.AddConfigPath(filepath.Join(home, "config"))
+	cfgDir := filepath.Join(home, "config")
+	v.AddConfigPath(cfgDir)
 	v.SetConfigName("client")
 	v.SetConfigType("toml")

-	if err := v.ReadInConfig(); err != nil {
-		return "", err
+	if err := v.ReadInConfig(); err != nil {
+		return "", fmt.Errorf("read config %s/client.toml: %w", cfgDir, err)
 	}

 	conf := new(config.ClientConfig)

-	if err := v.Unmarshal(conf); err != nil {
-		return "", err
+	if err := v.Unmarshal(conf); err != nil {
+		return "", fmt.Errorf("unmarshal client config: %w", err)
 	}

-	return conf.ChainID, nil
+	if conf.ChainID == "" {
+		return "", fmt.Errorf("chain-id not set in %s/client.toml", cfgDir)
+	}
+	return conf.ChainID, nil
 }

3-8: Add missing import for formatted errors.

Required by the suggested error wrapping.

 import (
+	"fmt"
 	"path/filepath"

 	"github.com/cosmos/cosmos-sdk/client/config"
 	"github.com/spf13/viper"
 )
prophet/registry.go (2)

8-11: Update comment to reflect plugins terminology.

-// registry is a global registry of tasks plugins.
+// registry is the global registry of plugins.

18-28: Rename parameter for clarity; consider avoiding panic for duplicates.

  • Use a neutral name (plugin) to match type and field.
  • Optional: return an error instead of panicking (API change).
-// Register registers a new task plugin with the given unique name.
-func Register(name string, task Plugin) {
+// Register registers a new plugin with the given unique name.
+func Register(name string, plugin Plugin) {
@@
-	registry.plugins[name] = task
+	registry.plugins[name] = plugin
 }
go.mod (1)

185-187: Optional: remove redundant indirect Pebble require

The replace on go.mod:10 pins Pebble to v0.0.0-20230928194634-aa077af62593, overriding the indirect require at go.mod:185. Run go mod tidy to drop the stale require and reduce confusion.

precompiles/precompiles.go (1)

3-22: Name collision risk between local cmn and evmcmn imports.

Two “common” aliases can confuse maintenance. Consider renaming the local one for clarity.

-	cmn "github.com/warden-protocol/wardenprotocol/precompiles/common"
+	pcommon "github.com/warden-protocol/wardenprotocol/precompiles/common"

And replace usages:

-	eventsRegistry := cmn.NewEthEventsRegistry()
+	eventsRegistry := pcommon.NewEthEventsRegistry()

-	newJsonPrecompile, err := jsonprecompile.NewPrecompile(cmn.NewAbiEncoder())
+	newJsonPrecompile, err := jsonprecompile.NewPrecompile(pcommon.NewAbiEncoder())
cmd/wardend/config/wardend_config.go (2)

34-41: Prefer error return over panic for default home dir.

If this function is used at CLI init, panicking aborts the process. Consider a non-Must variant and handle error at call sites.

-func MustGetDefaultNodeHome() string {
+func MustGetDefaultNodeHome() string { // keep for BC
    ...
 }
+
+func GetDefaultNodeHome() (string, error) {
+	return clienthelpers.GetNodeHomeDirectory(".warden")
+}

69-95: Pre-allocate blocked address map and avoid intermediate slice.

Minor perf/readability cleanups.

-func BlockedAddresses() map[string]bool {
-	blockedAddrs := make(map[string]bool)
-
-	maccPerms := GetMaccPerms()
-
-	accs := make([]string, 0, len(maccPerms))
-	for acc := range maccPerms {
-		accs = append(accs, acc)
-	}
-	sort.Strings(accs)
-
-	for _, acc := range accs {
-		blockedAddrs[authtypes.NewModuleAddress(acc).String()] = true
-	}
+func BlockedAddresses() map[string]bool {
+	maccPerms := GetMaccPerms()
+	blockedAddrs := make(map[string]bool, len(maccPerms)+len(corevm.PrecompiledAddressesBerlin)+len(evmtypes.AvailableStaticPrecompiles))
+
+	// determinism: stable order for reproducible maps if needed elsewhere
+	accs := make([]string, 0, len(maccPerms))
+	for acc := range maccPerms {
+		accs = append(accs, acc)
+	}
+	sort.Strings(accs)
+	for _, acc := range accs {
+		blockedAddrs[authtypes.NewModuleAddress(acc).String()] = true
+	}
warden/app/precompiles.go (1)

154-161: Rename param codec to avoid shadowing the imported package.

Improves clarity.

-	govPrecompile, err := govprecompile.NewPrecompile(
+	govPrecompile, err := govprecompile.NewPrecompile(
 		govkeeper.NewMsgServerImpl(&govKeeper),
 		govkeeper.NewQueryServer(&govKeeper),
 		bankKeeper,
-		codec,
+		codec, // keep callsite
 		options.AddressCodec,
 	)

Outside selected range (function signature), change:

-	codec codec.Codec,
+	cdc codec.Codec,

and the call:

-		govkeeper.NewQueryServer(&govKeeper),
-		bankKeeper,
-		codec,
+		govkeeper.NewQueryServer(&govKeeper),
+		bankKeeper,
+		cdc,
cmd/wardend/cmd/testnet.go (3)

250-257: Enable EVM JSON-RPC explicitly for testnet.

Defaults may be disabled; ensure it’s on for local testing.

 	evmCfg := evmdconfig.EVMAppConfig{
 		Config:  *appConfig,
 		EVM:     *evm,
-		JSONRPC: *cosmosevmserverconfig.DefaultJSONRPCConfig(),
+		JSONRPC: *func() *cosmosevmserverconfig.JSONRPCConfig { c := cosmosevmserverconfig.DefaultJSONRPCConfig(); c.Enable = true; return c }(),
 		TLS:     *cosmosevmserverconfig.DefaultTLSConfig(),
 	}

621-629: Avoid Scanln pitfalls; just wait for newline robustly.

fmt.Scanln() can error on empty input. Use a buffered read.

-	if _, err := fmt.Scanln(); err != nil { // wait for Enter Key
-		return err
-	}
+	_, _ = bufio.NewReader(os.Stdin).ReadBytes('\n')

634-641: Remove unused temp dir.

Temp dir is created and removed but never used.

-	dir, err := os.MkdirTemp("", "evm")
-	if err != nil {
-		panic(fmt.Sprintf("failed creating temporary directory: %v", err))
-	}
-	defer os.RemoveAll(dir)
+	// no temp dir needed for in-memory DB
cmd/wardend/cmd/root.go (1)

95-95: Avoid shadowing initClientCtx

Using := redefines initClientCtx in this scope; prefer assignment to keep a single variable and reduce confusion.

-      initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
+      initClientCtx, err = client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
warden/app/app.go (3)

1428-1434: Shadowing net/url import with local variable ‘url’

Local variable named url shadows the imported package, harms readability.

-    url, err := url.Parse(u)
+    parsedURL, err := url.Parse(u)
     if err != nil {
       panic(fmt.Errorf("invalid pricepred url: %s", u))
     }
 
-    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(url))
+    prophet.Register("pricepred", pricepred.NewPricePredictorSolidity(parsedURL))

332-341: Prophet sidecar is started from NewApp; ensure tempApp never starts it

NewApp may start the sidecar if rpc.laddr is set in appOpts. The CLI’s tempApp should never start external services. Verify temp AppOptions never include rpc.laddr; otherwise guard this block behind loadLatest or a dedicated option.

Would you like a follow-up diff to gate prophet startup behind a specific appOpt (e.g., prophet.enabled)?


1302-1318: Close gracefully aggregates errors; consider closing prophet too

Close() does not stop the prophet sidecar. If prophet exposes a stopper, call it here.

I can wire a best-effort shutdown (ignore if not present).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 12fedf7 and 25776fb.

⛔ Files ignored due to path filters (64)
  • go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (73)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (1 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/evm_app_options.go (1 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (0 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/genesis.go (0 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (3 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (33)
  • warden/x/act/module/genesis_test.go
  • warden/x/act/module/autocli.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/async/module/genesis.go
  • warden/x/sched/module/autocli.go
  • warden/x/warden/types/v1beta3/genesis.go
  • warden/x/warden/module/genesis_test.go
  • warden/x/warden/module/autocli.go
  • warden/testutil/nullify/nullify.go
  • cmd/wardend/cmd/config.go
  • warden/x/async/module/genesis_test.go
  • warden/app/genesis.go
  • warden/x/async/types/v1beta1/genesis.go
  • precompiles/slinky/slinky.go
  • warden/app/config.go
  • warden/app/sim_bench_test.go
  • warden/x/act/types/v1beta1/genesis.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/act/module/genesis.go
  • warden/testutil/sample/sample.go
  • warden/x/warden/module/genesis.go
  • warden/x/sched/module/genesis.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/x/sched/types/v1beta1/genesis.go
  • warden/x/act/types/v1beta1/codec.go
  • warden/x/sched/module/genesis_test.go
  • warden/app/app_config.go
  • warden/app/ante.go
  • warden/app/legacy.go
  • warden/app/sim_test.go
  • warden/testutil/network/network.go
  • cmd/wardend/cmd/commands.go
  • cmd/wardend/cmd/wait.go
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (25)
  • warden/app/ante/evm_handler.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • warden/app/ante/sched_handler.go
  • cmd/wardend/main.go
  • warden/x/warden/module/simulation.go
  • warden/app/vemanager/vemanager.go
  • precompiles/act/act.go
  • warden/app/ante/options.go
  • cmd/wardend/config/config.go
  • warden/app/ante/ante.go
  • warden/x/sched/keeper/abci.go
  • warden/x/act/module/simulation.go
  • tests/framework/exec/warden_eth.go
  • precompiles/sched/sched.go
  • precompiles/warden/warden.go
  • tests/framework/snapshot/snapshots.go
  • warden/x/async/module/simulation.go
  • precompiles/json/json.go
  • localnet.just
  • warden/x/warden/types/v1beta3/genesis_test.go
  • warden/x/async/types/v1beta1/keys.go
  • warden/app/export.go
  • warden/app/oracle.go
  • warden/app/upgrades.go
  • warden/app/ante/cosmos.go
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-10-24T13:01:55.558Z
Learnt from: backsapc
PR: warden-protocol/wardenprotocol#810
File: cmd/wardenkms/wardenkms.go:45-50
Timestamp: 2024-10-24T13:01:55.558Z
Learning: In the `cmd/wardenkms/wardenkms.go` file and the codebase, use `Grpc` instead of `GRPC` for acronym casing in type names, such as `GrpcNodeConfig` and `GrpcNodeConfigDecoder`, even though Go naming conventions suggest capitalizing acronyms.

Applied to files:

  • cmd/wardend/config/evm_app_options.go
📚 Learning: 2024-06-10T19:20:04.350Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-06-10T19:20:04.350Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
🧬 Code graph analysis (1)
warden/x/sched/types/v1beta1/genesis_test.go (1)
warden/x/sched/types/v1beta1/genesis.pb.go (3)
  • GenesisState (28-31)
  • GenesisState (35-35)
  • GenesisState (36-38)
⏰ 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). (7)
  • GitHub Check: lint
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (10)
warden/x/sched/types/v1beta1/genesis_test.go (1)

24-26: No changes needed: DefaultParams() returns the zero‐value Params and there is no Validate() logic on GenesisState or Params, so &GenesisState{} is functionally equivalent to &GenesisState{Params: types.DefaultParams()}.

precompiles/async/async.go (1)

45-49: Add nil-check for bankKeeper in NewPrecompile
Reject a nil BankKeeper up front to prevent a runtime nil-pointer in Run. All existing callers pass a non-nil value.

justfile (1)

27-29: Good: strict shell mode.

set -euxo pipefail makes the deploy flow fail-fast and easier to debug.

precompiles/precompiles.go (1)

36-44: BankKeeper wiring across precompiles looks good.

Constructor signatures and event registry integration are consistent with the evm precompile common.BankKeeper pattern.

Also applies to: 48-53, 65-71, 101-106, 121-129

cmd/wardend/config/wardend_config.go (1)

140-152: LGTM: AppConfig/EVM/JSON-RPC/Oracle defaults are coherent.

Enabling JSON-RPC by default and wiring EVM chain ID via parameter is consistent with the rest of the PR.

Also applies to: 160-186

warden/app/precompiles.go (4)

188-196: LGTM: Warden precompiles wiring via BankKeeper and opts-based codecs.

Clean separation with options and coherent constructor usage.


127-137: Awaiting script results to confirm parameter types and receiver expectations.


165-172: Verify slashing MsgServerImpl argument
Confirm the signature of slashingkeeper.NewMsgServerImpl and the declared type of slashingKeeper; only switch to &slashingKeeper if the method requires a pointer to the keeper.


49-56: No action required—Bech32 prefixes are set before precompile init
setupSDKConfig() in cmd/wardend/main.go sets and seals all Bech32 prefixes before NewAvailableStaticPrecompiles runs, and tests initialize prefixes in their init functions.

warden/app/app.go (1)

374-386: err reuse is now valid; keep it that way

Using the function-scoped err declared earlier fixes the previous compile error.

Copy link
Contributor

@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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
localnet.just (1)

101-103: Bug: wrong variable when deploying osmosis analyzer

Deploys ethereum_analyzer instead of osmosis_analyzer.

-          just deploy-contract $ethereum_analyzer_wasm
+          just deploy-contract $osmosis_analyzer_wasm
♻️ Duplicate comments (13)
go.mod (2)

143-143: Remove depinject to align with PR objective.

The PR removes depinject, but go.mod still lists cosmossdk.io/depinject (indirect). Drop it after ensuring no imports remain.

-  cosmossdk.io/depinject v1.2.1 // indirect
#!/usr/bin/env bash
# Ensure no code still imports depinject
rg -nP '\bcosmossdk\.io/depinject\b' -S -g '!**/vendor/**' -C2

380-381: Drop non-canonical YAML module path (use gopkg.in/yaml.v2).

go.yaml.in/yaml/v2 is redundant and non-canonical; gopkg.in/yaml.v2 is already present.

-  go.yaml.in/yaml/v2 v2.4.2 // indirect
#!/usr/bin/env bash
# Confirm no references to the non-canonical path remain
rg -nP 'go\.yaml\.in/yaml/v2' -S -g '!**/vendor/**' -C2
cmd/wardend/cmd/testnet.go (8)

317-319: Use loopback (127.0.0.1) in single-machine mode, not 0.0.0.0.

0.0.0.0 isn’t dialable for peers; this breaks persistent peer memos.

- if args.singleMachine {
-   ip = "0.0.0.0"
+ if args.singleMachine {
+   ip = "127.0.0.1"

418-419: Handle app.toml write errors.

Don’t ignore WriteConfigFile errors.

- srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg)
+ if err := srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg); err != nil {
+   return err
+ }

536-540: Persist CometBFT config (config.toml) per node.

After exporting genesis, write the (mutated) Comet config to disk.

   if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
     return err
   }
+  if err := cmtconfig.WriteConfigFile(
+    filepath.Join(nodeDir, "config", "config.toml"),
+    nodeConfig,
+  ); err != nil {
+    return err
+  }

236-243: Validate validator count early to prevent resource misuse.

Fail fast on invalid counts.

 if args.chainID == "" {
   args.chainID = "local-4221"
 }
+if args.numValidators < 1 || args.numValidators > 100 {
+  return fmt.Errorf("number of validators must be between 1 and 100, got %d", args.numValidators)
+}

280-289: Compile error: cannot range over int.

Replace the invalid range with an indexed for-loop.

- for i := range args.numValidators {
+ for i := 0; i < args.numValidators; i++ {
   var (
     portOffset    int
     evmPortOffset int
   )
   if args.singleMachine {
     portOffset = i
     evmPortOffset = i * 10

481-485: Compile error: cannot range over int in initGenFiles.

Same fix applies.

- for i := range numValidators {
+ for i := 0; i < numValidators; i++ {
   if err := genDoc.SaveAs(genFiles[i]); err != nil {
     return err
   }
 }

501-507: Compile error: cannot range over int in collectGenFiles.

Fix the loop construct.

- for i := range numValidators {
+ for i := 0; i < numValidators; i++ {
   if singleMachine {
     portOffset := i
     nodeConfig.RPC.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", rpcPortStart+portOffset)
     nodeConfig.P2P.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", p2pPortStart+portOffset)
   }

564-568: Compile error and IP math bug: cannot range over int; potential /24 overflow.

Implement safe arithmetic and bound to the same /24.

- for range i {
-   ipv4[3]++
- }
+ orig := (uint32(ipv4[0]) << 24) | (uint32(ipv4[1]) << 16) | (uint32(ipv4[2]) << 8) | uint32(ipv4[3])
+ off := int64(i)
+ if off < 0 && uint32(-off) > orig {
+   return "", fmt.Errorf("IP address underflow: %s + (%d)", ip, i)
+ }
+ newIP := uint32(int64(orig) + off)
+ // stay within the same /24 subnet
+ if (newIP>>8) != (orig>>8) {
+   return "", fmt.Errorf("IP address overflow into another subnet: %s + %d", ip, i)
+ }
+ ipv4[0] = byte(newIP >> 24)
+ ipv4[1] = byte(newIP >> 16)
+ ipv4[2] = byte(newIP >> 8)
+ ipv4[3] = byte(newIP)
warden/app/app.go (2)

1048-1060: InitChainer unmarshals wrong type; breaks genesis initialization.

Unmarshal AppState into map[string]json.RawMessage and pass that to ModuleManager.InitGenesis.

- var genesisState cosmosevmtypes.GenesisState
+ var genesisState map[string]json.RawMessage
  if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
    panic(err)
  }
- return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
+ return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)

914-929: Move EVM mempool initialization to after app.SetAnteHandler
Mempool setup at lines 914–929 runs before app.SetAnteHandler(...) at line 1374, so app.GetAnteHandler() returns nil.

- // mempool initialization (EVM priority nonce mempool)
- if evmtypes.GetChainConfig() != nil {
-   mempoolConfig := &evmmempool.EVMMempoolConfig{
-     AnteHandler:   app.GetAnteHandler(),
-     BlockGasLimit: 100_000_000,
-   }
-   evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-   app.EVMMempool = evmMempool
-   app.SetMempool(evmMempool)
-   app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
- }
+ // move this block to immediately after app.SetAnteHandler(...) at line 1374
cmd/wardend/cmd/root.go (1)

61-70: Temp app uses constant EVM chain ID — risk of EIP‑712 mismatch and global configurator conflicts.

Resolve evmChainID from home (or client config) before creating tempApp.

 	noOpEvmAppOptions := func(_ uint64) error { return nil }
+	// derive EVM chain ID for temp app (avoid EIP-712/config mismatches)
+	evmForTemp := wardendconfig.EVMChainID
+	if home := wardendconfig.MustGetDefaultNodeHome(); home != "" {
+		if cid, err := wardendconfig.GetChainIDFromHome(home); err == nil {
+			if parsed, err := parseEVMChainID(cid); err == nil {
+				evmForTemp = parsed
+			}
+		}
+	}
 	tempApp := app.NewApp(
 		log.NewNopLogger(),
 		dbm.NewMemDB(),
 		nil,
 		true,
 		simtestutil.NewAppOptionsWithFlagHome(temp),
-		wardendconfig.EVMChainID,
+		evmForTemp,
 		noOpEvmAppOptions,
 	)
🧹 Nitpick comments (13)
prophet/registry.go (4)

8-8: Fix outdated comment (“tasks plugins”)

Comment still references “tasks”. Update for accuracy.

-// registry is a global registry of tasks plugins.
+// registry is a global registry of plugins.

9-16: Rename internal type r for clarity

Single-letter type obscures intent. Rename to pluginRegistry and keep the package-level var as registry.

-var registry = r{
+var registry = pluginRegistry{
 	plugins: make(map[string]Plugin),
 }
 
-type r struct {
+type pluginRegistry struct {
 	rw      sync.RWMutex
 	plugins map[string]Plugin
 }

3-6: Deterministic order for RegisteredPlugins

Map iteration order is random; sort the names to avoid flakiness and improve UX. Add the import.

 import (
 	"fmt"
+	"sort"
 	"sync"
 )
-	plugins := make([]string, 0, len(registry.plugins))
-	for name := range registry.plugins {
-		plugins = append(plugins, name)
-	}
+	plugins := make([]string, 0, len(registry.plugins))
+	for name := range registry.plugins {
+		plugins = append(plugins, name)
+	}
+	sort.Strings(plugins)
 
 	return plugins

Also applies to: 41-46


9-16: Consider test isolation (global state)

A package-global registry can leak state across tests. Consider adding a constructor (e.g., NewRegistry for non-global instances) or a test-only Reset() to clear registry.plugins.

localnet.just (3)

37-37: Pass --home to init to avoid relying on default $HOME

Makes the script resilient if WARDEN_HOME ever changes or tests run under a different home.

-    {{bin}} init localnet --chain-id {{chain_id}} --default-denom award > /dev/null
+    {{bin}} init localnet --home "$WARDEN_HOME" --chain-id {{chain_id}} --default-denom award > /dev/null

Tip: consider doing the same for subsequent config/keys/genesis commands for consistency.


109-109: Pass --home to start for consistency with WARDEN_HOME

Prevents accidental use of a different home in CI/local runs.

-    (post_start &) && {{bin}} start
+    (post_start &) && {{bin}} start --home "$WARDEN_HOME"

4-5: Remove or use unused val2/val2_mnemonic

Currently defined but unused; either add val2 as a second validator/account or drop these lines.

- val2 := "warden194j3dx4t7u80765k2puu3082vc39yfqnvrxqu7"
- val2_mnemonic := "door blast other element embark noodle maple agent drastic bunker swarm logic wide deputy exhibit bicycle evil exile air other mesh foot tackle spot"
+ # (optional) define/use a second validator/account, or omit these variables
warden/x/sched/keeper/abci.go (1)

134-145: Future-proof EVM signer selection.

Using NewLondonSigner with a LegacyTx works, but LatestSignerForChainID is safer across hard forks.

- signedEthTx, err := ethtypes.SignNewTx(
-   privkey,
-   ethtypes.NewLondonSigner(new(big.Int).SetUint64(chainID)),
+ signedEthTx, err := ethtypes.SignNewTx(
+   privkey,
+   ethtypes.LatestSignerForChainID(new(big.Int).SetUint64(chainID)),
    &ethtypes.LegacyTx{
warden/app/oracle.go (1)

259-265: Recover + re-panic is fine; consider logging via app logger for consistency.

debug.PrintStack() goes to stderr. Logging the panic with app.Logger() improves observability.

-    defer func() {
-      if err := recover(); err != nil {
-        debug.PrintStack()
-        panic(err)
-      }
-    }()
+    defer func() {
+      if r := recover(); r != nil {
+        debug.PrintStack()
+        ctx.Logger().Error("panic in PreBlocker", "panic", r)
+        panic(r)
+      }
+    }()
cmd/wardend/cmd/testnet.go (1)

607-610: Typo in error message (“testnests”).

Fix for clarity.

- "testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
+ "testnets directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
precompiles/warden/warden.go (2)

74-76: Minor consistency: use p.Address() when setting the address.

Other precompiles use p.SetAddress(p.Address()). Align for uniformity.

-	p.SetAddress(common.HexToAddress(PrecompileAddress))
+	p.SetAddress(p.Address())

200-235: Avoid panic on unknown method in IsTransaction.

A panic here can crash the node if reached unexpectedly. Prefer a safe default.

 func (*Precompile) IsTransaction(method *abi.Method) bool {
   switch method.Name {
     // cases ...
-  }
-
-  panic(fmt.Errorf("warden precompile: method not exists: %s", method))
+  default:
+    // Unknown method: treat as a query; Run/ABI decode will error out safely.
+    return false
+  }
 }
cmd/wardend/cmd/root.go (1)

153-155: Don’t ignore error from ReadFromClientConfig.

Guard or log; PreRunE already does strict handling.

-	initClientCtx, _ = clientcfg.ReadFromClientConfig(initClientCtx)
-	autoCliOpts.ClientCtx = initClientCtx
+	if cctx, err := clientcfg.ReadFromClientConfig(initClientCtx); err == nil {
+		initClientCtx = cctx
+	}
+	autoCliOpts.ClientCtx = initClientCtx
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 25776fb and ae80e60.

⛔ Files ignored due to path filters (65)
  • go.sum is excluded by !**/*.sum
  • tests/slinky/go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (79)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (1 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/evm_app_options.go (1 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • tests/slinky/go.mod (10 hunks)
  • tests/slinky/slinky_test.go (2 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (0 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/genesis.go (0 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/module.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/module.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (3 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/module.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/module.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (37)
  • warden/x/sched/module/autocli.go
  • warden/x/act/types/v1beta1/codec.go
  • precompiles/slinky/slinky.go
  • warden/x/act/types/v1beta1/genesis.go
  • warden/x/warden/module/genesis.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/warden/types/v1beta3/genesis.go
  • warden/testutil/sample/sample.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/sched/types/v1beta1/genesis.go
  • cmd/wardend/cmd/commands.go
  • warden/app/sim_bench_test.go
  • warden/x/async/types/v1beta1/genesis.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/x/warden/module/genesis_test.go
  • warden/x/warden/module/module.go
  • warden/x/act/module/genesis_test.go
  • warden/x/act/module/module.go
  • warden/testutil/network/network.go
  • cmd/wardend/cmd/config.go
  • warden/app/config.go
  • warden/x/sched/module/genesis_test.go
  • warden/app/legacy.go
  • warden/app/app_config.go
  • warden/x/async/module/genesis.go
  • warden/x/sched/module/module.go
  • warden/x/async/module/genesis_test.go
  • warden/testutil/nullify/nullify.go
  • warden/app/sim_test.go
  • warden/app/ante.go
  • warden/x/async/module/module.go
  • warden/app/genesis.go
  • warden/x/act/module/autocli.go
  • warden/x/sched/module/genesis.go
  • warden/x/warden/module/autocli.go
  • cmd/wardend/cmd/wait.go
  • warden/x/act/module/genesis.go
🚧 Files skipped from review as they are similar to previous changes (26)
  • warden/x/sched/module/simulation.go
  • CHANGELOG.md
  • warden/app/ante/sched_handler.go
  • warden/x/sched/types/v1beta1/genesis_test.go
  • warden/app/upgrades.go
  • warden/app/vemanager/vemanager.go
  • precompiles/act/act.go
  • tests/framework/exec/warden_eth.go
  • cmd/wardend/config/evm_app_options.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • tests/framework/snapshot/snapshots.go
  • cmd/wardend/config/chain_id.go
  • warden/x/warden/types/v1beta3/genesis_test.go
  • warden/app/ante/ante.go
  • warden/x/async/module/simulation.go
  • cmd/wardend/config/config.go
  • warden/x/act/module/simulation.go
  • precompiles/async/async.go
  • warden/app/ante/options.go
  • precompiles/json/json.go
  • warden/x/async/types/v1beta1/keys.go
  • warden/app/export.go
  • warden/app/ante/cosmos.go
  • warden/app/ante/evm_handler.go
  • warden/x/warden/module/simulation.go
  • cmd/wardend/main.go
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2024-11-02T10:21:03.096Z
Learnt from: backsapc
PR: warden-protocol/wardenprotocol#975
File: warden/app/app.go:562-562
Timestamp: 2024-11-02T10:21:03.096Z
Learning: In `warden/app/app.go`, suggestions to handle errors from `ParamsKeeper.GetSubspace()` may be considered out of scope.

Applied to files:

  • cmd/wardend/cmd/testnet.go
📚 Learning: 2024-11-21T11:35:35.678Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#1095
File: warden/app/oracle.go:0-0
Timestamp: 2024-11-21T11:35:35.678Z
Learning: In the Go file `warden/app/oracle.go`, it is acceptable to panic inside the goroutine that starts the oracle client, because an error here indicates a misconfiguration (e.g., the address was misconfigured), and the application should exit.

Applied to files:

  • warden/app/oracle.go
📚 Learning: 2024-06-10T19:20:04.350Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-06-10T19:20:04.350Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
🧬 Code graph analysis (9)
cmd/wardend/config/wardend_config.go (1)
cmd/wardend/config/config.go (1)
  • EVMChainID (30-30)
precompiles/sched/sched.go (5)
precompiles/act/act.go (2)
  • NewPrecompile (45-70)
  • Precompile (31-37)
precompiles/async/async.go (2)
  • NewPrecompile (45-70)
  • Precompile (31-37)
precompiles/warden/warden.go (4)
  • NewPrecompile (50-78)
  • Precompile (34-42)
  • Precompile (81-83)
  • Precompile (200-235)
warden/x/sched/keeper/keeper.go (1)
  • Keeper (22-34)
warden/x/sched/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (18-22)
prophet/registry.go (1)
prophet/plugins.go (1)
  • Plugin (12-19)
warden/app/oracle.go (1)
warden/app/app.go (1)
  • App (184-255)
precompiles/warden/warden.go (2)
precompiles/act/act.go (3)
  • Precompile (31-37)
  • LoadABI (41-43)
  • NewPrecompile (45-70)
precompiles/async/async.go (3)
  • Precompile (31-37)
  • LoadABI (41-43)
  • NewPrecompile (45-70)
cmd/wardend/cmd/root.go (5)
warden/app/app.go (2)
  • NewApp (257-1025)
  • App (184-255)
cmd/wardend/config/config.go (2)
  • EVMChainID (30-30)
  • BaseDenom (26-26)
cmd/wardend/config/wardend_config.go (2)
  • MustGetDefaultNodeHome (34-41)
  • InitAppConfig (122-186)
cmd/wardend/config/evm_app_options.go (1)
  • EvmAppOptions (25-44)
cmd/wardend/config/chain_id.go (1)
  • GetChainIDFromHome (12-29)
warden/app/app.go (18)
warden/x/act/keeper/keeper.go (2)
  • Keeper (21-38)
  • NewKeeper (48-91)
warden/x/async/keeper/keeper.go (2)
  • Keeper (34-61)
  • NewKeeper (79-145)
warden/x/warden/keeper/keeper.go (2)
  • Keeper (18-45)
  • NewKeeper (62-122)
warden/x/sched/keeper/keeper.go (2)
  • Keeper (22-34)
  • NewKeeper (44-76)
prophet/prophet.go (2)
  • P (22-31)
  • New (34-51)
prophet/plugins/pfp/pfp.go (2)
  • New (25-40)
  • Plugin (20-23)
prophet/plugins/veniceimg/veniceimg.go (2)
  • New (21-30)
  • Plugin (17-19)
prophet/plugins/quantkit/quantkit.go (2)
  • New (18-30)
  • Plugin (13-15)
prophet/plugins/venice/venice.go (2)
  • New (15-24)
  • Plugin (11-13)
warden/x/act/types/v1beta1/registry.go (2)
  • NewTemplatesRegistry (68-72)
  • Register (37-44)
warden/app/precompiles.go (1)
  • NewAvailableStaticPrecompiles (82-211)
warden/app/genesis.go (3)
  • GenesisState (19-19)
  • NewEVMGenesisState (22-27)
  • NewErc20GenesisState (33-39)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
warden/app/ante/ante.go (1)
  • NewAnteHandler (17-58)
prophet/registry.go (1)
  • Register (19-28)
prophet/plugins/http/http.go (2)
  • Plugin (25-30)
  • NewPlugin (33-51)
prophet/plugins/echo/echo.go (1)
  • Plugin (13-13)
prophet/plugins/pricepred/pricepred.go (1)
  • NewPricePredictorSolidity (22-30)
precompiles/precompiles.go (6)
warden/x/async/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (31-35)
warden/x/sched/types/v1beta1/expected_keepers.go (1)
  • BankKeeper (18-22)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
warden/app/precompiles.go (5)
precompiles/act/act.go (1)
  • NewPrecompile (45-70)
precompiles/async/async.go (1)
  • NewPrecompile (45-70)
precompiles/sched/sched.go (1)
  • NewPrecompile (46-73)
precompiles/warden/warden.go (1)
  • NewPrecompile (50-78)
precompiles/slinky/slinky.go (1)
  • NewPrecompile (47-70)
🪛 OSV Scanner (2.1.0)
tests/slinky/go.mod

[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Denial of service in message decoding in github.com/btcsuite/btcd

(GO-2022-1098)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Consensus failures in github.com/btcsuite/btcd

(GO-2024-2818)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Consensus failure in github.com/btcsuite/btcd

(GO-2024-3189)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd did not correctly re-implement Bitcoin Core's "FindAndDelete()" functionality

(GHSA-27vh-h6mc-q6g8)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd mishandles witness size checking

(GHSA-2chg-86hq-7w38)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd susceptible to consensus failures

(GHSA-3jgf-r68h-xfqm)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: The x/crisis package does not cause chain halt in github.com/cosmos/cosmos-sdk

(GO-2023-1821)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: The x/crisis package does not charge ConstantFee in github.com/cosmos/cosmos-sdk

(GO-2023-1881)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: Groups module can halt chain when handling a malicious proposal in github.com/cosmos/cosmos-sdk

(GO-2025-3476)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK can halt when erroring in EndBlocker in github.com/cosmos/cosmos-sdk/

(GO-2025-3516)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Integer Overflow vulnerability in its Validator Rewards pool can cause a chain halt in github.com/cosmos/cosmos-sdk

(GO-2025-3803)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: x/group can halt when erroring in EndBlocker

(GHSA-47ww-ff84-4jrg)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK's Integer Overflow vulnerability in its Validator Rewards pool can cause a chain halt

(GHSA-p22h-3m2v-cmgh)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: Groups module can halt chain when handling a malicious proposal

(GHSA-x5vx-95h7-rv4p)

⏰ 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). (8)
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (go)
🔇 Additional comments (27)
prophet/registry.go (1)

10-11: LGTM: explicit map init

Preallocating the plugins map at package init is correct and concurrency-safe with the RWMutex.

localnet.just (2)

69-69: LGTM: enable no_base_fee for local dev

This aligns with frictionless local testing and your updated tests/framework.


71-76: Sleep runs only when deploying; confirm intent or move before early return

If the wait is desired regardless of deployment, place it before the guard.

 post_start () {
-  if [[ "{{deploy-contracts}}" == "false" ]]; then
-    return
-  fi
-
-  sleep 5
+  sleep 5
+  if [[ "{{deploy-contracts}}" == "false" ]]; then
+    return
+  fi
tests/slinky/slinky_test.go (2)

27-28: Field rename to UIDGID looks correct.

Matches upstream interchaintest/v8 change; no functional risk.


37-38: Consistent UIDGID usage for oracle image.

Good alignment with new API.

warden/x/sched/keeper/abci.go (3)

21-21: New crypto import is appropriate for deriving tx.From.

OK to use crypto.PubkeyToAddress for setting From.


138-141: Validate gas headroom for precompile call.

200_000 should exceed intrinsic cost, but if executeCallbacks grows, this could underflow at runtime. Consider a named const with a comment on budgeting assumptions or estimating intrinsic gas during tests.


166-170: Confirm FromEthereumTx error semantics; don’t ignore a possible error.
The rg search on your module cache didn’t locate MsgEthereumTx.FromEthereumTx, so please manually verify that in your pinned EVM implementation it has the signature

func (m *MsgEthereumTx) FromEthereumTx(*types.Transaction) error

and handle its error return accordingly:

 func buildCosmosWrappedTx(builder client.TxBuilder, signedEthTx *ethtypes.Transaction) (signing.Tx, error) {
-  tx.FromEthereumTx(signedEthTx)
+  if err := tx.FromEthereumTx(signedEthTx); err != nil {
+    return nil, fmt.Errorf("FromEthereumTx: %w", err)
+  }
   tx.From = crypto.PubkeyToAddress(privkey.PublicKey).Bytes()
warden/app/oracle.go (1)

58-61: Verify nil mempool usage in DefaultProposalHandler
Passing nil as the mempool to NewDefaultProposalHandler may impact proposer selection, prioritization, or recheck logic. Manually confirm that no code path in the handler assumes a non-nil mempool.

justfile (1)

27-30: Ignore fee/gas mismatch warning
Localnet and e2e snapshots configure minimum-gas-prices = 0award, so --gas 10000000 --fees 1award yields a gas price > 0 and will not be rejected.

Likely an incorrect or invalid review comment.

go.mod (1)

3-3: Build images use Go 1.25
Dockerfiles (warden.Dockerfile and all cmd/*/Dockerfile) reference golang:1.25-trixie, matching the go 1.25.0 directive.

tests/slinky/go.mod (2)

3-3: CI uses Go 1.25, so the go 1.24 directive is supported. The GitHub workflows all invoke actions/setup-go@v5 with go-version “1.25,” so no changes are needed to the go directive.


39-39: Cosmossdk.io/depinject is only a transitive dependency – no direct imports found.

warden/app/precompiles.go (4)

40-56: Options pattern for codecs: solid and backward-compatible.

Good defaulting and selective overrides; keeps constructors stable.


116-134: Staking/distribution codec injection: correct usage.

Passing AddressCodec into staking and distribution precompiles is consistent with new constructors.


154-171: Gov/slashing constructor updates: correct and aligned with upstream.

Bank keeper and codec wiring look right; Validator/Consensus codecs injected.


188-196: Bank-aware Warden precompiles: correct threading.

bankKeeper now provided; matches precompile constructors elsewhere.

warden/app/app.go (3)

1289-1291: GetAnteHandler delegates to BaseApp’s AnteHandler: OK.

Accessor is correct; no action.


1302-1318: Graceful Close joins mempool and baseapp errors: good shutdown behavior.

LGTM.


1482-1504: NewTxConfig custom signers and Bech32 codecs: coherent with EVM/erc20 flows.

LGTM.

precompiles/sched/sched.go (1)

46-71: Add bankKeeper and wire balance handler: correct enhancement.

Constructor change is minimal and matches the precompile contract pattern.

precompiles/warden/warden.go (2)

35-41: Good migration to evmcmn.Precompile and typed fields.

Embedding evmcmn.Precompile and wiring the query servers look correct and consistent with other precompiles.


111-116: Gas error handling LGTM.

Switch to evmcmn.HandleGasError is correct for the updated common.

cmd/wardend/config/wardend_config.go (1)

34-41: MustGetDefaultNodeHome semantics LGTM.

“Must*” behavior (panic on error) is acceptable here.

precompiles/precompiles.go (1)

37-44: BankKeeper propagation and balance handler wiring LGTM.

Signature changes and constructor calls are consistent across act/warden/async/sched and match the new common.

Also applies to: 48-52, 65-70, 101-105, 121-121

cmd/wardend/cmd/root.go (2)

125-147: Client context setup flow LGTM.

Online textual sign mode is conditionally enabled and context is propagated correctly.


187-193: Bech32 prefixes are initialized before sealing
The setupSDKConfig in cmd/wardend/main.go calls wardendconfig.SetBech32Prefixes(config) then config.Seal(), so the prefixes are set globally prior to the Seal() in initRootCmd.

Comment on lines +85 to +92
blockedPrecompilesHex := evmtypes.AvailableStaticPrecompiles
for _, addr := range corevm.PrecompiledAddressesBerlin {
blockedPrecompilesHex = append(blockedPrecompilesHex, addr.Hex())
}

for _, precompile := range blockedPrecompilesHex {
blockedAddrs[cosmosevmutils.Bech32StringFromHexAddress(precompile)] = true
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: possible mutation of evmtypes.AvailableStaticPrecompiles via slice aliasing.

Assigning the package slice and appending may modify the source slice if capacity permits. Copy before appending.

-	blockedPrecompilesHex := evmtypes.AvailableStaticPrecompiles
-	for _, addr := range corevm.PrecompiledAddressesBerlin {
-		blockedPrecompilesHex = append(blockedPrecompilesHex, addr.Hex())
-	}
+	blockedPrecompilesHex := make([]string, 0, len(evmtypes.AvailableStaticPrecompiles)+len(corevm.PrecompiledAddressesBerlin))
+	blockedPrecompilesHex = append(blockedPrecompilesHex, evmtypes.AvailableStaticPrecompiles...)
+	for _, addr := range corevm.PrecompiledAddressesBerlin {
+		blockedPrecompilesHex = append(blockedPrecompilesHex, addr.Hex())
+	}
📝 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
blockedPrecompilesHex := evmtypes.AvailableStaticPrecompiles
for _, addr := range corevm.PrecompiledAddressesBerlin {
blockedPrecompilesHex = append(blockedPrecompilesHex, addr.Hex())
}
for _, precompile := range blockedPrecompilesHex {
blockedAddrs[cosmosevmutils.Bech32StringFromHexAddress(precompile)] = true
}
blockedPrecompilesHex := make([]string, 0, len(evmtypes.AvailableStaticPrecompiles)+len(corevm.PrecompiledAddressesBerlin))
blockedPrecompilesHex = append(blockedPrecompilesHex, evmtypes.AvailableStaticPrecompiles...)
for _, addr := range corevm.PrecompiledAddressesBerlin {
blockedPrecompilesHex = append(blockedPrecompilesHex, addr.Hex())
}
for _, precompile := range blockedPrecompilesHex {
blockedAddrs[cosmosevmutils.Bech32StringFromHexAddress(precompile)] = true
}
🤖 Prompt for AI Agents
In cmd/wardend/config/wardend_config.go around lines 85 to 92, the code assigns
evmtypes.AvailableStaticPrecompiles to blockedPrecompilesHex and then appends to
it, which can mutate the package-level slice via slice aliasing; make a copy of
the source slice before modifying it (e.g., allocate a new slice with the same
length/capacity and copy the elements, or initialize via append([]string{},
evmtypes.AvailableStaticPrecompiles...)), then append the
corevm.PrecompiledAddressesBerlin hex strings to that new slice and proceed to
populate blockedAddrs from the copied slice.

Comment on lines +107 to +110
EVM cosmosevmserverconfig.EVMConfig
JSONRPC cosmosevmserverconfig.JSONRPCConfig
TLS cosmosevmserverconfig.TLSConfig

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add mapstructure/json tags for nested EVM/JSONRPC/TLS configs.

Hyphenated keys (json-rpc) won’t map reliably without tags.

-	EVM     cosmosevmserverconfig.EVMConfig
-	JSONRPC cosmosevmserverconfig.JSONRPCConfig
-	TLS     cosmosevmserverconfig.TLSConfig
+	EVM     cosmosevmserverconfig.EVMConfig     `mapstructure:"evm" json:"evm"`
+	JSONRPC cosmosevmserverconfig.JSONRPCConfig `mapstructure:"json-rpc" json:"json-rpc"`
+	TLS     cosmosevmserverconfig.TLSConfig     `mapstructure:"tls" json:"tls"`
📝 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
EVM cosmosevmserverconfig.EVMConfig
JSONRPC cosmosevmserverconfig.JSONRPCConfig
TLS cosmosevmserverconfig.TLSConfig
// …
EVM cosmosevmserverconfig.EVMConfig `mapstructure:"evm" json:"evm"`
JSONRPC cosmosevmserverconfig.JSONRPCConfig `mapstructure:"json-rpc" json:"json-rpc"`
TLS cosmosevmserverconfig.TLSConfig `mapstructure:"tls" json:"tls"`
// …
🤖 Prompt for AI Agents
In cmd/wardend/config/wardend_config.go around lines 107-110, the nested fields
EVM, JSONRPC and TLS lack mapstructure/json tags so hyphenated keys like
"json-rpc" won't map; add explicit struct tags to each field specifying both
json and mapstructure names (e.g. for EVM use json:"evm" mapstructure:"evm", for
JSONRPC use json:"json-rpc" mapstructure:"json-rpc", for TLS use json:"tls"
mapstructure:"tls") so the config loader/unmarshal correctly maps nested
configs.

Comment on lines +175 to +184
customAppTemplate := serverconfig.DefaultConfigTemplate +
oracleconfig.DefaultConfigTemplate +
cosmosevmserverconfig.DefaultEVMConfigTemplate +
pricepredconfig.DefaultConfigTemplate +
httpconfig.DefaultConfigTemplate +
pfpconfig.DefaultConfigTemplate +
quantkitconfig.DefaultConfigTemplate +
veniceconfig.DefaultConfigTemplate +
veniceimgconfig.DefaultConfigTemplate

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing JSON-RPC and TLS templates in customAppTemplate.

Without these, app.toml will omit json-rpc/tls sections despite being populated in customAppConfig.

 	customAppTemplate := serverconfig.DefaultConfigTemplate +
 		oracleconfig.DefaultConfigTemplate +
 		cosmosevmserverconfig.DefaultEVMConfigTemplate +
+		cosmosevmserverconfig.DefaultJSONRPCConfigTemplate +
+		cosmosevmserverconfig.DefaultTLSConfigTemplate +
 		pricepredconfig.DefaultConfigTemplate +
 		httpconfig.DefaultConfigTemplate +
 		pfpconfig.DefaultConfigTemplate +
 		quantkitconfig.DefaultConfigTemplate +
 		veniceconfig.DefaultConfigTemplate +
 		veniceimgconfig.DefaultConfigTemplate
📝 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
customAppTemplate := serverconfig.DefaultConfigTemplate +
oracleconfig.DefaultConfigTemplate +
cosmosevmserverconfig.DefaultEVMConfigTemplate +
pricepredconfig.DefaultConfigTemplate +
httpconfig.DefaultConfigTemplate +
pfpconfig.DefaultConfigTemplate +
quantkitconfig.DefaultConfigTemplate +
veniceconfig.DefaultConfigTemplate +
veniceimgconfig.DefaultConfigTemplate
customAppTemplate := serverconfig.DefaultConfigTemplate +
oracleconfig.DefaultConfigTemplate +
cosmosevmserverconfig.DefaultEVMConfigTemplate +
cosmosevmserverconfig.DefaultJSONRPCConfigTemplate +
cosmosevmserverconfig.DefaultTLSConfigTemplate +
pricepredconfig.DefaultConfigTemplate +
httpconfig.DefaultConfigTemplate +
pfpconfig.DefaultConfigTemplate +
quantkitconfig.DefaultConfigTemplate +
veniceconfig.DefaultConfigTemplate +
veniceimgconfig.DefaultConfigTemplate
🤖 Prompt for AI Agents
In cmd/wardend/config/wardend_config.go around lines 175 to 184,
customAppTemplate concatenation is missing the JSON-RPC and TLS config
templates; update the concatenation to include the appropriate
DefaultConfigTemplate variables for the JSON-RPC and TLS packages (e.g.
jsonrpcconfig.DefaultConfigTemplate and tlsconfig.DefaultConfigTemplate) so the
app.toml will include those sections, and add the corresponding import entries
at the top of the file if they are not already imported.

Comment on lines 18 to 28
// Register registers a new task plugin with the given unique name.
func Register(name string, task Plugin) {
registry.rw.Lock()
defer registry.rw.Unlock()

if _, found := registry.tasks[name]; found {
panic("task already registered")
if _, found := registry.plugins[name]; found {
panic(fmt.Errorf("plugin %s registered twice", name))
}

registry.tasks[name] = task
registry.plugins[name] = task
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden Register: naming consistency + input validation

  • Rename param taskplugin for consistency.
  • Guard against empty name and nil plugin.
  • Use Sprintf (or a string) instead of creating an error only to panic it.
-// Register registers a new task plugin with the given unique name.
+// Register registers a new plugin with the given unique name.
-func Register(name string, task Plugin) {
+func Register(name string, plugin Plugin) {
   registry.rw.Lock()
   defer registry.rw.Unlock()
 
-  if _, found := registry.plugins[name]; found {
-    panic(fmt.Errorf("plugin %s registered twice", name))
-  }
-
-  registry.plugins[name] = task
+  if name == "" {
+    panic("plugin name cannot be empty")
+  }
+  if _, found := registry.plugins[name]; found {
+    panic(fmt.Sprintf("plugin %q registered twice", name))
+  }
+  if plugin == nil {
+    panic("plugin " + name + " is nil")
+  }
+  registry.plugins[name] = plugin
 }
📝 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
// Register registers a new task plugin with the given unique name.
func Register(name string, task Plugin) {
registry.rw.Lock()
defer registry.rw.Unlock()
if _, found := registry.tasks[name]; found {
panic("task already registered")
if _, found := registry.plugins[name]; found {
panic(fmt.Errorf("plugin %s registered twice", name))
}
registry.tasks[name] = task
registry.plugins[name] = task
}
// Register registers a new plugin with the given unique name.
func Register(name string, plugin Plugin) {
registry.rw.Lock()
defer registry.rw.Unlock()
if name == "" {
panic("plugin name cannot be empty")
}
if _, found := registry.plugins[name]; found {
panic(fmt.Sprintf("plugin %q registered twice", name))
}
if plugin == nil {
panic("plugin " + name + " is nil")
}
registry.plugins[name] = plugin
}
🤖 Prompt for AI Agents
In prophet/registry.go around lines 18 to 28, rename the parameter `task` to
`plugin` for naming consistency, add input validation to panic when `name` is
empty or `plugin` is nil (check before mutating registry), and replace
panic(fmt.Errorf(...)) with panic(fmt.Sprintf("plugin %s registered twice",
name)) or simply panic("...") to avoid creating an error only to panic it;
preserve the existing rw lock/unlock and registry assignment semantics.

Copy link
Contributor

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
warden/app/export.go (3)

65-71: Avoid fatal exit during genesis export; return an error.
Using log.Fatal here terminates the process abruptly. Return a wrapped error so callers can handle it.

-        _, err := sdk.ValAddressFromBech32(addr)
-        if err != nil {
-            log.Fatal(err)
-        }
+        if _, err := sdk.ValAddressFromBech32(addr); err != nil {
+            return fmt.Errorf("invalid jailed-allowlist validator address %q: %w", addr, err)
+        }

89-98: Replace panics and unchecked returns with proper error handling in rewards/delegation re-init.
Panics during export are undesirable; also ignore-errors can mask state issues.

- for _, delegation := range dels {
-     valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
-     if err != nil {
-         panic(err)
-     }
-     delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
-     _, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
- }
+ for _, delegation := range dels {
+     valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
+     if err != nil {
+         return fmt.Errorf("parse validator addr %q: %w", delegation.ValidatorAddress, err)
+     }
+     delAddr, err := sdk.AccAddressFromBech32(delegation.DelegatorAddress)
+     if err != nil {
+         return fmt.Errorf("parse delegator addr %q: %w", delegation.DelegatorAddress, err)
+     }
+     if _, err := app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr); err != nil {
+         return fmt.Errorf("withdraw delegation rewards (%s -> %s): %w", delAddr, valAddr, err)
+     }
+ }
@@
-     valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
-     if err != nil {
-         panic(err)
-     }
-     delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress)
+     valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
+     if err != nil {
+         return fmt.Errorf("parse validator addr %q: %w", del.ValidatorAddress, err)
+     }
+     delAddr, err := sdk.AccAddressFromBech32(del.DelegatorAddress)
+     if err != nil {
+         return fmt.Errorf("parse delegator addr %q: %w", del.DelegatorAddress, err)
+     }
@@
-     if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
-         // never called as BeforeDelegationCreated always returns nil
-         panic(fmt.Errorf("error while incrementing period: %w", err))
-     }
+     if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
+         return fmt.Errorf("incrementing period: %w", err)
+     }
@@
-     if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
-         // never called as AfterDelegationModified always returns nil
-         panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
-     }
+     if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
+         return fmt.Errorf("creating delegation period record: %w", err)
+     }

Also applies to: 100-118


230-233: Avoid log.Fatal on ApplyAndReturnValidatorSetUpdates; return error.
Terminate-without-context hurts UX and automation.

- if err != nil {
-     log.Fatal(err)
- }
+ if err != nil {
+     return fmt.Errorf("apply validator set updates: %w", err)
+ }
♻️ Duplicate comments (20)
warden/x/sched/keeper/abci.go (1)

36-38: Don't hard-fail on unexpected injected-tx position; warn and proceed.

Strict equality to position 2 is brittle and can cause avoidable block rejections.

-	// expect the tx to be at the block position [schedTxTriggerPosition]
-	if position != schedTxTriggerPosition {
-		ctx.Logger().Error("found x/sched injected transaction at the wrong position in block", "expected", schedTxTriggerPosition, "found", position)
-
-		return &cometabci.ResponseProcessProposal{
-			Status: cometabci.ResponseProcessProposal_REJECT,
-		}, nil
-	}
+	// prefer the tx at [schedTxTriggerPosition], but don't make it fatal
+	if position != schedTxTriggerPosition {
+		ctx.Logger().Warn("x/sched injected transaction found at unexpected position; proceeding",
+			"expected", schedTxTriggerPosition, "found", position)
+	}

Also applies to: 94-101

warden/app/oracle.go (1)

109-119: Oracle client start panic is acceptable here

Starting the oracle client in a goroutine and panicking on misconfiguration aligns with prior guidance for this file.

Using retrieved learnings noted for oracle.go.

go.mod (1)

380-381: Drop non-canonical YAML module

Use gopkg.in/yaml.v2 only; remove go.yaml.in/yaml/v2 to avoid supply-chain confusion.

-	go.yaml.in/yaml/v2 v2.4.2 // indirect
justfile (1)

33-35: Update wasmvm checksums for v3.0.2 to match upstream artifacts

 wasmvm_version := `go list -m -f '{{ .Version }}' github.com/CosmWasm/wasmvm/v3`
-wasmvm_amd64_checksum := 'f2fab51ec2b393ffe6912ff31497c6f8a14c04ad2490a1a3a9fa11a37cb4ce33'
-wasmvm_arm64_checksum := 'f82e608707be7b193a78f5a7f7c6163b633a94ca6a0017a7fa3501cc8e9fbff5'
+wasmvm_amd64_checksum := 'b249396cf884b207f49f46bcf5b8d1fd73b8618eebbe35afb8bf60a8bb24f30a'
+wasmvm_arm64_checksum := 'b9df5056ab9f61d3f9b944060b44e893d7ade7dad6ff134b36276be0f9a4185a'

Retain or add a CI check to automatically verify these checksums on release.

warden/app/export.go (2)

225-228: Return iterator Close error instead of swallowing it.
Currently logs and returns nil, hiding the failure.

 if err := iter.Close(); err != nil {
     app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
-    return nil
+    return fmt.Errorf("closing validator reverse iterator: %w", err)
 }

130-156: IterateValidators: closure errors are still lost; capture and return them.
Returning true stops iteration but drops the underlying error.

- err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
+ var iterErr error
+ err = app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
@@
-     scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
-     if err != nil {
-         return true
-     }
+     scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, sdk.ValAddress(val.GetOperator()))
+     if err != nil { iterErr = err; return true }
@@
-     feePool, err := app.DistrKeeper.FeePool.Get(ctx)
-     if err != nil {
-         return true
-     }
+     feePool, err := app.DistrKeeper.FeePool.Get(ctx)
+     if err != nil { iterErr = err; return true }
@@
-     err = app.DistrKeeper.FeePool.Set(ctx, feePool)
-     if err != nil {
-         return true
-     }
+     if err = app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil { iterErr = err; return true }
@@
-     err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator()))
-     // this lets us stop in case there's an error
-     return err != nil
+     if err = app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, sdk.ValAddress(val.GetOperator())); err != nil {
+         iterErr = err
+         return true
+     }
+     return false
 })
 if err != nil {
     return err
 }
+if iterErr != nil {
+    return iterErr
+}
tests/slinky/go.mod (1)

22-26: Bump cosmos-sdk to a patched release (v0.53.4).
v0.50.11 has multiple HIGH advisories; align test module with patched series.

-require (
-    github.com/cosmos/cosmos-sdk v0.50.11
+require (
+    github.com/cosmos/cosmos-sdk v0.53.4
warden/app/ante/ante.go (1)

23-46: Route based on any supported extension option, not only the first.
Some txs carry multiple options; scan all and pick the first recognized.

-        txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx)
-        if ok {
+        if txWithExtensions, ok := tx.(authante.HasExtensionOptionsTx); ok {
             opts := txWithExtensions.GetExtensionOptions()
             if len(opts) > 0 {
-                switch typeURL := opts[0].GetTypeUrl(); typeURL {
-                case "/" + proto.MessageName(&schedv1beta1.ExtensionOptionsCallbacks{}):
-                    // x/sched evm transaction it's a system transaction bypasses normal checks
-                    anteHandler = newSchedAnteHandler(options)
-                case "/cosmos.evm.vm.v1.ExtensionOptionsEthereumTx":
-                    // handle as *evmtypes.MsgEthereumTx
-                    anteHandler = newMonoEVMAnteHandler(options)
-                case "/cosmos.evm.types.v1.ExtensionOptionDynamicFeeTx":
-                    // cosmos-sdk tx with dynamic fee extension
-                    anteHandler = newCosmosAnteHandler(options)
-                default:
-                    return ctx, errorsmod.Wrapf(
-                        errortypes.ErrUnknownExtensionOptions,
-                        "rejecting tx with unsupported extension option: %s", typeURL,
-                    )
-                }
-
-                return anteHandler(ctx, tx, sim)
+                var matched bool
+                for _, opt := range opts {
+                    switch typeURL := opt.GetTypeUrl(); typeURL {
+                    case "/" + proto.MessageName(&schedv1beta1.ExtensionOptionsCallbacks{}):
+                        anteHandler = newSchedAnteHandler(options)
+                        matched = true
+                    case "/cosmos.evm.vm.v1.ExtensionOptionsEthereumTx":
+                        anteHandler = newMonoEVMAnteHandler(options)
+                        matched = true
+                    case "/cosmos.evm.types.v1.ExtensionOptionDynamicFeeTx":
+                        anteHandler = newCosmosAnteHandler(options)
+                        matched = true
+                    }
+                    if matched {
+                        return anteHandler(ctx, tx, sim)
+                    }
+                }
+                return ctx, errorsmod.Wrapf(
+                    errortypes.ErrUnknownExtensionOptions,
+                    "rejecting tx with unsupported extension options: %v", opts,
+                )
             }
         }
cmd/wardend/cmd/root.go (1)

62-70: Build tempApp with real EVM chain ID to avoid EIP-712/config mismatches.
Resolve from home (fallback to default) before constructing tempApp.

-    noOpEvmAppOptions := func(_ uint64) error { return nil }
-    tempApp := app.NewApp(
+    noOpEvmAppOptions := func(_ uint64) error { return nil }
+    // try to match CLI/home chain ID for correct EIP-712 config in temp app
+    evmForTemp := wardendconfig.EVMChainID
+    if home := wardendconfig.MustGetDefaultNodeHome(); home != "" {
+        if cid, err := wardendconfig.GetChainIDFromHome(home); err == nil {
+            if parsed, err := parseEVMChainID(cid); err == nil {
+                evmForTemp = parsed
+            }
+        }
+    }
+    tempApp := app.NewApp(
         log.NewNopLogger(),
         dbm.NewMemDB(),
         nil,
         true,
         simtestutil.NewAppOptionsWithFlagHome(temp),
-        wardendconfig.EVMChainID,
+        evmForTemp,
         noOpEvmAppOptions,
     )
cmd/wardend/cmd/testnet.go (8)

236-239: Validate validator count early to fail fast and avoid resource exhaustion

Add a sane bound check (e.g., 1..100) before allocating slices and creating dirs.

 func initTestnetFiles(
@@
 ) error {
-	if args.chainID == "" {
+	if args.numValidators < 1 || args.numValidators > 100 {
+		return fmt.Errorf("number of validators must be between 1 and 100, got %d", args.numValidators)
+	}
+	if args.chainID == "" {
 		args.chainID = "local-4221"
 	}

280-299: Fix compile error: cannot range over int

Replace invalid range over int with a classic for loop.

-	for i := range args.numValidators {
+	for i := 0; i < args.numValidators; i++ {

317-319: Use loopback for single-host peers (0.0.0.0 is not dialable)

Peers cannot dial 0.0.0.0; use 127.0.0.1 in single-machine mode.

-		if args.singleMachine {
-			ip = "0.0.0.0"
+		if args.singleMachine {
+			ip = "127.0.0.1"

418-419: Handle app.toml write errors

Don’t ignore WriteConfigFile errors; surface them.

-		srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg)
+		if err := srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), evmCfg); err != nil {
+			return err
+		}

481-485: Fix compile error: cannot range over int (initGenFiles)

Use an indexed loop or iterate over genFiles.

-	for i := range numValidators {
+	for i := 0; i < numValidators; i++ {
 		if err := genDoc.SaveAs(genFiles[i]); err != nil {
 			return err
 		}
 	}

501-506: Fix compile error: cannot range over int (collectGenFiles)

Same issue in collectGenFiles.

-	for i := range numValidators {
+	for i := 0; i < numValidators; i++ {
 		if singleMachine {
 			portOffset := i
 			nodeConfig.RPC.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", rpcPortStart+portOffset)
 			nodeConfig.P2P.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%d", p2pPortStart+portOffset)
 		}

534-540: Persist CometBFT config (config.toml) per node

You mutate nodeConfig in-memory but never write it; persist to config/config.toml.

 		// overwrite each validator's genesis file to have a canonical genesis time
 		if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
 			return err
 		}
+		// persist cometbft config.toml
+		if err := cmtconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), nodeConfig); err != nil {
+			return err
+		}

558-569: Fix compile error and handle IP overflow/underflow in calculateIP

Replace invalid loop and guard against crossing subnets.

 func calculateIP(ip string, i int) (string, error) {
 	ipv4 := net.ParseIP(ip).To4()
 	if ipv4 == nil {
 		return "", fmt.Errorf("%v: non ipv4 address", ip)
 	}
-
-	for range i {
-		ipv4[3]++
-	}
-
-	return ipv4.String(), nil
+	orig := (uint32(ipv4[0]) << 24) | (uint32(ipv4[1]) << 16) | (uint32(ipv4[2]) << 8) | uint32(ipv4[3])
+	newIP := uint32(int64(orig) + int64(i))
+	// stay within the same /24
+	if (newIP>>8) != (orig>>8) {
+		return "", fmt.Errorf("IP address overflows /24: %s + %d", ip, i)
+	}
+	return fmt.Sprintf("%d.%d.%d.%d", byte(newIP>>24), byte(newIP>>16), byte(newIP>>8), byte(newIP)), nil
 }
warden/app/app.go (3)

914-929: Mempool captures nil/old AnteHandler; move initialization after SetAnteHandler

Initialize EVMMempool only after ante/post handlers are set; otherwise ante checks are bypassed.

-	// mempool initialization (EVM priority nonce mempool)
-	if evmtypes.GetChainConfig() != nil {
-		// TODO: Get the actual block gas limit from consensus parameters
-		mempoolConfig := &evmmempool.EVMMempoolConfig{
-			AnteHandler:   app.GetAnteHandler(),
-			BlockGasLimit: 100_000_000,
-		}
-
-		evmMempool := evmmempool.NewExperimentalEVMMempool(app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig)
-		app.EVMMempool = evmMempool
-
-		app.SetMempool(evmMempool)
-		checkTxHandler := evmmempool.NewCheckTxHandler(evmMempool)
-		app.SetCheckTxHandler(checkTxHandler)
-	}

Then add the block right after post handler setup (see next comment).


975-1002: Insert mempool initialization after ante/post handlers

Ensure the mempool uses the final AnteHandler.

 	app.setPostHandler()
 
+	// mempool initialization (EVM priority nonce mempool)
+	if evmtypes.GetChainConfig() != nil {
+		// TODO: derive from consensus params
+		mempoolConfig := &evmmempool.EVMMempoolConfig{
+			AnteHandler:   app.GetAnteHandler(), // now set
+			BlockGasLimit: 100_000_000,
+		}
+		evmMempool := evmmempool.NewExperimentalEVMMempool(
+			app.CreateQueryContext, logger, app.EVMKeeper, app.FeeMarketKeeper, app.txConfig, app.clientCtx, mempoolConfig,
+		)
+		app.EVMMempool = evmMempool
+		app.SetMempool(evmMempool)
+		app.SetCheckTxHandler(evmmempool.NewCheckTxHandler(evmMempool))
+	}

1049-1060: InitChainer unmarshals app state into wrong type; breaks genesis

Unmarshal into map[string]json.RawMessage and pass that to InitGenesis.

 func (app *App) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
-	var genesisState cosmosevmtypes.GenesisState
+	var genesisState map[string]json.RawMessage
 	if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
 		panic(err)
 	}
 
 	if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
 		panic(err)
 	}
 
-	return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
+	return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
 }
🧹 Nitpick comments (15)
warden/x/sched/keeper/abci.go (2)

21-21: Alias geth crypto to avoid confusion with std crypto.

Avoid importing go-ethereum as plain "crypto"; use an explicit alias.

-	"github.com/ethereum/go-ethereum/crypto"
+	gethcrypto "github.com/ethereum/go-ethereum/crypto"
@@
-	tx.From = crypto.PubkeyToAddress(privkey.PublicKey).Bytes()
+	tx.From = gethcrypto.PubkeyToAddress(privkey.PublicKey).Bytes()

Also applies to: 169-169


67-73: Detect the extension option anywhere, not only at index 0.

More robust to scan all options; preserves current single-tx invariant.

-			if hasExtOptsTx, ok := tx.(authante.HasExtensionOptionsTx); ok {
-				opts := hasExtOptsTx.GetExtensionOptions()
-
-				typeURL := "/" + proto.MessageName(&types.ExtensionOptionsCallbacks{})
-				if len(opts) > 0 && opts[0].TypeUrl == typeURL {
+			if hasExtOptsTx, ok := tx.(authante.HasExtensionOptionsTx); ok {
+				opts := hasExtOptsTx.GetExtensionOptions()
+				typeURL := "/" + proto.MessageName(&types.ExtensionOptionsCallbacks{})
+				foundHere := false
+				for _, o := range opts {
+					if o.TypeUrl == typeURL {
+						foundHere = true
+						break
+					}
+				}
+				if foundHere {
 					if found {
 						// found a second transaction with the extensions
 						ctx.Logger().Error("invalid proposal: only one transaction per block can have the extension " + typeURL)
warden/x/act/module/simulation.go (6)

52-54: Prefer nil slice for ProposalMsgs; align with ProposalContents and avoid alloc

Returning nil is idiomatic for “no proposals” and matches ProposalContents’ nil. Simulation code ranges over both equally.

 func (am AppModule) ProposalMsgs(simState module.SimulationState) []simtypes.WeightedProposalMsg {
-	return []simtypes.WeightedProposalMsg{}
+	return nil
 }

44-49: Simplify WeightedOperations: return nil directly

No operations are produced; skip the zero-length allocation.

 func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
-	operations := make([]simtypes.WeightedOperation, 0)
-
-	return operations
+	return nil
 }

25-28: Remove unused accs construction

accs is built but never used; drop to reduce noise.

-	accs := make([]string, len(simState.Accounts))
-	for i, acc := range simState.Accounts {
-		accs[i] = acc.Address.String()
-	}

15-21: Delete scaffold “avoid unused import” block and corresponding unused imports

These placeholders and imports are no longer needed.

-import (
-	"math/rand"
-
-	sdk "github.com/cosmos/cosmos-sdk/types"
-	"github.com/cosmos/cosmos-sdk/types/module"
-	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
-	"github.com/cosmos/cosmos-sdk/x/simulation"
-
-	actsimulation "github.com/warden-protocol/wardenprotocol/warden/x/act/simulation"
-	types "github.com/warden-protocol/wardenprotocol/warden/x/act/types/v1beta1"
-)
+import (
+	"github.com/cosmos/cosmos-sdk/types/module"
+	simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
+
+	types "github.com/warden-protocol/wardenprotocol/warden/x/act/types/v1beta1"
+)
-var (
-	_ = actsimulation.FindAccount
-	_ = rand.Rand{}
-	_ = sdk.AccAddress{}
-	_ = simulation.MsgEntryKind
-)

44-46: Fix grammar in comment

Minor doc cleanup.

-// WeightedOperations returns the all the gov module operations with their respective weights.
+// WeightedOperations returns all module operations with their respective weights.

39-42: Remove deprecated ProposalContents method
The project is on Cosmos SDK v0.53.4, where AppModule no longer defines ProposalContents (it was superseded by ProposalMsgs in v0.50+). You can safely delete the no-op ProposalContents implementation in warden/x/act/module/simulation.go (and likewise in the async and sched modules) to shrink your surface.

warden/app/oracle.go (1)

259-265: Improve panic diagnostics in PreBlocker

Log panic details and height before re-panicking to aid debugging; avoid only printing the stack.

-        defer func() {
-            if err := recover(); err != nil {
-                debug.PrintStack()
-                panic(err)
-            }
-        }()
+        defer func() {
+            if r := recover(); r != nil {
+                ctx.Logger().Error("panic in PreBlocker", "panic", r, "height", ctx.BlockHeight(), "stack", string(debug.Stack()))
+                panic(r)
+            }
+        }()
localnet.just (1)

4-5: Remove unused variables

val2 and val2_mnemonic are defined but not used. Drop them to reduce drift.

- val2 := "warden194j3dx4t7u80765k2puu3082vc39yfqnvrxqu7"
- val2_mnemonic := "door blast other element embark noodle maple agent drastic bunker swarm logic wide deputy exhibit bicycle evil exile air other mesh foot tackle spot"
warden/app/export.go (1)

203-223: Remove unused counter or use it to set intra-tx counters.
counter is incremented but never used; dead code.

- counter := int16(0)
@@
-     counter++

Or, if intended, assign to the validator’s intra-tx field and persist.

warden/app/ante/ante.go (2)

17-21: Validate options when constructing the ante handler.
Catch misconfiguration early.

-func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
+func NewAnteHandler(options HandlerOptions) sdk.AnteHandler {
+    if err := options.Validate(); err != nil {
+        // choose panic or prebuilt error-returning handler; panic is consistent with SDK builder patterns
+        panic(err)
+    }

48-56: Simplify: the type switch is redundant.
tx is already sdk.Tx by signature; directly route to Cosmos ante.

-        switch tx.(type) {
-        case sdk.Tx:
-            anteHandler = newCosmosAnteHandler(options)
-        default:
-            return ctx, errorsmod.Wrapf(errortypes.ErrUnknownRequest, "invalid transaction type: %T", tx)
-        }
+        anteHandler = newCosmosAnteHandler(options)
cmd/wardend/cmd/root.go (1)

153-155: Don’t ignore ReadFromClientConfig error (and avoid double-read).
You read client config in PreRunE; this second call ignores errors. Either remove it or handle the error.

-    initClientCtx, _ = clientcfg.ReadFromClientConfig(initClientCtx)
+    // already read in PersistentPreRunE; remove or handle error if needed
+    // initClientCtx, err = clientcfg.ReadFromClientConfig(initClientCtx)
+    // if err != nil { return nil }
cmd/wardend/cmd/testnet.go (1)

606-610: Fix typo in user-facing error message ("testnests" → "testnets")

Minor but user-visible.

-			"testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
+			"testnets directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ae80e60 and 5f3e20e.

⛔ Files ignored due to path filters (65)
  • go.sum is excluded by !**/*.sum
  • tests/slinky/go.sum is excluded by !**/*.sum
  • tests/testdata/snapshot-base/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-38d79e1aae59e234ad6a60fd92896082bf41c64e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/gentx/gentx-6945f3e30b02b9e34673acc22a18c3688ed57a19.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/80bd83f2b3f9f098fe4cd54891cdc86595a6d479.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-base/keyring-test/c8af84b4401237ec5048090f46c6327332be71cf.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-32688592d17c81e774a966370c9366b35845614e.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/gentx/gentx-c1add3510774b379cfe92d361f1aa521dc9c9fc6.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/2ff01d371641069bd86371069b21a11f69383a33.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/32a224cecfe0a0660c93073fbcb6afebdbffa5ab.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/461cb598a46fcc43bef9044774afd0c4d66b54c9.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/63675504137926347258e5687f45cbf2b1f87b56.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/7daa0db7bba477374f17bf0cc2fa96d344bb8258.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/f114af4db343f425c8633979922e6f668f47dbc1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/val.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-keychain/keyring-test/writer.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-2093ee4e76ca7a6460e5b92915bcbe61c8137495.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/gentx/gentx-a587c87739afa2c555eadf8b225cf7f389e31fa1.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/056d037ac7ae938ae179115f64a160d6976fc501.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/0fbc33e8e29268d962ebf0d9db19bf2715aee1d1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/1856bab8f08b38ece497419342ec2ff2ba79b884.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/356e83fe984f8cff0e34868a9e239f7623d77644.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/460023f64738ff322a330aaadabe989057e72a66.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/640d841942f70598dea2ecc203be2efe0754fe37.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/6b8720d45650a5f4718bb85c0b3c713be7dabf83.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/b730c0872fcb7106b5ab7fbaca574c4582e2a287.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bddff3c30fabae236823a53b91505b5f445f973e.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/befc8528482269aef5c988845d0e365e1de01458.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bf4bc4afeee16236f73202e7e93aafdab879c304.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/charlie.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/eb45ceb51c38527501b095031fa54c1b2911f981.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/erin.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-many-users/keyring-test/frank.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/app.toml.tmpl is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/genesis.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-2601681988711cb256c1068a6ae0fe35755fdb26.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/gentx/gentx-dbafff433fe3c3711b6ade63130895b84e777eb3.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/node_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/config/priv_validator_key.json is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/16159a91f2b78293bf6e1d0525433a6ad9fa7807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/3005241c8fb90192342c9d58b86b434f8ba1d807.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/4596f61417e0c4fae43c201a9a0cd06e3b403ffd.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/79fce8f9a2fd6d67aba6a83f8d2b499c6b9a4eb1.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/alice.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/b26f6dc33e0a93a55c3caa3dbf6e58155d6ca55f.address is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/bob.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/dave.info is excluded by !tests/testdata/**
  • tests/testdata/snapshot-precompiles/keyring-test/e0ace9b0c67b860bd22cffcbb08591f3cc3b6e42.address is excluded by !tests/testdata/**
📒 Files selected for processing (79)
  • CHANGELOG.md (1 hunks)
  • cmd/wardend/cmd/commands.go (0 hunks)
  • cmd/wardend/cmd/config.go (0 hunks)
  • cmd/wardend/cmd/root.go (1 hunks)
  • cmd/wardend/cmd/testnet.go (1 hunks)
  • cmd/wardend/cmd/wait.go (0 hunks)
  • cmd/wardend/config/chain_id.go (1 hunks)
  • cmd/wardend/config/config.go (2 hunks)
  • cmd/wardend/config/evm_app_options.go (1 hunks)
  • cmd/wardend/config/wardend_config.go (1 hunks)
  • cmd/wardend/main.go (1 hunks)
  • go.mod (9 hunks)
  • justfile (1 hunks)
  • localnet.just (3 hunks)
  • precompiles/act/act.go (2 hunks)
  • precompiles/async/async.go (2 hunks)
  • precompiles/json/json.go (1 hunks)
  • precompiles/precompiles.go (6 hunks)
  • precompiles/sched/sched.go (2 hunks)
  • precompiles/slinky/slinky.go (0 hunks)
  • precompiles/warden/warden.go (6 hunks)
  • prophet/registry.go (1 hunks)
  • proto/warden/act/v1beta1/query.proto (0 hunks)
  • tests/framework/exec/warden_eth.go (3 hunks)
  • tests/framework/snapshot/snapshots.go (1 hunks)
  • tests/slinky/go.mod (10 hunks)
  • tests/slinky/slinky_test.go (3 hunks)
  • warden/app/ante.go (0 hunks)
  • warden/app/ante/ante.go (1 hunks)
  • warden/app/ante/cosmos.go (1 hunks)
  • warden/app/ante/evm_handler.go (1 hunks)
  • warden/app/ante/options.go (1 hunks)
  • warden/app/ante/sched_handler.go (1 hunks)
  • warden/app/app.go (4 hunks)
  • warden/app/app_config.go (0 hunks)
  • warden/app/config.go (0 hunks)
  • warden/app/export.go (7 hunks)
  • warden/app/genesis.go (0 hunks)
  • warden/app/legacy.go (0 hunks)
  • warden/app/oracle.go (4 hunks)
  • warden/app/precompiles.go (6 hunks)
  • warden/app/sim_bench_test.go (0 hunks)
  • warden/app/sim_test.go (0 hunks)
  • warden/app/upgrades.go (1 hunks)
  • warden/app/vemanager/vemanager.go (2 hunks)
  • warden/testutil/network/network.go (0 hunks)
  • warden/testutil/nullify/nullify.go (0 hunks)
  • warden/testutil/sample/sample.go (0 hunks)
  • warden/x/act/module/autocli.go (0 hunks)
  • warden/x/act/module/genesis.go (0 hunks)
  • warden/x/act/module/genesis_test.go (0 hunks)
  • warden/x/act/module/module.go (0 hunks)
  • warden/x/act/module/simulation.go (1 hunks)
  • warden/x/act/types/v1beta1/codec.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis.go (0 hunks)
  • warden/x/act/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/async/module/genesis.go (0 hunks)
  • warden/x/async/module/genesis_test.go (0 hunks)
  • warden/x/async/module/module.go (0 hunks)
  • warden/x/async/module/simulation.go (1 hunks)
  • warden/x/async/types/v1beta1/genesis.go (0 hunks)
  • warden/x/async/types/v1beta1/keys.go (1 hunks)
  • warden/x/sched/keeper/abci.go (3 hunks)
  • warden/x/sched/module/autocli.go (0 hunks)
  • warden/x/sched/module/genesis.go (0 hunks)
  • warden/x/sched/module/genesis_test.go (0 hunks)
  • warden/x/sched/module/module.go (0 hunks)
  • warden/x/sched/module/simulation.go (1 hunks)
  • warden/x/sched/types/v1beta1/codec.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis.go (0 hunks)
  • warden/x/sched/types/v1beta1/genesis_test.go (1 hunks)
  • warden/x/warden/module/autocli.go (0 hunks)
  • warden/x/warden/module/genesis.go (0 hunks)
  • warden/x/warden/module/genesis_test.go (0 hunks)
  • warden/x/warden/module/module.go (0 hunks)
  • warden/x/warden/module/simulation.go (1 hunks)
  • warden/x/warden/types/v1beta3/codec.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis.go (0 hunks)
  • warden/x/warden/types/v1beta3/genesis_test.go (1 hunks)
💤 Files with no reviewable changes (37)
  • warden/x/async/module/genesis.go
  • proto/warden/act/v1beta1/query.proto
  • warden/x/warden/module/autocli.go
  • warden/x/async/types/v1beta1/genesis.go
  • warden/app/sim_bench_test.go
  • warden/x/sched/module/autocli.go
  • warden/x/sched/module/genesis.go
  • warden/x/act/module/genesis.go
  • warden/testutil/nullify/nullify.go
  • warden/app/ante.go
  • warden/x/warden/types/v1beta3/codec.go
  • warden/x/sched/types/v1beta1/genesis.go
  • warden/x/warden/module/genesis_test.go
  • warden/x/act/module/autocli.go
  • precompiles/slinky/slinky.go
  • warden/app/genesis.go
  • warden/x/act/types/v1beta1/genesis.go
  • warden/x/sched/module/genesis_test.go
  • cmd/wardend/cmd/config.go
  • warden/x/warden/types/v1beta3/genesis.go
  • warden/app/config.go
  • warden/x/async/module/module.go
  • warden/x/sched/types/v1beta1/codec.go
  • warden/x/act/types/v1beta1/codec.go
  • warden/app/app_config.go
  • warden/x/act/module/genesis_test.go
  • warden/x/async/module/genesis_test.go
  • warden/x/warden/module/genesis.go
  • cmd/wardend/cmd/wait.go
  • warden/app/legacy.go
  • warden/testutil/network/network.go
  • cmd/wardend/cmd/commands.go
  • warden/app/sim_test.go
  • warden/testutil/sample/sample.go
  • warden/x/act/module/module.go
  • warden/x/warden/module/module.go
  • warden/x/sched/module/module.go
🚧 Files skipped from review as they are similar to previous changes (28)
  • warden/x/async/types/v1beta1/keys.go
  • warden/app/ante/evm_handler.go
  • warden/x/sched/module/simulation.go
  • tests/framework/exec/warden_eth.go
  • warden/app/ante/cosmos.go
  • tests/framework/snapshot/snapshots.go
  • warden/x/warden/types/v1beta3/genesis_test.go
  • cmd/wardend/config/config.go
  • cmd/wardend/config/chain_id.go
  • precompiles/async/async.go
  • cmd/wardend/config/wardend_config.go
  • warden/app/upgrades.go
  • warden/x/sched/types/v1beta1/genesis_test.go
  • warden/x/async/module/simulation.go
  • precompiles/sched/sched.go
  • warden/x/warden/module/simulation.go
  • warden/app/vemanager/vemanager.go
  • warden/app/ante/sched_handler.go
  • warden/app/precompiles.go
  • prophet/registry.go
  • cmd/wardend/config/evm_app_options.go
  • tests/slinky/slinky_test.go
  • cmd/wardend/main.go
  • precompiles/act/act.go
  • warden/x/act/types/v1beta1/genesis_test.go
  • precompiles/json/json.go
  • precompiles/warden/warden.go
  • precompiles/precompiles.go
🧰 Additional context used
📓 Path-based instructions (1)
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness"

Files:

  • CHANGELOG.md
🧠 Learnings (4)
📚 Learning: 2024-11-02T10:21:03.096Z
Learnt from: backsapc
PR: warden-protocol/wardenprotocol#975
File: warden/app/app.go:562-562
Timestamp: 2024-11-02T10:21:03.096Z
Learning: In `warden/app/app.go`, suggestions to handle errors from `ParamsKeeper.GetSubspace()` may be considered out of scope.

Applied to files:

  • cmd/wardend/cmd/testnet.go
📚 Learning: 2024-06-10T19:20:04.350Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#0
File: :0-0
Timestamp: 2024-06-10T19:20:04.350Z
Learning: Pitasi has implemented error handling in the `Expand` method of `warden/x/warden/keeper/shield.go`, replacing `panic` with error returns.

Applied to files:

  • cmd/wardend/cmd/root.go
📚 Learning: 2025-02-06T08:48:57.285Z
Learnt from: mn13
PR: warden-protocol/wardenprotocol#1216
File: warden/x/async/keeper/abci.go:212-216
Timestamp: 2025-02-06T08:48:57.285Z
Learning: In the collections package from Cosmos SDK, calling Keys() on an iterator fully consumes and closes the iterator, making an explicit Close() call unnecessary.

Applied to files:

  • warden/app/export.go
📚 Learning: 2024-11-21T11:35:35.678Z
Learnt from: Pitasi
PR: warden-protocol/wardenprotocol#1095
File: warden/app/oracle.go:0-0
Timestamp: 2024-11-21T11:35:35.678Z
Learning: In the Go file `warden/app/oracle.go`, it is acceptable to panic inside the goroutine that starts the oracle client, because an error here indicates a misconfiguration (e.g., the address was misconfigured), and the application should exit.

Applied to files:

  • warden/app/oracle.go
🧬 Code graph analysis (5)
warden/app/ante/ante.go (1)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
cmd/wardend/cmd/testnet.go (2)
cmd/wardend/config/config.go (1)
  • EVMChainID (30-30)
cmd/wardend/config/evm_app_options.go (1)
  • EvmAppOptions (25-44)
cmd/wardend/cmd/root.go (9)
warden/app/app.go (2)
  • NewApp (257-1025)
  • App (184-255)
cmd/wardend/config/config.go (2)
  • EVMChainID (30-30)
  • BaseDenom (26-26)
cmd/wardend/config/wardend_config.go (2)
  • MustGetDefaultNodeHome (34-41)
  • InitAppConfig (122-186)
cmd/wardend/config/evm_app_options.go (1)
  • EvmAppOptions (25-44)
cmd/wardend/cmd/gen-keychains.go (1)
  • AddGenesisKeychainCmd (14-74)
cmd/wardend/cmd/gen-plugin.go (1)
  • AddGenesisPluginCmd (15-61)
cmd/wardend/cmd/gen-slinky-markets.go (1)
  • AddGenesisSlinkyMarketsCmd (15-74)
cmd/wardend/cmd/gen-spaces.go (1)
  • AddGenesisSpaceCmd (14-60)
cmd/wardend/config/chain_id.go (1)
  • GetChainIDFromHome (12-29)
warden/app/export.go (1)
warden/app/app.go (1)
  • App (184-255)
warden/app/app.go (16)
warden/x/act/keeper/keeper.go (2)
  • Keeper (21-38)
  • NewKeeper (48-91)
warden/x/async/keeper/keeper.go (2)
  • Keeper (34-61)
  • NewKeeper (79-145)
warden/x/warden/keeper/keeper.go (2)
  • Keeper (18-45)
  • NewKeeper (62-122)
warden/x/sched/keeper/keeper.go (2)
  • Keeper (22-34)
  • NewKeeper (44-76)
prophet/prophet.go (2)
  • P (22-31)
  • New (34-51)
prophet/plugins/pfp/pfp.go (2)
  • New (25-40)
  • Plugin (20-23)
prophet/plugins/veniceimg/veniceimg.go (2)
  • New (21-30)
  • Plugin (17-19)
prophet/plugins/quantkit/quantkit.go (2)
  • New (18-30)
  • Plugin (13-15)
prophet/plugins/venice/venice.go (2)
  • New (15-24)
  • Plugin (11-13)
warden/app/genesis.go (3)
  • GenesisState (19-19)
  • NewEVMGenesisState (22-27)
  • NewErc20GenesisState (33-39)
warden/app/ante/options.go (1)
  • HandlerOptions (15-23)
warden/app/ante/ante.go (1)
  • NewAnteHandler (17-58)
prophet/registry.go (1)
  • Register (19-28)
prophet/plugins/http/http.go (2)
  • Plugin (25-30)
  • NewPlugin (33-51)
prophet/plugins/echo/echo.go (1)
  • Plugin (13-13)
prophet/plugins/pricepred/pricepred.go (1)
  • NewPricePredictorSolidity (22-30)
🪛 GitHub Check: lint
warden/app/oracle.go

[failure] 316-316:
File is not properly formatted (gci)

🪛 GitHub Actions: Release Faucet development image
warden/app/oracle.go

[error] 316-316: golangci-lint: File is not properly formatted (gci). Command: golangci-lint run --timeout=10m ./warden/... ./cmd/wardend/... ./cmd/faucet/...

🪛 GitHub Actions: Release Wardend development image
warden/app/oracle.go

[error] 316-316: golangci-lint: File is not properly formatted (gci). Step failed: golangci-lint run --timeout=10m ./warden/... ./cmd/wardend/... ./cmd/faucet/... ./prophet/... ./precompiles/...

🪛 OSV Scanner (2.1.0)
tests/slinky/go.mod

[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Denial of service in message decoding in github.com/btcsuite/btcd

(GO-2022-1098)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Consensus failures in github.com/btcsuite/btcd

(GO-2024-2818)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: Consensus failure in github.com/btcsuite/btcd

(GO-2024-3189)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd did not correctly re-implement Bitcoin Core's "FindAndDelete()" functionality

(GHSA-27vh-h6mc-q6g8)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd mishandles witness size checking

(GHSA-2chg-86hq-7w38)


[CRITICAL] 45-45: github.com/btcsuite/btcd 0.22.1: btcd susceptible to consensus failures

(GHSA-3jgf-r68h-xfqm)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: The x/crisis package does not cause chain halt in github.com/cosmos/cosmos-sdk

(GO-2023-1821)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: The x/crisis package does not charge ConstantFee in github.com/cosmos/cosmos-sdk

(GO-2023-1881)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: Groups module can halt chain when handling a malicious proposal in github.com/cosmos/cosmos-sdk

(GO-2025-3476)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK can halt when erroring in EndBlocker in github.com/cosmos/cosmos-sdk/

(GO-2025-3516)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Integer Overflow vulnerability in its Validator Rewards pool can cause a chain halt in github.com/cosmos/cosmos-sdk

(GO-2025-3803)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: x/group can halt when erroring in EndBlocker

(GHSA-47ww-ff84-4jrg)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK's Integer Overflow vulnerability in its Validator Rewards pool can cause a chain halt

(GHSA-p22h-3m2v-cmgh)


[HIGH] 51-51: github.com/cosmos/cosmos-sdk 0.50.11: Cosmos SDK: Groups module can halt chain when handling a malicious proposal

(GHSA-x5vx-95h7-rv4p)

🔇 Additional comments (10)
warden/app/oracle.go (2)

58-61: Nil mempool in DefaultProposalHandler — confirm compatibility

Passing nil to baseapp.NewDefaultProposalHandler and only setting a signer extraction adapter looks intentional. Please confirm this matches SDK v0.53.4 expectations (no hidden mempool uses).

Would you like me to scan the codebase for any implicit mempool usage invoked by the proposal handler on your setup?


6-17: Ignore import formatting suggestion: imports in warden/app/oracle.go are already correctly grouped and sorted; no action required.

Likely an incorrect or invalid review comment.

localnet.just (2)

69-69: LGTM: enabling no_base_fee for localnet

Setting feemarket.params.no_base_fee = true aligns with snapshot/test expectations and simplifies local testing.


76-76: Minor: extended wait is sensible

sleep 5 improves stability before post-start actions. No further action.

go.mod (2)

52-53: No change needed for evmd pin: github.com/cosmos/evm/evmd is directly imported in your code (e.g., cmd/wardend/cmd/testnet.go), so retaining the explicit pseudo-version is required.


143-144: Remove residual depinject entry from go.mod
No direct imports of cosmossdk.io/depinject; it’s retained as an indirect requirement—likely via cosmossdk.io/schema. Upgrade to Go ≥1.25, run go mod why -m cosmossdk.io/depinject to confirm no import chain, then remove the line and run go mod tidy -compat=1.25.

-   cosmossdk.io/depinject v1.2.1 // indirect
justfile (1)

26-30: Deterministic wasm deployment pipeline: good improvements

Explicit gas/fees and stricter shell flags harden deployments. LGTM.

warden/app/export.go (1)

19-31: Good: error now propagated from prepForZeroHeightGenesis.
The early return on error prevents silent export failures.

tests/slinky/go.mod (1)

67-69: Don’t upgrade btcd to v0.24.2—breaks existing dependencies
The v0.24 release removes the old github.com/btcsuite/btcd/btcec package (tests/slinky and interchaintest → tendermint still import it), so bumping to v0.24.2 causes go mod tidy to fail. Hold at v0.22.1 until dependent modules update or you refactor imports to btcec/v2.

Likely an incorrect or invalid review comment.

cmd/wardend/cmd/root.go (1)

447-461: ChainID parsing: clear and defensive.
The format validation prevents bad slices; good.

@Pitasi Pitasi merged commit 983cedf into main Aug 28, 2025
25 of 26 checks passed
@Pitasi Pitasi deleted the remove-depinject branch August 28, 2025 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants