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: implementation of MsgBuyDataAccessNFT Tx #306

Merged
merged 25 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from 17 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
17 changes: 11 additions & 6 deletions proto/panacea/datapool/v2/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ import "panacea/datapool/v2/pool.proto";

// GenesisState defines the datapool module's genesis state.
message GenesisState {
repeated panacea.datapool.v2.DataValidator data_validators = 1;
uint64 next_pool_number = 2;
repeated Pool pools = 3;
Params params = 4 [
(gogoproto.nullable) = false
];
repeated DataValidator data_validators = 1 [(gogoproto.nullable) = false];
uint64 next_pool_number = 2;
repeated Pool pools = 3 [(gogoproto.nullable) = false];
Params params = 4 [(gogoproto.nullable) = false];
repeated WhiteList white_lists = 5 [(gogoproto.nullable) = false];
}

// Params define parameters of datapool module
Expand All @@ -25,4 +24,10 @@ message Params {
];
uint64 data_pool_code_id = 2;
string data_pool_nft_contract_address = 3;
}

// WhiteList define white list of data pool
message WhiteList {
0xHansLee marked this conversation as resolved.
Show resolved Hide resolved
0xHansLee marked this conversation as resolved.
Show resolved Hide resolved
uint64 pool_id = 1;
string address = 2;
}
10 changes: 2 additions & 8 deletions types/testsuite/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/medibloc/panacea-core/v2/types/assets"
aolkeeper "github.com/medibloc/panacea-core/v2/x/aol/keeper"
aoltypes "github.com/medibloc/panacea-core/v2/x/aol/types"
burnkeeper "github.com/medibloc/panacea-core/v2/x/burn/keeper"
Expand Down Expand Up @@ -243,13 +242,8 @@ func (suite *TestSuite) SetupTest() {
)
suite.DataPoolMsgServer = datapoolkeeper.NewMsgServerImpl(suite.DataPoolKeeper)

dataPoolGenState := datapooltypes.GenesisState{
DataValidators: []*datapooltypes.DataValidator{},
NextPoolNumber: 1,
Pools: []*datapooltypes.Pool{},
Params: datapooltypes.Params{DataPoolDeposit: sdk.NewCoin(assets.MicroMedDenom, sdk.NewInt(1000000))},
}
datapool.InitGenesis(suite.Ctx, suite.DataPoolKeeper, dataPoolGenState)
dataPoolGenState := datapooltypes.DefaultGenesis()
datapool.InitGenesis(suite.Ctx, suite.DataPoolKeeper, *dataPoolGenState)
}

func (suite *TestSuite) BeforeTest(suiteName, testName string) {
Expand Down
2 changes: 2 additions & 0 deletions x/datapool/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,7 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(CmdUpdateDataValidator())
cmd.AddCommand(CmdCreatePool())
cmd.AddCommand(CmdSellData())
cmd.AddCommand(CmdBuyDataAccessNFT())

return cmd
}
48 changes: 47 additions & 1 deletion x/datapool/client/cli/txPool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"strconv"
"time"

"github.com/cosmos/cosmos-sdk/client"
Expand Down Expand Up @@ -176,4 +177,49 @@ func readCertificateFromFile(file string) (*types.DataValidationCertificate, err
}

return &cert, nil
}
}
func CmdBuyDataAccessNFT() *cobra.Command {
cmd := &cobra.Command{
Use: "buy-data-access-nft [pool ID] [round] [payment]",
Short: "buy data access NFT",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

buyer := clientCtx.GetFromAddress()

poolID, err := strconv.ParseUint(args[0], 10, 64)
if err != nil {
return err
}

round, err := strconv.ParseUint(args[1], 10, 64)
if err != nil {
return err
}

payment, err := sdk.ParseCoinNormalized(args[2])
if err != nil {
return err
}

msg := &types.MsgBuyDataAccessNFT{
PoolId: poolID,
Round: round,
Payment: &payment,
Buyer: buyer.String(),
}

if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)
return cmd
}
27 changes: 19 additions & 8 deletions x/datapool/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,22 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)
k.SetPoolNumber(ctx, genState.NextPoolNumber)

