Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement x/cwregistry module #578

Draft
wants to merge 21 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Contains bug fixes.

Contains all the PRs that improved the code without changing the behaviors.
-->
## [Unreleased]

### Added
- [#578](https://github.com/archway-network/archway/pull/578) - Adding x/cwregistry module


## [v8.0.0](https://github.com/archway-network/archway/releases/tag/v8.0.0)

Expand Down
16 changes: 15 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ import (
cwicakeeper "github.com/archway-network/archway/x/cwica/keeper"
cwicatypes "github.com/archway-network/archway/x/cwica/types"

cwregistry "github.com/archway-network/archway/x/cwregistry"
cwregistrykeeper "github.com/archway-network/archway/x/cwregistry/keeper"
cwregistryTypes "github.com/archway-network/archway/x/cwregistry/types"

extendedGov "github.com/archway-network/archway/x/gov"

"github.com/CosmWasm/wasmd/x/wasm"
Expand Down Expand Up @@ -225,6 +229,7 @@ var (
cwfees.AppModule{},
cwica.AppModuleBasic{},
cwerrors.AppModuleBasic{},
cwregistry.AppModuleBasic{},
)

// module account permissions
Expand Down Expand Up @@ -329,7 +334,7 @@ func NewArchwayApp(
feegrant.StoreKey, authzkeeper.StoreKey, wasmdTypes.StoreKey, consensusparamtypes.StoreKey,
icacontrollertypes.StoreKey, icahosttypes.StoreKey, ibcfeetypes.StoreKey, crisistypes.StoreKey, group.StoreKey, nftkeeper.StoreKey, cwicatypes.StoreKey,

trackingTypes.StoreKey, rewardsTypes.StoreKey, callbackTypes.StoreKey, cwfees.ModuleName, cwerrorsTypes.StoreKey,
trackingTypes.StoreKey, rewardsTypes.StoreKey, callbackTypes.StoreKey, cwfees.ModuleName, cwerrorsTypes.StoreKey, cwregistryTypes.StoreKey,
)
tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, cwerrorsTypes.TStoreKey)
memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
Expand Down Expand Up @@ -667,6 +672,13 @@ func NewArchwayApp(
logger,
)

app.Keepers.CWRegistryKeeper = cwregistrykeeper.NewKeeper(
appCodec,
keys[cwregistryTypes.StoreKey],
app.Keepers.WASMKeeper,
logger,
)

var transferStack porttypes.IBCModule
transferStack = transfer.NewIBCModule(app.Keepers.TransferKeeper)
transferStack = ibcfee.NewIBCMiddleware(transferStack, app.Keepers.IBCFeeKeeper)
Expand Down Expand Up @@ -748,6 +760,7 @@ func NewArchwayApp(
callback.NewAppModule(app.appCodec, app.Keepers.CallbackKeeper, app.Keepers.WASMKeeper, app.Keepers.CWErrorsKeeper),
cwica.NewAppModule(appCodec, app.Keepers.CWICAKeeper, app.Keepers.AccountKeeper),
cwerrors.NewAppModule(app.appCodec, app.Keepers.CWErrorsKeeper, app.Keepers.WASMKeeper),
cwregistry.NewAppModule(app.appCodec, app.Keepers.CWRegistryKeeper),
crisis.NewAppModule(&app.Keepers.CrisisKeeper, skipGenesisInvariants, app.getSubspace(crisistypes.ModuleName)), // always be last to make sure that it checks for all invariants and not only part of them
)

Expand Down Expand Up @@ -877,6 +890,7 @@ func NewArchwayApp(
genmsg.ModuleName,
callbackTypes.ModuleName,
cwerrorsTypes.ModuleName,
cwregistryTypes.ModuleName,
// invariants checks are always the last to run
crisistypes.ModuleName,
cwicatypes.ModuleName,
Expand Down
3 changes: 3 additions & 0 deletions app/app_upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
upgrade6_0_0 "github.com/archway-network/archway/app/upgrades/6_0_0"
upgrade7_0_0 "github.com/archway-network/archway/app/upgrades/7_0_0"
upgrade8_0_0 "github.com/archway-network/archway/app/upgrades/8_0_0"
upgradelatest "github.com/archway-network/archway/app/upgrades/latest"
)

// UPGRADES
Expand All @@ -29,6 +30,8 @@ var Upgrades = []upgrades.Upgrade{
upgrade6_0_0.Upgrade, // v6.0.0
upgrade7_0_0.Upgrade, // v7.0.0
upgrade8_0_0.Upgrade, // v8.0.0

upgradelatest.Upgrade, // latest
}

func (app *ArchwayApp) RegisterUpgradeHandlers() {
Expand Down
14 changes: 8 additions & 6 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
callbackKeeper "github.com/archway-network/archway/x/callback/keeper"
cwerrorsKeeper "github.com/archway-network/archway/x/cwerrors/keeper"
cwicaKeeper "github.com/archway-network/archway/x/cwica/keeper"
cwregistryKeeper "github.com/archway-network/archway/x/cwregistry/keeper"
rewardsKeeper "github.com/archway-network/archway/x/rewards/keeper"
trackingKeeper "github.com/archway-network/archway/x/tracking/keeper"
)
Expand Down Expand Up @@ -61,10 +62,11 @@ type ArchwayKeepers struct {
WASMKeeper wasmkeeper.Keeper

// Archway Keepers
TrackingKeeper trackingKeeper.Keeper
RewardsKeeper rewardsKeeper.Keeper
CWFeesKeeper cwfees.Keeper
CallbackKeeper callbackKeeper.Keeper
CWErrorsKeeper cwerrorsKeeper.Keeper
CWICAKeeper cwicaKeeper.Keeper
TrackingKeeper trackingKeeper.Keeper
RewardsKeeper rewardsKeeper.Keeper
CWFeesKeeper cwfees.Keeper
CallbackKeeper callbackKeeper.Keeper
CWErrorsKeeper cwerrorsKeeper.Keeper
CWICAKeeper cwicaKeeper.Keeper
CWRegistryKeeper cwregistryKeeper.Keeper
}
4 changes: 3 additions & 1 deletion app/upgrades/8_0_0/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@ var Upgrade = upgrades.Upgrade{
return migrations, nil
}
},
StoreUpgrades: storetypes.StoreUpgrades{},
StoreUpgrades: storetypes.StoreUpgrades{
Added: []string{},
},
}
37 changes: 37 additions & 0 deletions app/upgrades/latest/upgrades.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package upgradelatest

