Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
00eef3b
audit: add module
mateeullahmalik Jan 14, 2026
d537fab
audit : Reafactor & cleanup
mateeullahmalik Jan 27, 2026
470cffc
audit: stable window math across param changes
mateeullahmalik Jan 27, 2026
98e5fd9
audit: enforce postponement + retention
mateeullahmalik Jan 28, 2026
13bc1fe
Add tests, reduce noise in CI test runner, Update CHNAGELOG
mateeullahmalik Jan 28, 2026
fc77bab
audit: port evidence + staleness
mateeullahmalik Feb 2, 2026
e6c1b4c
x/audit: fix query pagination and evidence IDs
mateeullahmalik Feb 2, 2026
4f16e2e
x/audit: avoid evidence ID reuse
mateeullahmalik Feb 2, 2026
06e3e53
x/audit: signature and finalization enforcement
mateeullahmalik Feb 4, 2026
84e6519
x/audit: lean metada
mateeullahmalik Feb 4, 2026
15d43f5
x/audit: action finalization postpone+recover
mateeullahmalik Feb 4, 2026
d0baede
x/supernode: persist postpone reason (#100)
j-rafique Feb 6, 2026
3f9fcc7
audit: epoch-based reporting
mateeullahmalik Feb 6, 2026
0750c95
audit : Rename Msgs for clarity, & tweaks
mateeullahmalik Feb 9, 2026
7f5ffd4
audit : fixes
mateeullahmalik Feb 11, 2026
68a2e78
audit: add cascade failure evidence type
mateeullahmalik Feb 11, 2026
98e932a
fix audit tests
mateeullahmalik Feb 11, 2026
2861200
audit evidence update
mateeullahmalik Feb 11, 2026
04a0235
Address copilot comments
mateeullahmalik Feb 19, 2026
126c277
app/upgrades: prevent double audit init in v1.11.0
mateeullahmalik Mar 2, 2026
95c9602
ci: pin buf install to go.mod version
mateeullahmalik Mar 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ jobs:
- name: Install buf CLI
run: |
set -euo pipefail
go install github.com/bufbuild/buf/cmd/buf@latest
BUF_VERSION="$(go list -m -f '{{.Version}}' github.com/bufbuild/buf)"
if [ -z "${BUF_VERSION}" ]; then
echo "Failed to resolve github.com/bufbuild/buf version from go.mod" >&2
exit 1
fi
go install "github.com/bufbuild/buf/cmd/buf@${BUF_VERSION}"

- name: Build with Ignite CLI
run: |
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ RELEASE_CGO_LDFLAGS ?= -Wl,-rpath,/usr/lib -Wl,--disable-new-dtags
COSMOS_PROTO_VERSION := $(call module_version,github.com/cosmos/cosmos-proto)
GOGOPROTO_VERSION := $(call module_version,github.com/cosmos/gogoproto)
GOLANGCI_LINT_VERSION := $(call module_version,github.com/golangci/golangci-lint)
BUF_VERSION := $(call module_version,github.com/bufbuild/buf)
GRPC_GATEWAY_VERSION := $(call module_version,github.com/grpc-ecosystem/grpc-gateway)
GRPC_GATEWAY_V2_VERSION := $(call module_version,github.com/grpc-ecosystem/grpc-gateway/v2)
GO_TOOLS_VERSION := $(call module_version,golang.org/x/tools)
Expand All @@ -30,7 +31,7 @@ GOCACHE := $(shell ${GO} env GOCACHE)
GOMODCACHE := $(shell ${GO} env GOMODCACHE)

TOOLS := \
github.com/bufbuild/buf/cmd/buf@latest \
github.com/bufbuild/buf/cmd/buf@$(BUF_VERSION) \
github.com/cosmos/gogoproto/protoc-gen-gocosmos@$(GOGOPROTO_VERSION) \
github.com/cosmos/gogoproto/protoc-gen-gogo@$(GOGOPROTO_VERSION) \
github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) \
Expand Down
4 changes: 4 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import (
upgrades "github.com/LumeraProtocol/lumera/app/upgrades"
appParams "github.com/LumeraProtocol/lumera/app/upgrades/params"
actionmodulekeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper"
auditmodulekeeper "github.com/LumeraProtocol/lumera/x/audit/v1/keeper"
claimmodulekeeper "github.com/LumeraProtocol/lumera/x/claim/keeper"
lumeraidmodulekeeper "github.com/LumeraProtocol/lumera/x/lumeraid/keeper"
sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types"
Expand Down Expand Up @@ -147,6 +148,7 @@ type App struct {
LumeraidKeeper lumeraidmodulekeeper.Keeper
ClaimKeeper claimmodulekeeper.Keeper
SupernodeKeeper sntypes.SupernodeKeeper
AuditKeeper auditmodulekeeper.Keeper
ActionKeeper actionmodulekeeper.Keeper
// this line is used by starport scaffolding # stargate/app/keeperDeclaration

Expand Down Expand Up @@ -248,6 +250,7 @@ func New(
&app.LumeraidKeeper,
&app.ClaimKeeper,
&app.SupernodeKeeper,
&app.AuditKeeper,
&app.ActionKeeper,
// this line is used by starport scaffolding # stargate/app/keeperDefinition
); err != nil {
Expand Down Expand Up @@ -328,6 +331,7 @@ func (app *App) setupUpgrades() {
SupernodeKeeper: app.SupernodeKeeper,
ParamsKeeper: &app.ParamsKeeper,
ConsensusParamsKeeper: &app.ConsensusParamsKeeper,
AuditKeeper: &app.AuditKeeper,
}

allUpgrades := upgrades.AllUpgrades(params)
Expand Down
9 changes: 9 additions & 0 deletions app/app_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import (
upgradetypes "cosmossdk.io/x/upgrade/types"
actionmodulev1 "github.com/LumeraProtocol/lumera/x/action/v1/module"
actionmoduletypes "github.com/LumeraProtocol/lumera/x/action/v1/types"
auditmodulev1 "github.com/LumeraProtocol/lumera/x/audit/v1/module"
auditmoduletypes "github.com/LumeraProtocol/lumera/x/audit/v1/types"
claimmodulev1 "github.com/LumeraProtocol/lumera/x/claim/module"
claimmoduletypes "github.com/LumeraProtocol/lumera/x/claim/types"
lumeraidmodulev1 "github.com/LumeraProtocol/lumera/x/lumeraid/module"
Expand Down Expand Up @@ -117,6 +119,7 @@ var (
wasmtypes.ModuleName,
claimmoduletypes.ModuleName,
supernodemoduletypes.ModuleName,
auditmoduletypes.ModuleName,
actionmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/initGenesis
}
Expand Down Expand Up @@ -145,6 +148,7 @@ var (
wasmtypes.ModuleName,
claimmoduletypes.ModuleName,
supernodemoduletypes.ModuleName,
auditmoduletypes.ModuleName,
actionmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/beginBlockers
}
Expand All @@ -166,6 +170,7 @@ var (
wasmtypes.ModuleName,
claimmoduletypes.ModuleName,
supernodemoduletypes.ModuleName,
auditmoduletypes.ModuleName,
actionmoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/endBlockers
}
Expand Down Expand Up @@ -333,6 +338,10 @@ var (
Name: supernodemoduletypes.ModuleName,
Config: appconfig.WrapAny(&supernodemodulev1.Module{}),
},
{
Name: auditmoduletypes.ModuleName,
Config: appconfig.WrapAny(&auditmodulev1.Module{}),
},
{
Name: actionmoduletypes.ModuleName,
Config: appconfig.WrapAny(&actionmodulev1.Module{}),
Expand Down
2 changes: 2 additions & 0 deletions app/upgrades/params/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"

actionmodulekeeper "github.com/LumeraProtocol/lumera/x/action/v1/keeper"
auditmodulekeeper "github.com/LumeraProtocol/lumera/x/audit/v1/keeper"
sntypes "github.com/LumeraProtocol/lumera/x/supernode/v1/types"
)

Expand All @@ -24,4 +25,5 @@ type AppUpgradeParams struct {
SupernodeKeeper sntypes.SupernodeKeeper
ParamsKeeper *paramskeeper.Keeper
ConsensusParamsKeeper *consensuskeeper.Keeper
AuditKeeper *auditmodulekeeper.Keeper
}
8 changes: 8 additions & 0 deletions app/upgrades/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
appParams "github.com/LumeraProtocol/lumera/app/upgrades/params"
upgrade_v1_10_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_0"
upgrade_v1_10_1 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_1"
upgrade_v1_11_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_11_0"
upgrade_v1_6_1 "github.com/LumeraProtocol/lumera/app/upgrades/v1_6_1"
upgrade_v1_8_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_0"
upgrade_v1_8_4 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_4"
Expand All @@ -33,6 +34,7 @@ import (
// | v1.9.1 | standard | none | Migrations only
// | v1.10.0 | custom | drop crisis | Migrate consensus params from x/params to x/consensus; remove x/crisis
// | v1.10.1 | custom | drop crisis (if not already) | Ensure consensus params are present in x/consensus
// | v1.11.0 | custom | add audit store | Initializes audit params with dynamic epoch_zero_height
// =================================================================================================================================

type UpgradeConfig struct {
Expand Down Expand Up @@ -60,6 +62,7 @@ var upgradeNames = []string{
upgradeNameV191,
upgrade_v1_10_0.UpgradeName,
upgrade_v1_10_1.UpgradeName,
upgrade_v1_11_0.UpgradeName,
}

var NoUpgradeConfig = UpgradeConfig{
Expand Down Expand Up @@ -124,6 +127,11 @@ func SetupUpgrades(upgradeName string, params appParams.AppUpgradeParams) (Upgra
StoreUpgrade: &upgrade_v1_10_1.StoreUpgrades,
Handler: upgrade_v1_10_1.CreateUpgradeHandler(params),
}, true
case upgrade_v1_11_0.UpgradeName:
return UpgradeConfig{
StoreUpgrade: &upgrade_v1_11_0.StoreUpgrades,
Handler: upgrade_v1_11_0.CreateUpgradeHandler(params),
}, true

// add future upgrades here
default:
Expand Down
8 changes: 5 additions & 3 deletions app/upgrades/upgrades_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
appParams "github.com/LumeraProtocol/lumera/app/upgrades/params"
upgrade_v1_10_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_0"
upgrade_v1_10_1 "github.com/LumeraProtocol/lumera/app/upgrades/v1_10_1"
upgrade_v1_11_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_11_0"
upgrade_v1_6_1 "github.com/LumeraProtocol/lumera/app/upgrades/v1_6_1"
upgrade_v1_8_0 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_0"
upgrade_v1_8_4 "github.com/LumeraProtocol/lumera/app/upgrades/v1_8_4"
Expand All @@ -33,6 +34,7 @@ func TestUpgradeNamesOrder(t *testing.T) {
upgradeNameV191,
upgrade_v1_10_0.UpgradeName,
upgrade_v1_10_1.UpgradeName,
upgrade_v1_11_0.UpgradeName,
}
require.Equal(t, expected, upgradeNames, "upgradeNames should stay in ascending order")
}
Expand Down Expand Up @@ -76,9 +78,9 @@ func TestSetupUpgradesAndHandlers(t *testing.T) {
continue
}

// v1.9.0 requires full keeper wiring; exercising it here would require
// v1.9.0 and v1.11.0 require full keeper wiring; exercising them here would require
// a full app harness. This test only verifies registration and gating.
if upgradeName == upgrade_v1_9_0.UpgradeName || upgradeName == upgrade_v1_10_0.UpgradeName || upgradeName == upgrade_v1_10_1.UpgradeName {
if upgradeName == upgrade_v1_9_0.UpgradeName || upgradeName == upgrade_v1_10_0.UpgradeName || upgradeName == upgrade_v1_10_1.UpgradeName || upgradeName == upgrade_v1_11_0.UpgradeName {
continue
}

Expand Down Expand Up @@ -123,7 +125,7 @@ func expectStoreUpgrade(upgradeName, chainID string) bool {
return IsMainnet(chainID)
case upgrade_v1_10_0.UpgradeName:
return true
case upgrade_v1_10_1.UpgradeName:
case upgrade_v1_10_1.UpgradeName, upgrade_v1_11_0.UpgradeName:
return true
default:
return false
Expand Down
107 changes: 107 additions & 0 deletions app/upgrades/v1_11_0/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package v1_11_0

import (
"context"
"fmt"

storetypes "cosmossdk.io/store/types"
upgradetypes "cosmossdk.io/x/upgrade/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"

appParams "github.com/LumeraProtocol/lumera/app/upgrades/params"
audittypes "github.com/LumeraProtocol/lumera/x/audit/v1/types"
)

// Storage challenge feature toggle at activation time.
//
// This is set exactly once during the upgrade; thereafter, params are governed by MsgUpdateParams.
// All other parameter defaults are owned by the audit module (types.DefaultParams()).
const auditScEnabled = true

// UpgradeName is the on-chain name used for this upgrade.
const UpgradeName = "v1.11.0"

// StoreUpgrades declares store additions/deletions for this upgrade.
//
// Audit is introduced for the first time on-chain, so its KV store must be added.
var StoreUpgrades = storetypes.StoreUpgrades{
Added: []string{
audittypes.StoreKey, // "audit"
},
}

// CreateUpgradeHandler creates an upgrade handler for v1.11.0.
//
// This upgrade introduces the audit module and initializes its params in a way
// that requires no hard-coded epoch_zero_height for existing networks:
// - epoch_zero_height is set to the upgrade block height (the first block the
// new binary processes).
// - epoch_length_blocks remains its default unless governance later changes it
// (epoch cadence fields are immutable after initialization).
func CreateUpgradeHandler(p appParams.AppUpgradeParams) upgradetypes.UpgradeHandler {
return func(goCtx context.Context, _ upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
p.Logger.Info(fmt.Sprintf("Starting upgrade %s...", UpgradeName))

ctx := sdk.UnwrapSDKContext(goCtx)

// x/module's RunMigrations auto-calls InitGenesis for modules missing from fromVM.
// We want custom, upgrade-height-aware audit initialization instead of default genesis,
// so pin audit to its consensus version before running migrations.
migrationVM := prepareVersionMapForCustomAuditInit(fromVM)

p.Logger.Info("Running module migrations...")
newVM, err := p.ModuleManager.RunMigrations(ctx, p.Configurator, migrationVM)
if err != nil {
p.Logger.Error("Failed to run migrations", "error", err)
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
p.Logger.Info("Module migrations completed.")

if p.AuditKeeper == nil {
return nil, fmt.Errorf("%s upgrade requires audit keeper to be wired", UpgradeName)
}

// Initialize audit genesis state with an automatically chosen epoch_zero_height.
// Using the current block height ensures that the audit BeginBlocker will create
// the epoch-0 anchor immediately at the epoch start height.
gs := audittypes.DefaultGenesis()
params := gs.Params.WithDefaults()

// For an already-running chain, epoch zero must be chosen dynamically at the upgrade height.
// This is set exactly once here; thereafter it is immutable.
params.EpochZeroHeight = uint64(ctx.BlockHeight())

// Feature gate for SC evidence validation/acceptance.
params.ScEnabled = auditScEnabled

gs.Params = params

if err := p.AuditKeeper.InitGenesis(ctx, *gs); err != nil {
return nil, fmt.Errorf("init audit module: %w", err)
}

// Create epoch-0 anchor immediately, so audit reporting can begin in the same upgrade block
// without depending on BeginBlock ordering assumptions.
epochID := uint64(0)
epochStart := ctx.BlockHeight()
epochEnd := epochStart + int64(params.EpochLengthBlocks) - 1
if err := p.AuditKeeper.CreateEpochAnchorIfNeeded(ctx, epochID, epochStart, epochEnd, params); err != nil {
return nil, fmt.Errorf("create audit epoch anchor: %w", err)
}

p.Logger.Info(fmt.Sprintf("Successfully completed upgrade %s", UpgradeName))
return newVM, nil
}
}

func prepareVersionMapForCustomAuditInit(fromVM module.VersionMap) module.VersionMap {
migrationVM := make(module.VersionMap, len(fromVM)+1)
for moduleName, version := range fromVM {
migrationVM[moduleName] = version
}

migrationVM[audittypes.ModuleName] = audittypes.ConsensusVersion
return migrationVM
}
33 changes: 33 additions & 0 deletions app/upgrades/v1_11_0/upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package v1_11_0

import (
"testing"

"github.com/cosmos/cosmos-sdk/types/module"
"github.com/stretchr/testify/require"

audittypes "github.com/LumeraProtocol/lumera/x/audit/v1/types"
)

func TestPrepareVersionMapForCustomAuditInit_NilInput(t *testing.T) {
migrationVM := prepareVersionMapForCustomAuditInit(nil)

require.Equal(t, module.VersionMap{
audittypes.ModuleName: audittypes.ConsensusVersion,
}, migrationVM)
}

func TestPrepareVersionMapForCustomAuditInit_ClonesAndPinsAuditVersion(t *testing.T) {
fromVM := module.VersionMap{
"bank": 3,
"auth": 2,
"audit": 0,
}

migrationVM := prepareVersionMapForCustomAuditInit(fromVM)

require.Equal(t, uint64(0), fromVM[audittypes.ModuleName], "input map must not be mutated")
require.Equal(t, uint64(3), migrationVM["bank"])
require.Equal(t, uint64(2), migrationVM["auth"])
require.Equal(t, uint64(audittypes.ConsensusVersion), migrationVM[audittypes.ModuleName])
}
2 changes: 1 addition & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ genesis:
max_processing_time: 1h0m0s
expiration_duration: 24h0m0s
claim:
total_claimable_amount: '18749999991853'
total_claimable_amount: '18749999981413'
params:
claim_end_time: '1767225600' # Jan 1 2026, 00:00:00
crisis:
Expand Down
2 changes: 1 addition & 1 deletion docs/static/openapi.yml

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions proto/lumera/audit/module/v1/module.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";
package lumera.audit.module.v1;

option go_package = "x/audit/v1/module;audit";

import "cosmos/app/v1alpha1/module.proto";

// Module is the config object for the module.
message Module {
option (cosmos.app.v1alpha1.module) = {
go_import: "github.com/LumeraProtocol/lumera/x/audit/v1"
};

// authority defines the custom module authority. If not set, defaults to the governance module.
string authority = 1;
}
Loading