for _, dataValidator := range genState.DataValidators {
err := k.SetDataValidator(ctx, *dataValidator)
err := k.SetDataValidator(ctx, dataValidator)
if err != nil {
panic(err)
}
}

for _, pool := range genState.Pools {
k.SetPool(ctx, pool)
k.SetPool(ctx, &pool)
}

for _, whiteList := range genState.WhiteLists {
addr, err := sdk.AccAddressFromBech32(whiteList.Address)
if err != nil {
panic(err)
}
k.AddToWhiteList(ctx, whiteList.PoolId, addr)
}
// this line is used by starport scaffolding # genesis/module/init

Expand All @@ -38,21 +46,24 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState {
panic(err)
}

for _, val := range dataValidators {
genesis.DataValidators = append(genesis.DataValidators, &val)
}
genesis.DataValidators = append(genesis.DataValidators, dataValidators...)

pools, err := k.GetAllPools(ctx)
if err != nil {
panic(err)
}

for _, pool := range pools {
genesis.Pools = append(genesis.Pools, &pool)
}
genesis.Pools = append(genesis.Pools, pools...)

genesis.Params = k.GetParams(ctx)

whiteLists, err := k.GetAllWhiteLists(ctx)
if err != nil {
panic(err)
}

genesis.WhiteLists = append(genesis.WhiteLists, whiteLists...)

// this line is used by starport scaffolding # genesis/module/export

// this line is used by starport scaffolding # ibc/genesis/export
Expand Down
60 changes: 48 additions & 12 deletions x/datapool/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import (
var (
dataVal = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
curator = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
buyer = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
buyer2 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address())
NFTPrice = sdk.NewCoin(assets.MicroMedDenom, sdk.NewInt(10000000))
downloadPeriod = time.Duration(time.Second * 100000000)
poolID = uint64(1)
)