import (
"context"

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"

"github.com/archway-network/archway/app/keepers"
"github.com/archway-network/archway/app/upgrades"
cwregistrytypes "github.com/archway-network/archway/x/cwregistry/types"
)

const Name = "latest"
const NameAsciiArt = ""

var Upgrade = upgrades.Upgrade{
UpgradeName: Name,
CreateUpgradeHandler: func(mm *module.Manager, cfg module.Configurator, keepers keepers.ArchwayKeepers) upgradetypes.UpgradeHandler {
return func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
migrations, err := mm.RunMigrations(ctx, cfg, fromVM)
if err != nil {
return nil, err
}

sdk.UnwrapSDKContext(ctx).Logger().Info(upgrades.ArchwayLogo + NameAsciiArt)
return migrations, nil
}
},
StoreUpgrades: storetypes.StoreUpgrades{
Added: []string{
cwregistrytypes.ModuleName,
},
},
}
Empty file removed genesis.json
Empty file.
46 changes: 46 additions & 0 deletions pkg/testutils/cwregistrykeeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package testutils

import (
"testing"

"cosmossdk.io/log"
"cosmossdk.io/store"
storemetrics "cosmossdk.io/store/metrics"
storetypes "cosmossdk.io/store/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

"github.com/archway-network/archway/x/cwregistry/keeper"
"github.com/archway-network/archway/x/cwregistry/types"
)

