Skip to content

Commit

Permalink
Problem: No module to do NFT transfers via IBC (#860)
Browse files Browse the repository at this point in the history
Solution: Add nft-transfer module.

Note: Have to include ibc-go git submodule for building protobuf files. Can be removed once this issue is closed: cosmos/ibc-go#1345
  • Loading branch information
devashishdxt authored Sep 23, 2022
1 parent d86e35e commit 3e3d7ee
Show file tree
Hide file tree
Showing 64 changed files with 8,121 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[flake8]
max-line-length = 88
extend-ignore = E203
exclude = .git,__pycache__,./pystarport/pystarport/tendermint,./pystarport/pystarport/proto_python,./third_party/cosmos-sdk
exclude = .git,__pycache__,./pystarport/pystarport/tendermint,./pystarport/pystarport/proto_python,./third_party/cosmos-sdk,./third_party/ibc-go
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
[submodule "cosmos-sdk"]
path = third_party/cosmos-sdk
url = https://github.com/cosmos/cosmos-sdk.git

[submodule "ibc-go"]
path = third_party/ibc-go
url = https://github.com/cosmos/ibc-go.git
29 changes: 29 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ import (
icaauthmodulekeeper "github.com/crypto-org-chain/chain-main/v4/x/icaauth/keeper"
icaauthmoduletypes "github.com/crypto-org-chain/chain-main/v4/x/icaauth/types"
"github.com/crypto-org-chain/chain-main/v4/x/nft"
nfttransfer "github.com/crypto-org-chain/chain-main/v4/x/nft-transfer"
nfttransferkeeper "github.com/crypto-org-chain/chain-main/v4/x/nft-transfer/keeper"
nfttransfertypes "github.com/crypto-org-chain/chain-main/v4/x/nft-transfer/types"
nftkeeper "github.com/crypto-org-chain/chain-main/v4/x/nft/keeper"
nfttypes "github.com/crypto-org-chain/chain-main/v4/x/nft/types"
supply "github.com/crypto-org-chain/chain-main/v4/x/supply"
Expand Down Expand Up @@ -168,6 +171,7 @@ var (
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
transfer.AppModuleBasic{},
nfttransfer.AppModuleBasic{},
authzmodule.AppModuleBasic{},
groupmodule.AppModuleBasic{},
vesting.AppModuleBasic{},
Expand Down Expand Up @@ -237,13 +241,15 @@ type ChainApp struct {
FeeGrantKeeper feegrantkeeper.Keeper
GroupKeeper groupkeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
NFTTransferKeeper nfttransferkeeper.Keeper
chainmainKeeper chainmainkeeper.Keeper
SupplyKeeper supplykeeper.Keeper
NFTKeeper nftkeeper.Keeper

// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
ScopedNFTTransferKeeper capabilitykeeper.ScopedKeeper
ScopedIBCFeeKeeper capabilitykeeper.ScopedKeeper
ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper
ScopedICAHostKeeper capabilitykeeper.ScopedKeeper
Expand Down Expand Up @@ -310,6 +316,7 @@ func New(
icahosttypes.StoreKey,
capabilitytypes.StoreKey,
authzkeeper.StoreKey,
nfttransfertypes.StoreKey,
group.StoreKey,
ibcfeetypes.StoreKey,
icaauthmoduletypes.StoreKey,
Expand Down Expand Up @@ -346,6 +353,7 @@ func New(
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
scopedNFTTransferKeeper := app.CapabilityKeeper.ScopeToModule(nfttransfertypes.ModuleName)
scopedICAControllerKeeper := app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName)
scopedICAHostKeeper := app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName)
scopedICAAuthKeeper := app.CapabilityKeeper.ScopeToModule(icaauthmoduletypes.ModuleName)
Expand Down Expand Up @@ -444,6 +452,21 @@ func New(
transferStack = transfer.NewIBCModule(app.TransferKeeper)
transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper)

app.NFTTransferKeeper = nfttransferkeeper.NewKeeper(
appCodec,
keys[nfttransfertypes.StoreKey],
app.IBCFeeKeeper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
app.NFTKeeper,
app.AccountKeeper,
scopedNFTTransferKeeper,
)

var nftTransferStack porttypes.IBCModule
nftTransferStack = nfttransfer.NewIBCModule(app.NFTTransferKeeper)
nftTransferStack = ibcfee.NewIBCMiddleware(nftTransferStack, app.IBCFeeKeeper)

app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper(
appCodec, keys[icacontrollertypes.StoreKey], app.GetSubspace(icacontrollertypes.SubModuleName),
app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware
Expand Down Expand Up @@ -477,6 +500,7 @@ func New(
ibcRouter.AddRoute(icacontrollertypes.SubModuleName, icaControllerStack)
ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostStack)
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
ibcRouter.AddRoute(nfttransfertypes.ModuleName, nftTransferStack)
ibcRouter.AddRoute(icaauthmoduletypes.ModuleName, icaControllerStack)
app.IBCKeeper.SetRouter(ibcRouter)

Expand Down Expand Up @@ -511,6 +535,7 @@ func New(
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
transferModule,
nfttransfer.NewAppModule(app.NFTTransferKeeper),
feeModule,
icaModule,
icaAuthModule,
Expand Down Expand Up @@ -547,6 +572,7 @@ func New(
ibcfeetypes.ModuleName,
chainmaintypes.ModuleName,
nfttypes.ModuleName,
nfttransfertypes.ModuleName,
supplytypes.ModuleName,
)
app.mm.SetOrderEndBlockers(
Expand All @@ -573,6 +599,7 @@ func New(
ibcfeetypes.ModuleName,
chainmaintypes.ModuleName,
nfttypes.ModuleName,
nfttransfertypes.ModuleName,
supplytypes.ModuleName,
)

Expand Down Expand Up @@ -603,6 +630,7 @@ func New(
chainmaintypes.ModuleName,
supplytypes.ModuleName,
nfttypes.ModuleName,
nfttransfertypes.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
Expand Down Expand Up @@ -751,6 +779,7 @@ func New(
icahosttypes.StoreKey,
icaauthmoduletypes.StoreKey,
ibcfeetypes.StoreKey,
nfttransfertypes.StoreKey,
},
}

Expand Down
20 changes: 20 additions & 0 deletions app/docs/swagger-ui/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18153,6 +18153,8 @@ paths:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
nfts:
type: array
Expand Down Expand Up @@ -18359,6 +18361,8 @@ paths:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
pagination:
type: object
Expand Down Expand Up @@ -18493,6 +18497,8 @@ paths:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
title: >-
QueryDenomByNameResponse is the response type for the
Expand Down Expand Up @@ -18547,6 +18553,8 @@ paths:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
title: >-
QueryDenomResponse is the response type for the Query/Denom RPC
Expand Down Expand Up @@ -34390,6 +34398,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
nfts:
type: array
Expand Down Expand Up @@ -34419,6 +34429,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
chainmain.nft.v1.IDCollection:
type: object
Expand Down Expand Up @@ -34465,6 +34477,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
nfts:
type: array
Expand Down Expand Up @@ -34526,6 +34540,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
title: >-
QueryDenomByNameResponse is the response type for the Query/DenomByName
Expand All @@ -34544,6 +34560,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
title: QueryDenomResponse is the response type for the Query/Denom RPC method
chainmain.nft.v1.QueryDenomsResponse:
Expand All @@ -34562,6 +34580,8 @@ definitions:
type: string
creator:
type: string
uri:
type: string
title: Denom defines a type of NFT
pagination:
type: object
Expand Down
1 change: 1 addition & 0 deletions buf.work.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
version: v1
directories:
- proto
- third_party/ibc-go/proto
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.18

require (
cosmossdk.io/math v1.0.0-beta.3
github.com/armon/go-metrics v0.4.0
github.com/confluentinc/bincover v0.1.0
github.com/cosmos/cosmos-proto v1.0.0-alpha7
github.com/cosmos/cosmos-sdk v0.46.1
Expand Down Expand Up @@ -39,7 +40,6 @@ require (
github.com/99designs/keyring v1.2.1 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
github.com/Workiva/go-datastructures v1.0.53 // indirect
github.com/armon/go-metrics v0.4.0 // indirect
github.com/aws/aws-sdk-go v1.40.45 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
Expand Down
30 changes: 30 additions & 0 deletions integration_tests/configs/nft_transfer.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
local default = {
accounts: [
{
name: 'relayer',
coins: '100cro',
},
{
name: 'signer',
coins: '200cro',
},
],
genesis: {},
};
local validator = {
coins: '10cro',
staked: '10cro',
};

{
'ibc-0': default {
validators: [validator { base_port: 26650 }, validator],
},
'ibc-1': default {
validators: [validator { base_port: port } for port in [26750, 26760]],
},
'ibc-2': default {
validators: [validator { base_port: port } for port in [26850, 26860]],
},
relayer: {},
}
16 changes: 11 additions & 5 deletions integration_tests/ibc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ def search_target(query, key, chains):
return results


def start_and_wait_relayer(cluster, init_relayer=True):
def start_and_wait_relayer(
cluster,
port="transfer",
chains=["ibc-0", "ibc-1"],
start_relaying=True,
init_relayer=True,
):
relayer = wait_relayer_ready(cluster)
chains = ["ibc-0", "ibc-1"]
if init_relayer:
# create connection and channel
subprocess.run(
Expand All @@ -40,9 +45,9 @@ def start_and_wait_relayer(cluster, init_relayer=True):
"create",
"channel",
"--a-port",
"transfer",
port,
"--b-port",
"transfer",
port,
"--a-chain",
chains[0],
"--b-chain",
Expand All @@ -54,7 +59,8 @@ def start_and_wait_relayer(cluster, init_relayer=True):
)

# start relaying
cluster[chains[0]].supervisor.startProcess("relayer-demo")
if start_relaying:
cluster[chains[0]].supervisor.startProcess("relayer-demo")

query = relayer + ["query", "channels", "--chain"]
return search_target(query, "channel", chains)
Loading

0 comments on commit 3e3d7ee

Please sign in to comment.