type genesisTestSuite struct {
Expand All @@ -31,81 +34,100 @@ func TestGenesisTestSuite(t *testing.T) {
}

func (suite genesisTestSuite) TestDataPoolInitGenesis() {
var dataValidators []*types.DataValidator
var dataValidators []types.DataValidator

dataValidator := makeSampleDataValidator()

dataValidators = append(dataValidators, dataValidator)

pool := makeSamplePool()

pools := []*types.Pool{pool}
pools := []types.Pool{pool}

params := types.DefaultParams()

whiteList := makeSampleWhiteList()

genState := &types.GenesisState{
DataValidators: dataValidators,
NextPoolNumber: 2,
Pools: pools,
Params: params,
WhiteLists: whiteList,
}

datapool.InitGenesis(suite.Ctx, suite.DataPoolKeeper, *genState)

// check data validator
dataValidatorFromKeeper, err := suite.DataPoolKeeper.GetDataValidator(suite.Ctx, dataVal)
suite.Require().NoError(err)
suite.Require().Equal(*dataValidator, dataValidatorFromKeeper)
suite.Require().Equal(dataValidator, dataValidatorFromKeeper)

// check the next pool number
suite.Require().Equal(uint64(2), suite.DataPoolKeeper.GetNextPoolNumber(suite.Ctx))

// check pool
poolFromKeeper, err := suite.DataPoolKeeper.GetPool(suite.Ctx, uint64(1))
suite.Require().NoError(err)
suite.Require().Equal(pool, poolFromKeeper)
suite.Require().Equal(pool, *poolFromKeeper)

// check params
paramsFromKeeper := suite.DataPoolKeeper.GetParams(suite.Ctx)
suite.Require().Equal(params, paramsFromKeeper)

// check white list
whiteListFromKeeper, err := suite.DataPoolKeeper.GetAllWhiteLists(suite.Ctx)
suite.Require().NoError(err)
suite.Require().Len(whiteListFromKeeper, 2)
}

func (suite genesisTestSuite) TestDataPoolExportGenesis() {
// register data validator
dataValidator := makeSampleDataValidator()
err := suite.DataPoolKeeper.SetDataValidator(suite.Ctx, *dataValidator)
err := suite.DataPoolKeeper.SetDataValidator(suite.Ctx, dataValidator)
suite.Require().NoError(err)

// create pool
pool := makeSamplePool()
suite.DataPoolKeeper.SetPool(suite.Ctx, pool)
suite.DataPoolKeeper.SetPool(suite.Ctx, &pool)
suite.DataPoolKeeper.SetPoolNumber(suite.Ctx, uint64(2))

// set params
suite.DataPoolKeeper.SetParams(suite.Ctx, types.DefaultParams())

// set white list
whiteList := makeSampleWhiteList()
for _, list := range whiteList {
addr, err := sdk.AccAddressFromBech32(list.Address)
suite.Require().NoError(err)
suite.DataPoolKeeper.AddToWhiteList(suite.Ctx, list.PoolId, addr)
}

genesisState := datapool.ExportGenesis(suite.Ctx, suite.DataPoolKeeper)
suite.Require().Equal(uint64(2), genesisState.NextPoolNumber)
suite.Require().Len(genesisState.Pools, 1)
suite.Require().Equal(types.DefaultParams(), genesisState.Params)
suite.Require().Len(genesisState.DataValidators, 1)
suite.Require().Len(genesisState.WhiteLists, 2)
suite.Require().Contains(genesisState.WhiteLists, whiteList[0])
suite.Require().Contains(genesisState.WhiteLists, whiteList[1])
}

func makeSampleDataValidator() *types.DataValidator {
return &types.DataValidator{
func makeSampleDataValidator() types.DataValidator {
return types.DataValidator{
Address: dataVal.String(),
Endpoint: "https://my-validator.org",
}
}

func makeSamplePool() *types.Pool {
return &types.Pool{
PoolId: 1,
func makeSamplePool() types.Pool {
return types.Pool{
PoolId: poolID,
PoolAddress: types.NewPoolAddress(uint64(1)).String(),
Round: 1,
PoolParams: makeSamplePoolParams(),
CurNumData: 0,
NumIssuedNfts: 0,
NumIssuedNfts: 1,
Status: types.PENDING,
Curator: curator.String(),
}
Expand All @@ -122,3 +144,17 @@ func makeSamplePoolParams() *types.PoolParams {
DownloadPeriod: &downloadPeriod,
}
}

func makeSampleWhiteList() []types.WhiteList {
whiteList1 := types.WhiteList{
PoolId: poolID,
Address: buyer.String(),
}

whiteList2 := types.WhiteList{
PoolId: poolID,
Address: buyer2.String(),
}

return []types.WhiteList{whiteList1, whiteList2}
}
3 changes: 3 additions & 0 deletions x/datapool/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgCreatePool:
res, err := msgServer.CreatePool(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgBuyDataAccessNFT:
res, err := msgServer.BuyDataAccessNFT(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgSellData:
res, err := msgServer.SellData(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
Expand Down
14 changes: 13 additions & 1 deletion x/datapool/keeper/msg_server_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,19 @@ func (m msgServer) SellData(goCtx context.Context, msg *types.MsgSellData) (*typ
}

func (m msgServer) BuyDataAccessNFT(goCtx context.Context, msg *types.MsgBuyDataAccessNFT) (*types.MsgBuyDataAccessNFTResponse, error) {
return &types.MsgBuyDataAccessNFTResponse{}, nil
ctx := sdk.UnwrapSDKContext(goCtx)

buyer, err := sdk.AccAddressFromBech32(msg.Buyer)
if err != nil {
return nil, err
}

err = m.Keeper.BuyDataAccessNFT(ctx, buyer, msg.PoolId, msg.Round, *msg.Payment)
if err != nil {
return nil, err
}

return &types.MsgBuyDataAccessNFTResponse{PoolId: msg.PoolId, Round: msg.Round}, nil
}

func (m msgServer) RedeemDataAccessNFT(goCtx context.Context, msg *types.MsgRedeemDataAccessNFT) (*types.MsgRedeemDataAccessNFTResponse, error) {
Expand Down
Loading