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 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
10 changes: 4 additions & 6 deletions proto/panacea/datapool/v2/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ 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];
}

// Params define parameters of datapool module
Expand Down
12 changes: 6 additions & 6 deletions proto/panacea/datapool/v2/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ service Msg {
// SellData defines a method for selling data
rpc SellData(MsgSellData) returns (MsgSellDataResponse);

// BuyDataAccessNFT defines a method for buying data access NFT
rpc BuyDataAccessNFT(MsgBuyDataAccessNFT) returns (MsgBuyDataAccessNFTResponse);
// BuyDataPass defines a method for buying data access NFT
rpc BuyDataPass(MsgBuyDataPass) returns (MsgBuyDataPassResponse);

// RedeemDataAccessNFT defines a method for redeeming data access NFT to get data
rpc RedeemDataAccessNFT(MsgRedeemDataAccessNFT) returns (MsgRedeemDataAccessNFTResponse);
Expand Down Expand Up @@ -75,16 +75,16 @@ message MsgSellDataResponse {
cosmos.base.v1beta1.Coin accum_pool_share_token = 1; // denom: DP-{pood-id}
}

// MsgBuyDataAccessNFT defines the Msg/BuyDataAccessNFT request type.
message MsgBuyDataAccessNFT {
// MsgBuyDataPass defines the Msg/BuyDataPass request type.
message MsgBuyDataPass {
uint64 pool_id = 1;
uint64 round = 2;
cosmos.base.v1beta1.Coin payment = 3;
string buyer = 4; // 'panacea1' address of buyer
}

// MsgBuyDataAccessNFTResponse defines the Msg/BuyDataAccessNFT response type.
message MsgBuyDataAccessNFTResponse {
// MsgBuyDataPassResponse defines the Msg/BuyDataAccessNFT response type.
message MsgBuyDataPassResponse {
uint64 pool_id = 1;
uint64 round = 2;
uint64 nft_id = 3;
Expand Down
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.MsgBuyDataPass{
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
}
13 changes: 5 additions & 8 deletions x/datapool/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ 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)
}

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

// this line is used by starport scaffolding # ibc/genesis/init
Expand All @@ -38,18 +39,14 @@ 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)

Expand Down
25 changes: 13 additions & 12 deletions x/datapool/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var (
curator = 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,15 +32,15 @@ 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()

Expand All @@ -55,15 +56,15 @@ func (suite genesisTestSuite) TestDataPoolInitGenesis() {
// 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)
Expand All @@ -73,12 +74,12 @@ func (suite genesisTestSuite) TestDataPoolInitGenesis() {
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
Expand All @@ -91,21 +92,21 @@ func (suite genesisTestSuite) TestDataPoolExportGenesis() {
suite.Require().Len(genesisState.DataValidators, 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 Down
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.MsgBuyDataPass:
res, err := msgServer.BuyDataPass(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
16 changes: 14 additions & 2 deletions x/datapool/keeper/msg_server_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,20 @@ func (m msgServer) SellData(goCtx context.Context, msg *types.MsgSellData) (*typ
}, nil
}

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

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

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

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

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