diff --git a/Makefile b/Makefile index 381bffc2..71f6476a 100644 --- a/Makefile +++ b/Makefile @@ -195,6 +195,7 @@ test-race: ARGS=-timeout=5m -race test-race: TEST_PACKAGES=$(PACKAGES_UNIT) test-e2e: ARGS=-timeout=25m -v test-e2e: TEST_PACKAGES=$(PACKAGES_E2E) +test-e2e: docker-build-debug $(TEST_TARGETS): run-tests run-tests: diff --git a/app/keepers/gov_adapter.go b/app/keepers/gov_adapter.go new file mode 100644 index 00000000..15139484 --- /dev/null +++ b/app/keepers/gov_adapter.go @@ -0,0 +1,32 @@ +package keepers + +import ( + ccvtypes "github.com/cosmos/interchain-security/v5/x/ccv/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + + atomonegovkeeper "github.com/atomone-hub/atomone/x/gov/keeper" +) + +// GovKeeperAdapter adapts AtomOne's gov keeper to match the interface expected by ICS +type GovKeeperAdapter struct { + keeper *atomonegovkeeper.Keeper +} + +// NewGovKeeperAdapter creates a new adapter for AtomOne's gov keeper +func NewGovKeeperAdapter(k *atomonegovkeeper.Keeper) *GovKeeperAdapter { + return &GovKeeperAdapter{keeper: k} +} + +// GetProposal retrieves a proposal and converts it to ICS's Proposal type +func (a *GovKeeperAdapter) GetProposal(ctx sdk.Context, proposalID uint64) (ccvtypes.Proposal, bool) { + prop, found := a.keeper.GetProposal(ctx, proposalID) + if !found { + return ccvtypes.Proposal{}, false + } + + // Convert AtomOne proposal to ICS proposal - only copy the Messages field + return ccvtypes.Proposal{ + Messages: prop.Messages, + }, true +} diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index ba5591b2..2b360b5b 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -14,6 +14,9 @@ import ( ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v10/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v10/modules/light-clients/07-tendermint" + icsprovider "github.com/cosmos/interchain-security/v5/x/ccv/provider" + icsproviderkeeper "github.com/cosmos/interchain-security/v5/x/ccv/provider/keeper" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" @@ -87,11 +90,13 @@ type AppKeepers struct { ConsensusParamsKeeper consensusparamkeeper.Keeper PhotonKeeper *photonkeeper.Keeper DynamicfeeKeeper *dynamicfeekeeper.Keeper + ProviderKeeper icsproviderkeeper.Keeper // Modules ICAModule ica.AppModule TransferModule transfer.AppModule TMClientModule ibctm.AppModule + ProviderModule icsprovider.AppModule } func NewAppKeeper( @@ -211,15 +216,6 @@ func NewAppKeeper( authorityStr, ) - // register the staking hooks - // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks - appKeepers.StakingKeeper.SetHooks( - stakingtypes.NewMultiStakingHooks( - appKeepers.DistrKeeper.Hooks(), - appKeepers.SlashingKeeper.Hooks(), - ), - ) - // UpgradeKeeper must be created before IBCKeeper appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper( skipUpgradeHeights, @@ -304,9 +300,41 @@ func NewAppKeeper( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // Initialize ProviderKeeper + appKeepers.ProviderKeeper = icsproviderkeeper.NewKeeper( + appCodec, + appKeepers.keys[providertypes.StoreKey], + appKeepers.GetSubspace(providertypes.ModuleName), + appKeepers.IBCKeeper.ChannelKeeper, + appKeepers.IBCKeeper.ConnectionKeeper, + appKeepers.IBCKeeper.ClientKeeper, + appKeepers.StakingKeeper, + appKeepers.SlashingKeeper, + appKeepers.AccountKeeper, + appKeepers.DistrKeeper, + appKeepers.BankKeeper, + NewGovKeeperAdapter(appKeepers.GovKeeper), // inline the adapter creation + authorityStr, + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + addresscodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + authtypes.FeeCollectorName, + ) + + // Register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + // This includes hooks from distribution, slashing, and provider modules + appKeepers.StakingKeeper.SetHooks( + stakingtypes.NewMultiStakingHooks( + appKeepers.DistrKeeper.Hooks(), + appKeepers.SlashingKeeper.Hooks(), + appKeepers.ProviderKeeper.Hooks(), + ), + ) + // Middleware Stacks appKeepers.ICAModule = ica.NewAppModule(nil, &appKeepers.ICAHostKeeper) appKeepers.TransferModule = transfer.NewAppModule(appKeepers.TransferKeeper) + appKeepers.ProviderModule = icsprovider.NewAppModule(&appKeepers.ProviderKeeper, appKeepers.GetSubspace(providertypes.ModuleName)) // create IBC module from bottom to top of stack var ( @@ -366,6 +394,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(ibctransfertypes.ModuleName) paramsKeeper.Subspace(ibcexported.ModuleName) paramsKeeper.Subspace(icahosttypes.SubModuleName) + paramsKeeper.Subspace(providertypes.ModuleName) return paramsKeeper } diff --git a/app/keepers/keys.go b/app/keepers/keys.go index 25152327..3ee47d4a 100644 --- a/app/keepers/keys.go +++ b/app/keepers/keys.go @@ -4,6 +4,7 @@ import ( icahosttypes "github.com/cosmos/ibc-go/v10/modules/apps/27-interchain-accounts/host/types" ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" storetypes "cosmossdk.io/store/types" evidencetypes "cosmossdk.io/x/evidence/types" @@ -47,6 +48,7 @@ func (appKeepers *AppKeepers) GenerateKeys() { consensusparamtypes.StoreKey, photontypes.StoreKey, dynamicfeetypes.StoreKey, + providertypes.StoreKey, ) // Define transient store keys diff --git a/app/modules.go b/app/modules.go index 95a7bd49..b7096daf 100644 --- a/app/modules.go +++ b/app/modules.go @@ -5,6 +5,7 @@ import ( ibctransfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" ibc "github.com/cosmos/ibc-go/v10/modules/core" ibcexported "github.com/cosmos/ibc-go/v10/modules/core/exported" + providertypes "github.com/cosmos/interchain-security/v5/x/ccv/provider/types" "cosmossdk.io/x/evidence" evidencetypes "cosmossdk.io/x/evidence/types" @@ -48,16 +49,18 @@ import ( ) var maccPerms = map[string][]string{ - authtypes.FeeCollectorName: nil, - distrtypes.ModuleName: nil, - icatypes.ModuleName: nil, - minttypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - govtypes.ModuleName: {authtypes.Burner}, - ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - photontypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - dynamicfeetypes.ModuleName: nil, + authtypes.FeeCollectorName: nil, + distrtypes.ModuleName: nil, + icatypes.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + govtypes.ModuleName: {authtypes.Burner}, + ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + photontypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + dynamicfeetypes.ModuleName: nil, + providertypes.ConsumerRewardsPool: nil, + providertypes.ModuleName: nil, } func appModules( @@ -99,6 +102,7 @@ func appModules( app.TransferModule, app.ICAModule, app.TMClientModule, + app.ProviderModule, } } @@ -127,6 +131,7 @@ func orderBeginBlockers() []string { banktypes.ModuleName, photontypes.ModuleName, govtypes.ModuleName, + providertypes.ModuleName, ibcexported.ModuleName, ibctransfertypes.ModuleName, icatypes.ModuleName, @@ -152,6 +157,7 @@ func orderEndBlockers() []string { dynamicfeetypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, + providertypes.ModuleName, // provider.EndBlock must be after staking.EndBlock ibcexported.ModuleName, ibctransfertypes.ModuleName, icatypes.ModuleName, @@ -193,6 +199,7 @@ func orderInitBlockers() []string { ibctransfertypes.ModuleName, ibcexported.ModuleName, icatypes.ModuleName, + providertypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, feegrant.ModuleName, diff --git a/e2e.Dockerfile b/e2e.Dockerfile index 552428a4..87b2eb7f 100644 --- a/e2e.Dockerfile +++ b/e2e.Dockerfile @@ -1,20 +1,20 @@ ARG GO_VERSION -ARG IMG_TAG=latest # Compile the atomoned binary -FROM golang:$GO_VERSION-alpine AS atomoned-builder +# we should always pass in a GO_VERSION, but we should also set a default +# to prevent breakage. Our `make install` also runs a sanity check, so this +# is safe and please the linter. +FROM golang:${GO_VERSION:-1.24.5}-alpine AS atomoned-builder WORKDIR /src/app/ -COPY go.mod go.sum* ./ +COPY go.mod go.sum ./ RUN go mod download COPY . . -ENV PACKAGES curl make git libc-dev bash gcc linux-headers eudev-dev python3 -RUN apk add --no-cache $PACKAGES +RUN apk add --no-cache curl make git libc-dev bash gcc linux-headers eudev-dev python3 RUN CGO_ENABLED=0 make install # Add to a distroless container -FROM alpine:$IMG_TAG +FROM alpine:latest RUN adduser -D nonroot -ARG IMG_TAG COPY --from=atomoned-builder /go/bin/atomoned /usr/local/bin/ EXPOSE 26656 26657 1317 9090 USER nonroot diff --git a/go.mod b/go.mod index 59b8d48d..23834672 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ replace ( cosmossdk.io/x/upgrade => github.com/atomone-hub/cosmos-sdk/x/upgrade v0.1.5-atomone.1 github.com/cosmos/cosmos-sdk => github.com/atomone-hub/cosmos-sdk v0.50.14-atomone.1 github.com/cosmos/ibc-go/v10 => github.com/cosmos/ibc-go/v10 v10.2.0 + github.com/cosmos/interchain-security/v5 => github.com/allinbits/interchain-security/v5 v5.2.1-0.20250820180847-73b66563eba0 ) require ( @@ -32,6 +33,7 @@ require ( github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/gogoproto v1.7.0 github.com/cosmos/ibc-go/v10 v10.2.0 + github.com/cosmos/interchain-security/v5 v5.2.0 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/google/gofuzz v1.2.0 @@ -211,6 +213,7 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.11 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index 3bdcb32f..aacb0447 100644 --- a/go.sum +++ b/go.sum @@ -689,6 +689,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/allinbits/interchain-security/v5 v5.2.1-0.20250820180847-73b66563eba0 h1:W/LgJIn/Afsa63VTfjIe9E9tMkTvY7k7cnQavLSO6No= +github.com/allinbits/interchain-security/v5 v5.2.1-0.20250820180847-73b66563eba0/go.mod h1:egP/5LDmnwKgQPtoVYu9wjYt51BGV6uXKHrA2ZC6H3U= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= @@ -1573,10 +1575,10 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= diff --git a/tests/e2e/e2e_gov_test.go b/tests/e2e/e2e_gov_test.go index c522600b..4d7fbcf7 100644 --- a/tests/e2e/e2e_gov_test.go +++ b/tests/e2e/e2e_gov_test.go @@ -514,7 +514,7 @@ func (s *IntegrationTestSuite) submitGovCommand(chainAAPIEndpoint, sender string require.NoError(c, err) assert.Equal(c, res.GetProposal().Status.String(), expectedStatus.String()) }, - 15*time.Second, + 20*time.Second, time.Second, ) }