func CWRegistryKeeper(tb testing.TB) (keeper.Keeper, sdk.Context) {
tb.Helper()
storeKey := storetypes.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey("m_cwregistry")
tStoreKey := storetypes.NewTransientStoreKey("t_cwregistry")

db := dbm.NewMemDB()
stateStore := store.NewCommitMultiStore(db, log.NewTestLogger(tb), storemetrics.NewNoOpMetrics())
stateStore.MountStoreWithDB(storeKey, storetypes.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, storetypes.StoreTypeMemory, nil)
stateStore.MountStoreWithDB(tStoreKey, storetypes.StoreTypeTransient, db)
require.NoError(tb, stateStore.LoadLatestVersion())

registry := codectypes.NewInterfaceRegistry()
cdc := codec.NewProtoCodec(registry)

k := keeper.NewKeeper(
cdc,
storeKey,
nil,
log.NewTestLogger(tb),
)
ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())

return k, ctx
}
16 changes: 16 additions & 0 deletions pkg/testutils/wasmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ var _ wasmKeeper.Messenger = (*MockMessenger)(nil)
// Mock returns a contract info if admin is set.
type MockContractViewer struct {
contractAdminSet map[string]string // key: contractAddr, value: adminAddr
codeAdminSet map[uint64]string // key: codeID, value: adminAddr
returnSudoError error
}

// NewMockContractViewer creates a new MockContractViewer instance.
func NewMockContractViewer() *MockContractViewer {
return &MockContractViewer{
contractAdminSet: make(map[string]string),
codeAdminSet: make(map[uint64]string),
returnSudoError: nil,
}
}
Expand All @@ -31,6 +33,10 @@ func (v *MockContractViewer) AddContractAdmin(contractAddr, adminAddr string) {
v.contractAdminSet[contractAddr] = adminAddr
}

func (v *MockContractViewer) AddCodeAdmin(codeID uint64, adminAddr string) {
v.codeAdminSet[codeID] = adminAddr
}

// GetContractInfo returns a contract info if admin is set.
func (v MockContractViewer) GetContractInfo(ctx context.Context, contractAddress sdk.AccAddress) *wasmdTypes.ContractInfo {
adminAddr, found := v.contractAdminSet[contractAddress.String()]
Expand All @@ -49,6 +55,16 @@ func (v MockContractViewer) HasContractInfo(ctx context.Context, contractAddress
return found
}

func (v MockContractViewer) GetCodeInfo(ctx context.Context, codeID uint64) *wasmdTypes.CodeInfo {
_, found := v.codeAdminSet[codeID]
if !found {
return nil
}
return &wasmdTypes.CodeInfo{
Creator: v.codeAdminSet[codeID],
}
}

// Sudo implements the wasmKeeper.ContractInfoViewer interface.
func (v MockContractViewer) Sudo(ctx context.Context, contractAddress sdk.AccAddress, msg []byte) ([]byte, error) {
return nil, v.returnSudoError
Expand Down
38 changes: 38 additions & 0 deletions proto/archway/cwregistry/v1/cwregistry.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
syntax = "proto3";
package archway.cwregistry.v1;

option go_package = "github.com/archway-network/archway/x/cwregistry/types";

// CodeMetadata defines the metadata of a contract code
message CodeMetadata {
// The Code ID of the deployed contract
uint64 code_id = 1;
// The information regarding the contract source codebase
SourceMetadata source = 2;
// The information regarding the image used to build and optimize the contract binary
SourceBuilder source_builder = 3;
// The JSON schema url which specifies the interaction endpoints of the contract
string schema = 4;
// The contacts of the developers or security incidence handlers
repeated string contacts = 5;
}

// SourceMetadata defines the metadata of the source code of a contract
message SourceMetadata {
// The link to the code repository. e.g https://github.com/archway-network/archway
string repository = 1;
// The tag of the commit message at which the binary was built and deployed. e.g v1.0.2
string tag = 2;
// The software license of the smart contract code. e.g Apache-2.0
string license = 3;
}

// SourceBuilder defines the metadata of the builder used to build the contract binary
message SourceBuilder {
// Docker image. e.g cosmwasm/rust-optimizer
string image = 1;
// Docker image tag. e.g 0.12.6
string tag = 2;
// Name of the generated contract binary. e.g counter.wasm
string contract_name = 3;
}
13 changes: 13 additions & 0 deletions proto/archway/cwregistry/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";
package archway.cwregistry.v1;

import "gogoproto/gogo.proto";
import "archway/cwregistry/v1/cwregistry.proto";

option go_package = "github.com/archway-network/archway/x/cwregistry/types";

// GenesisState defines the cwregistry module's genesis state.
message GenesisState {
// code_metadata defines all the code metadata stored in the cwregistry module.
repeated CodeMetadata code_metadata = 1 [ (gogoproto.nullable) = false ];
}
43 changes: 43 additions & 0 deletions proto/archway/cwregistry/v1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
syntax = "proto3";
package archway.cwregistry.v1;

import "gogoproto/gogo.proto";
import "archway/cwregistry/v1/cwregistry.proto";
import "google/api/annotations.proto";

option go_package = "github.com/archway-network/archway/x/cwregistry/types";

// Query service for the cwregistry module.
service Query {
rpc CodeMetadata(QueryCodeMetadataRequest) returns (QueryCodeMetadataResponse) {
option (google.api.http).get = "/archway/cwregistry/v1/code_metadata";
}

rpc ContractMetadata(QueryContractMetadataRequest) returns (QueryContractMetadataResponse) {
option (google.api.http).get = "/archway/cwregistry/v1/contract_metadata";
}
}

// QueryCodeMetadataRequest is the request type for the Query/CodeMetadata RPC method.
message QueryCodeMetadataRequest {
// code_id is the contract code id to query metadata for.
uint64 code_id = 1;
}

// QueryContractMetadataRequest is the request type for the Query/ContractMetadata RPC method.
message QueryCodeMetadataResponse {
// code_metadata is the metadata for the contract code.
CodeMetadata code_metadata = 1;
}

// QueryContractMetadataRequest is the request type for the Query/ContractMetadata RPC method.
message QueryContractMetadataRequest {
// contract_address is the bech32 contract address to query metadata for.
string contract_address = 1;
}

// QueryContractMetadataResponse is the response type for the Query/ContractMetadata RPC method.
message QueryContractMetadataResponse {
// contract_metadata is the metadata for the contract.
CodeMetadata code_metadata = 1;
}
39 changes: 39 additions & 0 deletions proto/archway/cwregistry/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
syntax = "proto3";
package archway.cwregistry.v1;

import "amino/amino.proto";
import "cosmos/msg/v1/msg.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "archway/cwregistry/v1/cwregistry.proto";

option go_package = "github.com/archway-network/archway/x/cwregistry/types";

// Msg defines the Msg service.
service Msg {
option (cosmos.msg.v1.service) = true;
// RegisterCode registers a contract code with the contract registry.
rpc RegisterCode(MsgRegisterCode) returns (MsgRegisterCodeResponse) {}
}

// MsgRegisterCode registers a contract code with the contract registry.
message MsgRegisterCode {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
option (cosmos.msg.v1.signer) = "sender";
// sender is the bech32 address of the sender.
string sender = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
// code_id is the id of the contract code.
uint64 code_id = 2;
// source_metadata is the metadata of the contract source.
SourceMetadata source_metadata = 3;
// source_builder is the builder image of the contract source.
SourceBuilder source_builder = 4;
// schema is the json schema of the contract.
string schema = 5;
// contacts is the list of dev contacts for the contract.
repeated string contacts = 6;
}

message MsgRegisterCodeResponse {}
Loading
Loading