forked from cerc-io/laconicd-deprecated
Merge branch 'main' into sai/upgrade_cosmos_v0.46
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
# Auction Module CLI Commands
|
||||
|
||||
## Build the Chain
|
||||
|
||||
The following command builds the Ethermint daemon and places the binary in the `build` directory
|
||||
|
||||
```
|
||||
make build
|
||||
|
||||
```
|
||||
|
||||
## Setup the Chain
|
||||
|
||||
The following steps need to be followed only before running the chain for the first time.
|
||||
|
||||
1. Add the root key:
|
||||
```
|
||||
./build/chibaclonkd keys add root
|
||||
```
|
||||
Keep a note of the keyring passphrase if you set it.
|
||||
2. Init the chain:
|
||||
```
|
||||
./build/chibaclonkd init test-moniker --chain-id ethermint_9000-1
|
||||
```
|
||||
3. Add genesis account:
|
||||
```
|
||||
./build/chibaclonkd add-genesis-account $(./build/chibaclonkd keys show root -a) 1000000000000000000aphoton,1000000000000000000stake
|
||||
```
|
||||
4. Make a genesis tx:
|
||||
```
|
||||
./build/chibaclonkd gentx root 1000000000000000000stake --chain-id ethermint_9000-1
|
||||
```
|
||||
5. Collect gentxs:
|
||||
```
|
||||
./build/chibaclonkd collect-gentxs
|
||||
```
|
||||
|
||||
The chain can now be started using:
|
||||
|
||||
```
|
||||
./build/chibaclonkd start
|
||||
```
|
||||
|
||||
## Querying the Params
|
||||
|
||||
The following command will dislay the default params for the `auction` module:
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction params -o json | jq
|
||||
|
||||
{
|
||||
"params": {
|
||||
"commits_duration": "0s",
|
||||
"reveals_duration": "0s",
|
||||
"commit_fee": {
|
||||
"denom": "",
|
||||
"amount": "0"
|
||||
},
|
||||
"reveal_fee": {
|
||||
"denom": "",
|
||||
"amount": "0"
|
||||
},
|
||||
"minimum_bid": {
|
||||
"denom": "",
|
||||
"amount": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Auction TX CLI Commands
|
||||
|
||||
### Create Auction
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd tx auction create 100s 100s 10aphoton 10aphoton 1000aphoton --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
|
||||
Enter keyring passphrase:
|
||||
|
||||
{"body":{"messages":[{"@type":"/vulcanize.auction.v1beta1.MsgCreateAuction","commits_duration":"100s","reveals_duration":"100s","commit_fee":{"denom":"aphoton","amount":"10"},"reveal_fee":{"denom":"aphoton","amount":"10"},"minimum_bid":{"denom":"aphoton","amount":"1000"},"signer":"ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: ECAD6DF1ECA763FBD26EB7C2C0B77425FFE2FBEA2BEC57CE0FBC173AE0F45298
|
||||
```
|
||||
|
||||
### Commit Bid
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd tx auction commit-bid e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d 2000aphoton --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
|
||||
Enter keyring passphrase:
|
||||
|
||||
{"body":{"messages":[{"@type":"/vulcanize.auction.v1beta1.MsgCommitBid","auction_id":"e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d","commit_hash":"bafyreibt4twofrc3xi2es27cfrroy346iy6lr3gkw33i5dltkqqarlyltm","signer":"ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 71D8CF34026E32A3A34C2C2D4ADF25ABC8D7943A4619761BE27F196603D91B9D
|
||||
```
|
||||
|
||||
### Reveal Bid
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd tx auction reveal-bid e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d root-bafyreibt4twofrc3xi2es27cfrroy346iy6lr3gkw33i5dltkqqarlyltm.json --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
|
||||
Enter keyring passphrase:
|
||||
|
||||
{"body":{"messages":[{"@type":"/vulcanize.auction.v1beta1.MsgRevealBid","auction_id":"e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d","reveal":"7b2261756374696f6e4964223a2265376431346337653761366437353337636264623866626536326632326231353533633265663463653337303561646137633238663830666166326662653064222c22626964416d6f756e74223a22323030306170686f746f6e222c2262696464657241646472657373223a226574686d316c37637374777466326c76657632376b613637633233796b376d6d6a38616437746574707163222c22636861696e4964223a2265746865726d696e745f393030302d31222c226e6f697365223a22636c69666620737566666572206472616d6120676f7370656c2077656173656c207061706572206c696272617279206469736f726465722063757276652073706f74206375727461696e207a6562726120696e76657374206465766f74652072656e64657220636c6970207377616c6c6f77206d6f6e6b6579206f62736572766520726573706f6e7365206c696e6b206372616e6520766961626c6520736576656e227d","signer":"ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 4D1C0B3DDA4050F9BB32240FBD5234229E5C32543C1A0A78033B9531EB0CF8BA
|
||||
```
|
||||
|
||||
## Auction Query CLI Commands
|
||||
|
||||
### List Auctions
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction list
|
||||
|
||||
auctions:
|
||||
auctions:
|
||||
- commit_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
commits_end_time: "2021-09-30T07:57:07.933412800Z"
|
||||
create_time: "2021-09-30T07:55:27.933412800Z"
|
||||
id: e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
minimum_bid:
|
||||
amount: "1000"
|
||||
denom: aphoton
|
||||
owner_address: ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
reveal_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
reveals_end_time: "2021-09-30T07:58:47.933412800Z"
|
||||
status: commit
|
||||
winner_address: ""
|
||||
winning_bid:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
winning_price:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
pagination: null
|
||||
```
|
||||
|
||||
### Get Bid
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction get-bid e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0e ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
|
||||
bid:
|
||||
auction_id: e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
bid_amount:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
bidder_address: ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
commit_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
commit_hash: bafyreibt4twofrc3xi2es27cfrroy346iy6lr3gkw33i5dltkqqarlyltm
|
||||
commit_time: "2021-09-30T08:49:48.358878200Z"
|
||||
reveal_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
reveal_time: "0001-01-01T00:00:00Z"
|
||||
status: commit
|
||||
```
|
||||
|
||||
### Get All Bids for an Auction
|
||||
|
||||
```
|
||||
./build/chibaclonkd q auction get-bids e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
|
||||
bids:
|
||||
- auction_id: e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
bid_amount:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
bidder_address: ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
commit_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
commit_hash: bafyreibt4twofrc3xi2es27cfrroy346iy6lr3gkw33i5dltkqqarlyltm
|
||||
commit_time: "2021-09-30T08:49:48.358878200Z"
|
||||
reveal_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
reveal_time: "0001-01-01T00:00:00Z"
|
||||
status: commit
|
||||
```
|
||||
|
||||
### Get Auction by AuctionID
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction get e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
|
||||
auction:
|
||||
commit_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
commits_end_time: "2021-09-30T07:57:07.933412800Z"
|
||||
create_time: "2021-09-30T07:55:27.933412800Z"
|
||||
id: e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
minimum_bid:
|
||||
amount: "1000"
|
||||
denom: aphoton
|
||||
owner_address: ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
reveal_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
reveals_end_time: "2021-09-30T07:58:47.933412800Z"
|
||||
status: commit
|
||||
winner_address: ""
|
||||
winning_bid:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
winning_price:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
|
||||
```
|
||||
|
||||
### Get Auction by Bidder
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction query-by-owner ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
|
||||
auctions:
|
||||
auctions:
|
||||
- commit_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
commits_end_time: "2021-09-30T07:57:07.933412800Z"
|
||||
create_time: "2021-09-30T07:55:27.933412800Z"
|
||||
id: e7d14c7e7a6d7537cbdb8fbe62f22b1553c2ef4ce3705ada7c28f80faf2fbe0d
|
||||
minimum_bid:
|
||||
amount: "1000"
|
||||
denom: aphoton
|
||||
owner_address: ethm1l7cstwtf2lvev27ka67c23yk7mmj8ad7tetpqc
|
||||
reveal_fee:
|
||||
amount: "10"
|
||||
denom: aphoton
|
||||
reveals_end_time: "2021-09-30T07:58:47.933412800Z"
|
||||
status: commit
|
||||
winner_address: ""
|
||||
winning_bid:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
winning_price:
|
||||
amount: "0"
|
||||
denom: ""
|
||||
```
|
||||
|
||||
### Query Account Balance
|
||||
|
||||
```
|
||||
# ./build/chibaclonkd q auction balance
|
||||
|
||||
balance:
|
||||
- amount: "20"
|
||||
denom: aphoton
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
package auction
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/auction/keeper"
|
||||
)
|
||||
|
||||
// EndBlocker is called every block, returns updated validator set.
|
||||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
|
||||
k.EndBlockerProcessAuctions(ctx)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
func GetQueryCmd() *cobra.Command {
|
||||
auctionQueryCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName),
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
auctionQueryCmd.AddCommand(
|
||||
GetCmdList(),
|
||||
GetCmdGetAuction(),
|
||||
GetCmdGetBid(),
|
||||
GetCmdGetBids(),
|
||||
GetCmdAuctionsByBidder(),
|
||||
GetCmdAuctionsByOwner(),
|
||||
GetCmdQueryParams(),
|
||||
GetCmdBalance(),
|
||||
)
|
||||
|
||||
return auctionQueryCmd
|
||||
}
|
||||
|
||||
// GetCmdList queries all auctions.
|
||||
func GetCmdList() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List auctions.",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Auctions(cmd.Context(), &types.AuctionsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdGetBid queries an auction bid.
|
||||
func GetCmdGetBid() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get-bid [auction-id] [bidder]",
|
||||
Short: "Get auction bid.",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id := args[0]
|
||||
bidder := args[1]
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetBid(cmd.Context(), &types.BidRequest{AuctionId: id, Bidder: bidder})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdGetBids queries all auction bids.
|
||||
func GetCmdGetBids() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get-bids [auction-id]",
|
||||
Short: "Get all auction bids.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id := args[0]
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetBids(cmd.Context(), &types.BidsRequest{AuctionId: id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdGetAuction queries an auction.
|
||||
func GetCmdGetAuction() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [ID]",
|
||||
Short: "Get auction.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id := args[0]
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetAuction(cmd.Context(), &types.AuctionRequest{Id: id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdAuctionsByBidder queries auctions by bidder.
|
||||
func GetCmdAuctionsByBidder() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-by-bidder [address]",
|
||||
Short: "Query auctions by bidder.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
address := args[0]
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.AuctionsByBidder(cmd.Context(), &types.AuctionsByBidderRequest{BidderAddress: address})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdAuctionsByOwner queries auctions by owner
|
||||
func GetCmdAuctionsByOwner() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-by-owner [address]",
|
||||
Short: "Query auctions by owner/creator.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
address := args[0]
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.AuctionsByOwner(cmd.Context(), &types.AuctionsByOwnerRequest{OwnerAddress: address})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdQueryParams implements the params query command.
|
||||
func GetCmdQueryParams() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "params",
|
||||
Args: cobra.NoArgs,
|
||||
Short: "Query the current auction parameters information.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query values set as auction parameters.
|
||||
Example:
|
||||
$ %s query auction params
|
||||
`,
|
||||
version.AppName,
|
||||
),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.QueryParams(cmd.Context(), &types.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdBalance queries the auction module account balance.
|
||||
func GetCmdBalance() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "balance",
|
||||
Short: "Get auction module account balance.",
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Balance(cmd.Context(), &types.BalanceRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
|
||||
wnsUtils "github.com/tharsis/ethermint/utils"
|
||||
)
|
||||
|
||||
// GetTxCmd returns transaction commands for this module.
|
||||
func GetTxCmd() *cobra.Command {
|
||||
auctionTxCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Auction transactions subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
auctionTxCmd.AddCommand(
|
||||
GetCmdCreateAuction(),
|
||||
GetCmdCommitBid(),
|
||||
GetCmdRevealBid(),
|
||||
)
|
||||
|
||||
return auctionTxCmd
|
||||
}
|
||||
|
||||
func GetCmdCreateAuction() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "create [commits-duration] [reveals-duration] [commit-fee] [reveal-fee] [minimum-bid]",
|
||||
Short: "Create auction.",
|
||||
Args: cobra.ExactArgs(5),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commitsDuration, err := time.ParseDuration(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
revealsDuration, err := time.ParseDuration(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commitFee, err := sdk.ParseCoinNormalized(args[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
revealFee, err := sdk.ParseCoinNormalized(args[3])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minimumBid, err := sdk.ParseCoinNormalized(args[4])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params := types.Params{
|
||||
CommitsDuration: commitsDuration,
|
||||
RevealsDuration: revealsDuration,
|
||||
CommitFee: commitFee,
|
||||
RevealFee: revealFee,
|
||||
MinimumBid: minimumBid,
|
||||
}
|
||||
msg := types.NewMsgCreateAuction(params, clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdCommitBid is the CLI command for committing a bid.
|
||||
func GetCmdCommitBid() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "commit-bid [auction-id] [bid-amount]",
|
||||
Short: "Commit sealed bid.",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bidAmount, err := sdk.ParseCoinNormalized(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mnemonic, err := wnsUtils.GenerateMnemonic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chainID := viper.GetString("chain-id")
|
||||
auctionID := args[0]
|
||||
|
||||
reveal := map[string]interface{}{
|
||||
"chainId": chainID,
|
||||
"auctionId": auctionID,
|
||||
"bidderAddress": clientCtx.GetFromAddress().String(),
|
||||
"bidAmount": bidAmount.String(),
|
||||
"noise": mnemonic,
|
||||
}
|
||||
|
||||
commitHash, content, err := wnsUtils.GenerateHash(reveal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Save reveal file.
|
||||
ioutil.WriteFile(fmt.Sprintf("%s-%s.json", clientCtx.GetFromName(), commitHash), content, 0600)
|
||||
|
||||
msg := types.NewMsgCommitBid(auctionID, commitHash, clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdRevealBid is the CLI command for revealing a bid.
|
||||
func GetCmdRevealBid() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reveal-bid [auction-id] [reveal-file-path]",
|
||||
Short: "Reveal bid.",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
auctionID := args[0]
|
||||
revealFilePath := args[1]
|
||||
|
||||
revealBytes, err := ioutil.ReadFile(revealFilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgRevealBid(auctionID, hex.EncodeToString(revealBytes), clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlagsToCmd(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
)
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
|
||||
suite.Run(t, NewIntegrationTestSuite(cfg))
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/crypto/hd"
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
defaultAuctionID string
|
||||
}
|
||||
|
||||
var (
|
||||
ownerAccount = "owner"
|
||||
bidderAccount = "bidder"
|
||||
ownerAddress string
|
||||
bidderAddress string
|
||||
)
|
||||
|
||||
func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
|
||||
return &IntegrationTestSuite{cfg: cfg}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
var err error
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// setting up random owner and bidder accounts
|
||||
s.createAccountWithBalance(ownerAccount, &ownerAddress)
|
||||
s.createAccountWithBalance(bidderAccount, &bidderAddress)
|
||||
|
||||
s.defaultAuctionID = s.createAuctionAndBid(true, false)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) createAccountWithBalance(accountName string, accountAddress *string) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic(accountName, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.EthSecp256k1)
|
||||
sr.NoError(err)
|
||||
|
||||
val.ClientCtx.Keyring.SavePubKey(accountName, info.GetPubKey(), hd.EthSecp256k1Type)
|
||||
|
||||
newAddr := sdk.AccAddress(info.GetPubKey().Address())
|
||||
_, err = banktestutil.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
newAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200000))),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
)
|
||||
sr.NoError(err)
|
||||
*accountAddress = newAddr.String()
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
auctiontypes "github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
const (
|
||||
randomAuctionID = "randomAuctionID"
|
||||
randomBidderAddress = "randomBidderAddress"
|
||||
randomOwnerAddress = "randomOwnerAddress"
|
||||
)
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetAllAuctionsGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/auctions", val.APIAddress)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
url string
|
||||
errorMsg string
|
||||
isErrorExpected bool
|
||||
}{
|
||||
{
|
||||
"invalid request to get all auctions",
|
||||
reqUrl + randomAuctionID,
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid request to get all auctions",
|
||||
reqUrl,
|
||||
"",
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.msg, func() {
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
if tc.isErrorExpected {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var auctions auctiontypes.AuctionsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &auctions)
|
||||
sr.NotZero(len(auctions.Auctions.Auctions))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestQueryParamsGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/params", val.APIAddress)
|
||||
|
||||
suite.Run("valid request to get auction params", func() {
|
||||
resp, err := rest.GetRequest(reqUrl)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
var params auctiontypes.QueryParamsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, ¶ms)
|
||||
|
||||
sr.NoError(err)
|
||||
sr.Equal(*params.GetParams(), auctiontypes.DefaultParams())
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetAuctionGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/auctions/", val.APIAddress)
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
url string
|
||||
errorMsg string
|
||||
isErrorExpected bool
|
||||
preRun func() string
|
||||
}{
|
||||
{
|
||||
"invalid request to get an auction",
|
||||
reqUrl + randomAuctionID,
|
||||
"",
|
||||
true,
|
||||
func() string { return "" },
|
||||
},
|
||||
{
|
||||
"valid request to get an auction",
|
||||
reqUrl,
|
||||
"",
|
||||
false,
|
||||
func() string { return suite.defaultAuctionID },
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.msg, func() {
|
||||
auctionID := tc.preRun()
|
||||
resp, err := rest.GetRequest(tc.url + auctionID)
|
||||
if tc.isErrorExpected {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var auction auctiontypes.AuctionResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &auction)
|
||||
sr.NoError(err)
|
||||
sr.Equal(auctionID, auction.Auction.Id)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetBidsGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/bids/", val.APIAddress)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
url string
|
||||
errorMsg string
|
||||
isErrorExpected bool
|
||||
preRun func() string
|
||||
}{
|
||||
{
|
||||
"invalid request to get all bids",
|
||||
reqUrl,
|
||||
"",
|
||||
true,
|
||||
func() string { return "" },
|
||||
},
|
||||
{
|
||||
"valid request to get all bids",
|
||||
reqUrl,
|
||||
"",
|
||||
false,
|
||||
func() string { return suite.createAuctionAndBid(false, true) },
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.msg, func() {
|
||||
auctionID := tc.preRun()
|
||||
tc.url += auctionID
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
if tc.isErrorExpected {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var bids auctiontypes.BidsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bids)
|
||||
sr.NoError(err)
|
||||
sr.Equal(auctionID, bids.Bids[0].AuctionId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetBidGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/bids/", val.APIAddress)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
url string
|
||||
errorMsg string
|
||||
isErrorExpected bool
|
||||
}{
|
||||
{
|
||||
"invalid request to get bid",
|
||||
fmt.Sprintf("%s/%s/", reqUrl, randomAuctionID),
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid request to get bid",
|
||||
fmt.Sprintf("%s/%s/%s", reqUrl, randomAuctionID, randomBidderAddress),
|
||||
"",
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.msg, func() {
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
if tc.isErrorExpected {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var bid auctiontypes.BidResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bid)
|
||||
sr.NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetAuctionsByOwnerGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/by-owner/", val.APIAddress)
|
||||
testCases := []struct {
|
||||
msg string
|
||||
url string
|
||||
errorMsg string
|
||||
isErrorExpected bool
|
||||
}{
|
||||
{
|
||||
"invalid request to get auctions by owner",
|
||||
reqUrl,
|
||||
"",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"valid request to get auctions by owner",
|
||||
fmt.Sprintf("%s/%s", reqUrl, randomOwnerAddress),
|
||||
"",
|
||||
false,
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
suite.Run(tc.msg, func() {
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
if tc.isErrorExpected {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var auctions auctiontypes.AuctionsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &auctions)
|
||||
sr.NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestQueryBalanceGrpc() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/auction/v1beta1/balance", val.APIAddress)
|
||||
msg := "valid request to get the auction module balance"
|
||||
|
||||
suite.createAuctionAndBid(false, true)
|
||||
|
||||
suite.Run(msg, func() {
|
||||
resp, err := rest.GetRequest(reqUrl)
|
||||
sr.NoError(err)
|
||||
|
||||
var response auctiontypes.BalanceResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetBalance()))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/auction/client/cli"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
var queryJSONFlag = []string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdQueryParams() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
suite.Run(fmt.Sprintf("Case %s", "fetch query params"), func() {
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdQueryParams(), queryJSONFlag)
|
||||
sr.NoError(err)
|
||||
var params types.QueryParamsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), ¶ms)
|
||||
sr.NoError(err)
|
||||
sr.Equal(types.DefaultParams(), *params.Params)
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdBalance() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
createAuctionAndBid bool
|
||||
}{
|
||||
{
|
||||
"fetch module balance without creating auction and bid",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"fetch module balance with valid auction and bid",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndBid {
|
||||
suite.createAuctionAndBid(false, true)
|
||||
}
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdBalance(), queryJSONFlag)
|
||||
sr.NoError(err)
|
||||
var balance types.BalanceResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &balance)
|
||||
sr.NoError(err)
|
||||
if test.createAuctionAndBid {
|
||||
sr.NotZero(len(balance.Balance))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdList() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
createAuction bool
|
||||
}{
|
||||
{
|
||||
"list auctions when no auctions exist",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"list auctions after creating an auction",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdList(), queryJSONFlag)
|
||||
sr.NoError(err)
|
||||
var auctions types.AuctionsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &auctions)
|
||||
sr.NoError(err)
|
||||
if test.createAuction {
|
||||
sr.NotZero(len(auctions.Auctions.Auctions))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdGetBid() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
args []string
|
||||
createAuctionAndBid bool
|
||||
}{
|
||||
{
|
||||
"get bid without creating auction",
|
||||
[]string{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"get bid after creating auction and bid",
|
||||
[]string{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndBid {
|
||||
auctionID := suite.createAuctionAndBid(false, true)
|
||||
test.args = append(test.args, auctionID)
|
||||
getBidsArgs := []string{auctionID, queryJSONFlag[0]}
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdGetBids(), getBidsArgs)
|
||||
sr.NoError(err)
|
||||
var bids types.BidsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &bids)
|
||||
sr.NoError(err)
|
||||
test.args = append(test.args, bids.GetBids()[0].BidderAddress)
|
||||
}
|
||||
|
||||
test.args = append(test.args, queryJSONFlag...)
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdGetBid(), test.args)
|
||||
if test.createAuctionAndBid {
|
||||
sr.NoError(err)
|
||||
var bid types.BidResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &bid)
|
||||
sr.NoError(err)
|
||||
sr.NotNil(bid.GetBid())
|
||||
} else {
|
||||
sr.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdGetBids() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
args []string
|
||||
createAuctionAndBid bool
|
||||
}{
|
||||
{
|
||||
"get bids without creating auction",
|
||||
[]string{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"get bids after creating auction and bid",
|
||||
[]string{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndBid {
|
||||
auctionID := suite.createAuctionAndBid(false, true)
|
||||
test.args = append(test.args, auctionID)
|
||||
}
|
||||
|
||||
test.args = append(test.args, queryJSONFlag...)
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdGetBids(), test.args)
|
||||
if test.createAuctionAndBid {
|
||||
sr.NoError(err)
|
||||
var bids types.BidsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &bids)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(bids.Bids))
|
||||
} else {
|
||||
sr.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdGetAuction() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
auctionID string
|
||||
createAuction bool
|
||||
}{
|
||||
{
|
||||
"get auction with empty auction ID",
|
||||
"",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"get auction with valid auction ID",
|
||||
"",
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuction {
|
||||
test.auctionID = suite.defaultAuctionID
|
||||
}
|
||||
|
||||
args := []string{test.auctionID, queryJSONFlag[0]}
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdGetAuction(), args)
|
||||
if test.createAuction {
|
||||
sr.NoError(err)
|
||||
var auction types.AuctionResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &auction)
|
||||
sr.NoError(err)
|
||||
sr.NotNil(auction.GetAuction())
|
||||
sr.Equal(test.auctionID, auction.GetAuction().Id)
|
||||
} else {
|
||||
sr.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestGetCmdAuctionsByBidder() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
createAuctionAndBid bool
|
||||
bidderAddress string
|
||||
}{
|
||||
{
|
||||
"get auctions by bidder without creating auctions",
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"get auctions by bidder for valid bidder address",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndBid {
|
||||
auctionID := suite.createAuctionAndBid(false, true)
|
||||
args := []string{auctionID, queryJSONFlag[0]}
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdGetBids(), args)
|
||||
sr.NoError(err)
|
||||
var bids types.BidsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &bids)
|
||||
sr.NoError(err)
|
||||
test.bidderAddress = bids.Bids[0].BidderAddress
|
||||
}
|
||||
|
||||
getByBidderArgs := []string{test.bidderAddress, queryJSONFlag[0]}
|
||||
_, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdAuctionsByBidder(), getByBidderArgs)
|
||||
if test.createAuctionAndBid {
|
||||
sr.NoError(err)
|
||||
} else {
|
||||
sr.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite IntegrationTestSuite) createAuctionAndBid(createAuction, createBid bool) string {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
auctionID := ""
|
||||
|
||||
if createAuction {
|
||||
auctionArgs := []string{
|
||||
sampleCommitTime, sampleRevealTime,
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("100%s", suite.cfg.BondDenom),
|
||||
}
|
||||
|
||||
resp, err := suite.executeTx(cli.GetCmdCreateAuction(), auctionArgs, ownerAccount)
|
||||
sr.NoError(err)
|
||||
sr.Zero(resp.Code)
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdList(), queryJSONFlag)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.AuctionsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
auctionID = queryResponse.Auctions.Auctions[0].Id
|
||||
} else {
|
||||
auctionID = suite.defaultAuctionID
|
||||
}
|
||||
|
||||
if createBid {
|
||||
bidArgs := []string{auctionID, fmt.Sprintf("200%s", suite.cfg.BondDenom)}
|
||||
resp, err := suite.executeTx(cli.GetCmdCommitBid(), bidArgs, bidderAccount)
|
||||
sr.NoError(err)
|
||||
sr.Zero(resp.Code)
|
||||
}
|
||||
|
||||
return auctionID
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/spf13/cobra"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/auction/client/cli"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
const (
|
||||
sampleCommitTime = "90s"
|
||||
sampleRevealTime = "5s"
|
||||
placeholderAuctionID = "placeholder_auction_id"
|
||||
)
|
||||
|
||||
func (suite *IntegrationTestSuite) TestTxCreateAuction() {
|
||||
sr := suite.Require()
|
||||
testCases := []struct {
|
||||
msg string
|
||||
args []string
|
||||
expectErr bool
|
||||
}{
|
||||
{
|
||||
"create auction with missing arguments",
|
||||
[]string{sampleCommitTime, sampleRevealTime},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"create auction with proper arguments",
|
||||
[]string{
|
||||
sampleCommitTime, sampleRevealTime,
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("100%s", suite.cfg.BondDenom),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
resp, err := suite.executeTx(cli.GetCmdCreateAuction(), test.args, ownerAccount)
|
||||
if test.expectErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.Zero(resp.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) TestTxCommitBid() {
|
||||
val := suite.network.Validators[0]
|
||||
sr := suite.Require()
|
||||
testCases := []struct {
|
||||
msg string
|
||||
args []string
|
||||
createAuction bool
|
||||
}{
|
||||
{
|
||||
"commit bid with missing args",
|
||||
[]string{fmt.Sprintf("200%s", suite.cfg.BondDenom)},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"commit bid with valid args",
|
||||
[]string{
|
||||
placeholderAuctionID,
|
||||
fmt.Sprintf("200%s", suite.cfg.BondDenom),
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuction {
|
||||
auctionArgs := []string{
|
||||
sampleCommitTime, sampleRevealTime,
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("10%s", suite.cfg.BondDenom),
|
||||
fmt.Sprintf("100%s", suite.cfg.BondDenom),
|
||||
}
|
||||
_, err := suite.executeTx(cli.GetCmdCreateAuction(), auctionArgs, ownerAccount)
|
||||
sr.NoError(err)
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cli.GetCmdList(),
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.AuctionsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
sr.NotNil(queryResponse.GetAuctions())
|
||||
test.args[0] = queryResponse.GetAuctions().Auctions[0].Id
|
||||
}
|
||||
|
||||
resp, err := suite.executeTx(cli.GetCmdCommitBid(), test.args, bidderAccount)
|
||||
if test.createAuction {
|
||||
sr.NoError(err)
|
||||
sr.Zero(resp.Code)
|
||||
} else {
|
||||
sr.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *IntegrationTestSuite) executeTx(cmd *cobra.Command, args []string, caller string) (sdk.TxResponse, error) {
|
||||
val := suite.network.Validators[0]
|
||||
additionalArgs := []string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, caller),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", suite.cfg.BondDenom)),
|
||||
}
|
||||
args = append(args, additionalArgs...)
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, cmd, args)
|
||||
if err != nil {
|
||||
return sdk.TxResponse{}, err
|
||||
}
|
||||
|
||||
var resp sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &resp)
|
||||
if err != nil {
|
||||
return sdk.TxResponse{}, err
|
||||
}
|
||||
|
||||
err = suite.network.WaitForNextBlock()
|
||||
if err != nil {
|
||||
return sdk.TxResponse{}, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package auction
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/keeper"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
// func NewGenesisState(params types.Params, auctions []types.Auction) types.GenesisState {
|
||||
// return types.GenesisState{Params: params, Auctions: &types.Auctions{Auctions: auctions}}
|
||||
// }
|
||||
|
||||
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data types.GenesisState) []abci.ValidatorUpdate {
|
||||
keeper.SetParams(ctx, data.Params)
|
||||
|
||||
for _, auction := range data.Auctions {
|
||||
keeper.SaveAuction(ctx, auction)
|
||||
}
|
||||
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) types.GenesisState {
|
||||
params := keeper.GetParams(ctx)
|
||||
auctions := keeper.ListAuctions(ctx)
|
||||
|
||||
var genesisAuctions []*types.Auction
|
||||
for _, auction := range auctions {
|
||||
genesisAuctions = append(genesisAuctions, &auction)
|
||||
}
|
||||
return types.GenesisState{Params: params, Auctions: genesisAuctions}
|
||||
}
|
||||
|
||||
func ValidateGenesis(data types.GenesisState) error {
|
||||
err := data.Params.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
type Querier struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
var _ types.QueryServer = Querier{}
|
||||
|
||||
// Auctions queries all auctions
|
||||
func (q Querier) Auctions(c context.Context, req *types.AuctionsRequest) (*types.AuctionsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
resp := q.Keeper.ListAuctions(ctx)
|
||||
return &types.AuctionsResponse{Auctions: &types.Auctions{Auctions: resp}}, nil
|
||||
}
|
||||
|
||||
// GetAuction queries an auction
|
||||
func (q Querier) GetAuction(c context.Context, req *types.AuctionRequest) (*types.AuctionResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
if req.Id == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "auction ID is required")
|
||||
}
|
||||
|
||||
resp := q.Keeper.GetAuction(ctx, req.Id)
|
||||
return &types.AuctionResponse{Auction: resp}, nil
|
||||
}
|
||||
|
||||
// GetBid queries and auction bid
|
||||
func (q Querier) GetBid(c context.Context, req *types.BidRequest) (*types.BidResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
if req.AuctionId == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "auction ID is required")
|
||||
}
|
||||
if req.Bidder == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bidder address is required")
|
||||
}
|
||||
resp := q.Keeper.GetBid(ctx, req.AuctionId, req.Bidder)
|
||||
return &types.BidResponse{Bid: &resp}, nil
|
||||
}
|
||||
|
||||
// GetBids queries all auction bids
|
||||
func (q Querier) GetBids(c context.Context, req *types.BidsRequest) (*types.BidsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
if req.AuctionId == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "auction ID is required")
|
||||
}
|
||||
resp := q.Keeper.GetBids(ctx, req.AuctionId)
|
||||
return &types.BidsResponse{Bids: resp}, nil
|
||||
}
|
||||
|
||||
// AuctionsByBidder queries auctions by bidder
|
||||
func (q Querier) AuctionsByBidder(c context.Context, req *types.AuctionsByBidderRequest) (*types.AuctionsByBidderResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
if req.BidderAddress == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bidder address is required")
|
||||
}
|
||||
resp := q.Keeper.QueryAuctionsByBidder(ctx, req.BidderAddress)
|
||||
return &types.AuctionsByBidderResponse{Auctions: &types.Auctions{Auctions: resp}}, nil
|
||||
}
|
||||
|
||||
// AuctionsByOwner queries auctions by owner
|
||||
func (q Querier) AuctionsByOwner(c context.Context, req *types.AuctionsByOwnerRequest) (*types.AuctionsByOwnerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
if req.OwnerAddress == "" {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "owner address is required")
|
||||
}
|
||||
resp := q.Keeper.QueryAuctionsByOwner(ctx, req.OwnerAddress)
|
||||
return &types.AuctionsByOwnerResponse{Auctions: &types.Auctions{Auctions: resp}}, nil
|
||||
}
|
||||
|
||||
// QueryParams implements the params query command
|
||||
func (q Querier) QueryParams(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
resp := q.Keeper.GetParams(ctx)
|
||||
return &types.QueryParamsResponse{Params: &resp}, nil
|
||||
}
|
||||
|
||||
// Balance queries the auction module account balance
|
||||
func (q Querier) Balance(c context.Context, req *types.BalanceRequest) (*types.BalanceResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
resp := q.Keeper.GetAuctionModuleBalances(ctx)
|
||||
return &types.BalanceResponse{Balance: resp}, nil
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/app"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
const testCommitHash = "71D8CF34026E32A3A34C2C2D4ADF25ABC8D7943A4619761BE27F196603D91B9D"
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetAllAuctions() {
|
||||
client, ctx, k := suite.queryClient, suite.ctx, suite.app.AuctionKeeper
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.AuctionsRequest
|
||||
createAuctions bool
|
||||
auctionCount int
|
||||
}{
|
||||
{
|
||||
"fetch auctions when no auctions exist",
|
||||
&types.AuctionsRequest{},
|
||||
false,
|
||||
0,
|
||||
},
|
||||
|
||||
{
|
||||
"fetch auctions with one auction created",
|
||||
&types.AuctionsRequest{},
|
||||
true,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctions {
|
||||
account := app.CreateRandomAccounts(1)[0]
|
||||
err := simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(
|
||||
sdk.Coin{Amount: sdk.NewInt(100), Denom: sdk.DefaultBondDenom},
|
||||
))
|
||||
|
||||
_, err = k.CreateAuction(ctx, types.NewMsgCreateAuction(k.GetParams(ctx), account))
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
resp, _ := client.Auctions(context.Background(), test.req)
|
||||
suite.Require().Equal(test.auctionCount, len(resp.GetAuctions().Auctions))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryParams() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryParamsRequest
|
||||
}{
|
||||
{
|
||||
"fetch params",
|
||||
&types.QueryParamsRequest{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
resp, err := suite.queryClient.QueryParams(context.Background(), test.req)
|
||||
suite.Require().Nil(err)
|
||||
suite.Require().Equal(*(resp.Params), types.DefaultParams())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetAuction() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.AuctionRequest
|
||||
createAuction bool
|
||||
}{
|
||||
{
|
||||
"fetch auction with empty auction ID",
|
||||
&types.AuctionRequest{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"fetch auction with valid auction ID",
|
||||
&types.AuctionRequest{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuction {
|
||||
auction, _, err := suite.createAuctionAndCommitBid(false)
|
||||
suite.Require().NoError(err)
|
||||
test.req.Id = auction.Id
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.GetAuction(context.Background(), test.req)
|
||||
if test.createAuction {
|
||||
suite.Require().Nil(err)
|
||||
suite.Require().NotNil(resp.GetAuction())
|
||||
suite.Require().Equal(test.req.Id, resp.GetAuction().Id)
|
||||
} else {
|
||||
suite.Require().NotNil(err)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetBids() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.BidsRequest
|
||||
createAuction bool
|
||||
commitBid bool
|
||||
bidCount int
|
||||
}{
|
||||
{
|
||||
"fetch all bids when no auction exists",
|
||||
&types.BidsRequest{},
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"fetch all bids for valid auction but no added bids",
|
||||
&types.BidsRequest{},
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"fetch all bids for valid auction and valid bid",
|
||||
&types.BidsRequest{},
|
||||
true,
|
||||
true,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuction {
|
||||
auction, _, err := suite.createAuctionAndCommitBid(test.commitBid)
|
||||
suite.Require().NoError(err)
|
||||
test.req.AuctionId = auction.Id
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.GetBids(context.Background(), test.req)
|
||||
if test.createAuction {
|
||||
suite.Require().Nil(err)
|
||||
suite.Require().Equal(test.bidCount, len(resp.GetBids()))
|
||||
} else {
|
||||
suite.Require().NotNil(err)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetBid() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.BidRequest
|
||||
createAuctionAndBid bool
|
||||
}{
|
||||
{
|
||||
"fetch bid when bid does not exist",
|
||||
&types.BidRequest{},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"fetch bid when valid bid exists",
|
||||
&types.BidRequest{},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndBid {
|
||||
auction, bid, err := suite.createAuctionAndCommitBid(test.createAuctionAndBid)
|
||||
suite.Require().NoError(err)
|
||||
test.req.AuctionId = auction.Id
|
||||
test.req.Bidder = bid.BidderAddress
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.GetBid(context.Background(), test.req)
|
||||
if test.createAuctionAndBid {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(resp.Bid)
|
||||
suite.Require().Equal(test.req.Bidder, resp.Bid.BidderAddress)
|
||||
} else {
|
||||
suite.Require().NotNil(err)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetAuctionsByBidder() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.AuctionsByBidderRequest
|
||||
createAuctionAndCommitBid bool
|
||||
auctionCount int
|
||||
}{
|
||||
{
|
||||
"get auctions by bidder with invalid bidder address",
|
||||
&types.AuctionsByBidderRequest{},
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"get auctions by bidder with valid auction and bid",
|
||||
&types.AuctionsByBidderRequest{},
|
||||
true,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuctionAndCommitBid {
|
||||
_, bid, err := suite.createAuctionAndCommitBid(test.createAuctionAndCommitBid)
|
||||
suite.Require().NoError(err)
|
||||
test.req.BidderAddress = bid.BidderAddress
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.AuctionsByBidder(context.Background(), test.req)
|
||||
if test.createAuctionAndCommitBid {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(resp.Auctions)
|
||||
suite.Require().Equal(test.auctionCount, len(resp.Auctions.Auctions))
|
||||
} else {
|
||||
suite.Require().NotNil(err)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetAuctionsByOwner() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.AuctionsByOwnerRequest
|
||||
createAuction bool
|
||||
auctionCount int
|
||||
}{
|
||||
{
|
||||
"get auctions by owner with invalid owner address",
|
||||
&types.AuctionsByOwnerRequest{},
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"get auctions by owner with valid auction",
|
||||
&types.AuctionsByOwnerRequest{},
|
||||
true,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s", test.msg), func() {
|
||||
if test.createAuction {
|
||||
auction, _, err := suite.createAuctionAndCommitBid(false)
|
||||
suite.Require().NoError(err)
|
||||
test.req.OwnerAddress = auction.OwnerAddress
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.AuctionsByOwner(context.Background(), test.req)
|
||||
if test.createAuction {
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().NotNil(resp.Auctions)
|
||||
suite.Require().Equal(test.auctionCount, len(resp.Auctions.Auctions))
|
||||
} else {
|
||||
suite.Require().NotNil(err)
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite KeeperTestSuite) TestGrpcQueryBalance() {
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.BalanceRequest
|
||||
createAuction bool
|
||||
auctionCount int
|
||||
}{
|
||||
{
|
||||
"get balance with no auctions created",
|
||||
&types.BalanceRequest{},
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"get balance with single auction created",
|
||||
&types.BalanceRequest{},
|
||||
true,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
if test.createAuction {
|
||||
_, _, err := suite.createAuctionAndCommitBid(true)
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
|
||||
resp, err := suite.queryClient.Balance(context.Background(), test.req)
|
||||
suite.Require().NoError(err)
|
||||
suite.Require().Equal(test.auctionCount, len(resp.GetBalance()))
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) createAuctionAndCommitBid(commitBid bool) (*types.Auction, *types.Bid, error) {
|
||||
ctx, k := suite.ctx, suite.app.AuctionKeeper
|
||||
accCount := 1
|
||||
if commitBid {
|
||||
accCount++
|
||||
}
|
||||
|
||||
accounts := app.CreateRandomAccounts(accCount)
|
||||
for _, account := range accounts {
|
||||
err := simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(
|
||||
sdk.Coin{Amount: sdk.NewInt(100), Denom: sdk.DefaultBondDenom},
|
||||
))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
|
||||
auction, err := k.CreateAuction(ctx, types.NewMsgCreateAuction(k.GetParams(ctx), accounts[0]))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if commitBid {
|
||||
bid, err := k.CommitBid(ctx, types.NewMsgCommitBid(auction.Id, testCommitHash, accounts[1]))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return auction, bid, nil
|
||||
}
|
||||
|
||||
return auction, nil, nil
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
// RegisterInvariants registers all auction module invariants.
|
||||
func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
|
||||
ir.RegisterRoute(types.ModuleName, "module-account", ModuleAccountInvariant(k))
|
||||
}
|
||||
|
||||
// ModuleAccountInvariant checks that the 'auction' module account balance is non-negative.
|
||||
func ModuleAccountInvariant(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(types.ModuleName)
|
||||
if k.bankKeeper.GetAllBalances(ctx, moduleAddress).IsAnyNegative() {
|
||||
return sdk.FormatInvariant(
|
||||
types.ModuleName,
|
||||
"module-account",
|
||||
fmt.Sprintf("Module account '%s' has negative balance.", types.ModuleName)),
|
||||
true
|
||||
}
|
||||
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
// AllInvariants runs all invariants of the auctions module.
|
||||
func AllInvariants(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
return ModuleAccountInvariant(k)(ctx)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,658 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
params "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
|
||||
wnsUtils "github.com/tharsis/ethermint/utils"
|
||||
)
|
||||
|
||||
// CompletedAuctionDeleteTimeout => Completed auctions are deleted after this timeout (after reveals end time).
|
||||
const CompletedAuctionDeleteTimeout = time.Hour * 24
|
||||
|
||||
// PrefixIDToAuctionIndex is the prefix for Id -> Auction index in the KVStore.
|
||||
// Note: This is the primary index in the system.
|
||||
// Note: Golang doesn't support const arrays.
|
||||
var PrefixIDToAuctionIndex = []byte{0x00}
|
||||
|
||||
// prefixOwnerToAuctionsIndex is the prefix for the Owner -> [Auction] index in the KVStore.
|
||||
var prefixOwnerToAuctionsIndex = []byte{0x01}
|
||||
|
||||
// PrefixAuctionBidsIndex is the prefix for the (auction, bidder) -> Bid index in the KVStore.
|
||||
var PrefixAuctionBidsIndex = []byte{0x02}
|
||||
|
||||
// PrefixBidderToAuctionsIndex is the prefix for the Bidder -> [Auction] index in the KVStore.
|
||||
var PrefixBidderToAuctionsIndex = []byte{0x03}
|
||||
|
||||
// Keeper maintains the link to storage and exposes getter/setter methods for the various parts of the state machine
|
||||
type Keeper struct {
|
||||
accountKeeper auth.AccountKeeper
|
||||
bankKeeper bank.Keeper
|
||||
|
||||
// Track auction usage in other cosmos-sdk modules (more like a usage tracker).
|
||||
usageKeepers []types.AuctionUsageKeeper
|
||||
|
||||
storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context
|
||||
|
||||
cdc codec.BinaryCodec // The wire codec for binary encoding/decoding.
|
||||
|
||||
paramSubspace params.Subspace
|
||||
}
|
||||
|
||||
// AuctionClientKeeper is the subset of functionality exposed to other modules.
|
||||
type AuctionClientKeeper interface {
|
||||
HasAuction(ctx sdk.Context, id string) bool
|
||||
GetAuction(ctx sdk.Context, id string) types.Auction
|
||||
MatchAuctions(ctx sdk.Context, matchFn func(*types.Auction) bool) []*types.Auction
|
||||
}
|
||||
|
||||
// NewKeeper creates new instances of the auction Keeper
|
||||
func NewKeeper(accountKeeper auth.AccountKeeper, bankKeeper bank.Keeper, storeKey sdk.StoreKey, cdc codec.BinaryCodec, ps params.Subspace) Keeper {
|
||||
if !ps.HasKeyTable() {
|
||||
ps = ps.WithKeyTable(types.ParamKeyTable())
|
||||
}
|
||||
|
||||
return Keeper{
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
paramSubspace: ps,
|
||||
}
|
||||
}
|
||||
|
||||
func (k *Keeper) SetUsageKeepers(usageKeepers []types.AuctionUsageKeeper) {
|
||||
k.usageKeepers = usageKeepers
|
||||
}
|
||||
|
||||
func (k Keeper) GetUsageKeepers() []types.AuctionUsageKeeper {
|
||||
return k.usageKeepers
|
||||
}
|
||||
|
||||
// Generates Auction Id -> Auction index key.
|
||||
func GetAuctionIndexKey(id string) []byte {
|
||||
return append(PrefixIDToAuctionIndex, []byte(id)...)
|
||||
}
|
||||
|
||||
// Generates Owner -> Auctions index key.
|
||||
func GetOwnerToAuctionsIndexKey(owner string, auctionID string) []byte {
|
||||
return append(append(prefixOwnerToAuctionsIndex, []byte(owner)...), []byte(auctionID)...)
|
||||
}
|
||||
|
||||
func GetBidderToAuctionsIndexKey(bidder string, auctionID string) []byte {
|
||||
return append(append(PrefixBidderToAuctionsIndex, []byte(bidder)...), []byte(auctionID)...)
|
||||
}
|
||||
|
||||
func GetBidIndexKey(auctionID string, bidder string) []byte {
|
||||
return append(GetAuctionBidsIndexPrefix(auctionID), []byte(bidder)...)
|
||||
}
|
||||
|
||||
func GetAuctionBidsIndexPrefix(auctionID string) []byte {
|
||||
return append(append(PrefixAuctionBidsIndex, []byte(auctionID)...))
|
||||
}
|
||||
|
||||
// SaveAuction - saves a auction to the store.
|
||||
func (k Keeper) SaveAuction(ctx sdk.Context, auction *types.Auction) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
// Auction Id -> Auction index.
|
||||
store.Set(GetAuctionIndexKey(auction.Id), k.cdc.MustMarshal(auction))
|
||||
|
||||
// Owner -> [Auction] index.
|
||||
store.Set(GetOwnerToAuctionsIndexKey(auction.OwnerAddress, auction.Id), []byte{})
|
||||
|
||||
// Notify interested parties.
|
||||
for _, keeper := range k.usageKeepers {
|
||||
keeper.OnAuction(ctx, auction.Id)
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) SaveBid(ctx sdk.Context, bid *types.Bid) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(GetBidIndexKey(bid.AuctionId, bid.BidderAddress), k.cdc.MustMarshal(bid))
|
||||
store.Set(GetBidderToAuctionsIndexKey(bid.BidderAddress, bid.AuctionId), []byte{})
|
||||
|
||||
// Notify interested parties.
|
||||
for _, keeper := range k.usageKeepers {
|
||||
keeper.OnAuctionBid(ctx, bid.AuctionId, bid.BidderAddress)
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) DeleteBid(ctx sdk.Context, bid types.Bid) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(GetBidIndexKey(bid.AuctionId, bid.BidderAddress))
|
||||
store.Delete(GetOwnerToAuctionsIndexKey(bid.BidderAddress, bid.AuctionId))
|
||||
}
|
||||
|
||||
// HasAuction - checks if a auction by the given Id exists.
|
||||
func (k Keeper) HasAuction(ctx sdk.Context, id string) bool {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return store.Has(GetAuctionIndexKey(id))
|
||||
}
|
||||
|
||||
func (k Keeper) HasBid(ctx sdk.Context, id string, bidder string) bool {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return store.Has(GetBidIndexKey(id, bidder))
|
||||
}
|
||||
|
||||
// DeleteAuction - deletes the auction.
|
||||
func (k Keeper) DeleteAuction(ctx sdk.Context, auction types.Auction) {
|
||||
// Delete all bids first.
|
||||
bids := k.GetBids(ctx, auction.Id)
|
||||
for _, bid := range bids {
|
||||
k.DeleteBid(ctx, *bid)
|
||||
}
|
||||
|
||||
// Delete the auction itself.
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(GetAuctionIndexKey(auction.Id))
|
||||
store.Delete(GetOwnerToAuctionsIndexKey(auction.OwnerAddress, auction.Id))
|
||||
}
|
||||
|
||||
// GetAuction - gets a record from the store.
|
||||
func (k Keeper) GetAuction(ctx sdk.Context, id string) *types.Auction {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
auctionKey := GetAuctionIndexKey(id)
|
||||
if !store.Has(auctionKey) {
|
||||
return nil
|
||||
}
|
||||
|
||||
bz := store.Get(auctionKey)
|
||||
var obj types.Auction
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
|
||||
return &obj
|
||||
}
|
||||
|
||||
// GetBids gets the auction bids.
|
||||
func (k Keeper) GetBids(ctx sdk.Context, id string) []*types.Bid {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bids := []*types.Bid{}
|
||||
itr := sdk.KVStorePrefixIterator(store, GetAuctionBidsIndexPrefix(id))
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Bid
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
bids = append(bids, &obj)
|
||||
}
|
||||
}
|
||||
|
||||
return bids
|
||||
}
|
||||
|
||||
func (k Keeper) GetBid(ctx sdk.Context, id string, bidder string) types.Bid {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
bz := store.Get(GetBidIndexKey(id, bidder))
|
||||
var obj types.Bid
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// ListAuctions - get all auctions.
|
||||
func (k Keeper) ListAuctions(ctx sdk.Context) []types.Auction {
|
||||
var auctions []types.Auction
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixIDToAuctionIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Auction
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
auctions = append(auctions, obj)
|
||||
}
|
||||
}
|
||||
|
||||
return auctions
|
||||
}
|
||||
|
||||
// QueryAuctionsByOwner - query auctions by owner.
|
||||
func (k Keeper) QueryAuctionsByOwner(ctx sdk.Context, ownerAddress string) []types.Auction {
|
||||
auctions := []types.Auction{}
|
||||
|
||||
ownerPrefix := append(prefixOwnerToAuctionsIndex, []byte(ownerAddress)...)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, ownerPrefix)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
auctionID := itr.Key()[len(ownerPrefix):]
|
||||
bz := store.Get(append(PrefixIDToAuctionIndex, auctionID...))
|
||||
if bz != nil {
|
||||
var obj types.Auction
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
auctions = append(auctions, obj)
|
||||
}
|
||||
}
|
||||
|
||||
return auctions
|
||||
}
|
||||
|
||||
// QueryAuctionsByBidder - query auctions by bidder
|
||||
func (k Keeper) QueryAuctionsByBidder(ctx sdk.Context, bidderAddress string) []types.Auction {
|
||||
auctions := []types.Auction{}
|
||||
|
||||
bidderPrefix := append(PrefixBidderToAuctionsIndex, []byte(bidderAddress)...)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, []byte(bidderPrefix))
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
auctionID := itr.Key()[len(bidderPrefix):]
|
||||
bz := store.Get(append(PrefixIDToAuctionIndex, auctionID...))
|
||||
if bz != nil {
|
||||
var obj types.Auction
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
auctions = append(auctions, obj)
|
||||
}
|
||||
}
|
||||
|
||||
return auctions
|
||||
}
|
||||
|
||||
// MatchAuctions - get all matching auctions.
|
||||
func (k Keeper) MatchAuctions(ctx sdk.Context, matchFn func(*types.Auction) bool) []*types.Auction {
|
||||
var auctions []*types.Auction
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixIDToAuctionIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Auction
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
if matchFn(&obj) {
|
||||
auctions = append(auctions, &obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return auctions
|
||||
}
|
||||
|
||||
// CreateAuction creates a new auction.
|
||||
func (k Keeper) CreateAuction(ctx sdk.Context, msg types.MsgCreateAuction) (*types.Auction, error) {
|
||||
// Might be called from another module directly, always validate.
|
||||
err := msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate auction Id.
|
||||
account := k.accountKeeper.GetAccount(ctx, signerAddress)
|
||||
if account == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "Account not found.")
|
||||
}
|
||||
|
||||
auctionID := types.AuctionID{
|
||||
Address: signerAddress,
|
||||
AccNum: account.GetAccountNumber(),
|
||||
Sequence: account.GetSequence(),
|
||||
}.Generate()
|
||||
|
||||
// Compute timestamps.
|
||||
now := ctx.BlockTime()
|
||||
commitsEndTime := now.Add(time.Duration(msg.CommitsDuration))
|
||||
revealsEndTime := now.Add(time.Duration(msg.CommitsDuration + msg.RevealsDuration))
|
||||
|
||||
auction := types.Auction{
|
||||
Id: auctionID,
|
||||
Status: types.AuctionStatusCommitPhase,
|
||||
OwnerAddress: signerAddress.String(),
|
||||
CreateTime: now,
|
||||
CommitsEndTime: commitsEndTime,
|
||||
RevealsEndTime: revealsEndTime,
|
||||
CommitFee: msg.CommitFee,
|
||||
RevealFee: msg.RevealFee,
|
||||
MinimumBid: msg.MinimumBid,
|
||||
}
|
||||
|
||||
// Save auction in store.
|
||||
k.SaveAuction(ctx, &auction)
|
||||
|
||||
return &auction, nil
|
||||
}
|
||||
|
||||
func (k Keeper) CommitBid(ctx sdk.Context, msg types.MsgCommitBid) (*types.Bid, error) {
|
||||
if !k.HasAuction(ctx, msg.AuctionId) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Auction not found.")
|
||||
}
|
||||
|
||||
auction := k.GetAuction(ctx, msg.AuctionId)
|
||||
if auction.Status != types.AuctionStatusCommitPhase {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Auction is not in commit phase.")
|
||||
}
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Take auction fees from account.
|
||||
totalFee := auction.CommitFee.Add(auction.RevealFee)
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, signerAddress, types.ModuleName, sdk.NewCoins(totalFee))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
|
||||
// Check if an old bid already exists, if so, return old bids auction fee (update bid scenario).
|
||||
bidder := signerAddress.String()
|
||||
if k.HasBid(ctx, msg.AuctionId, bidder) {
|
||||
oldBid := k.GetBid(ctx, msg.AuctionId, bidder)
|
||||
oldTotalFee := oldBid.CommitFee.Add(oldBid.RevealFee)
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, signerAddress, sdk.NewCoins(oldTotalFee))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
}
|
||||
|
||||
// Save new bid.
|
||||
bid := types.Bid{
|
||||
AuctionId: msg.AuctionId,
|
||||
BidderAddress: bidder,
|
||||
Status: types.BidStatusCommitted,
|
||||
CommitHash: msg.CommitHash,
|
||||
CommitTime: ctx.BlockTime(),
|
||||
CommitFee: auction.CommitFee,
|
||||
RevealFee: auction.RevealFee,
|
||||
}
|
||||
|
||||
k.SaveBid(ctx, &bid)
|
||||
|
||||
return &bid, nil
|
||||
}
|
||||
|
||||
// RevealBid reeals a bid comitted earlier.
|
||||
func (k Keeper) RevealBid(ctx sdk.Context, msg types.MsgRevealBid) (*types.Auction, error) {
|
||||
if !k.HasAuction(ctx, msg.AuctionId) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Auction not found.")
|
||||
}
|
||||
|
||||
auction := k.GetAuction(ctx, msg.AuctionId)
|
||||
if auction.Status != types.AuctionStatusRevealPhase {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Auction is not in reveal phase.")
|
||||
}
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !k.HasBid(ctx, msg.AuctionId, signerAddress.String()) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bid not found.")
|
||||
}
|
||||
|
||||
bid := k.GetBid(ctx, auction.Id, signerAddress.String())
|
||||
if bid.Status != types.BidStatusCommitted {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bid not in committed state.")
|
||||
}
|
||||
|
||||
revealBytes, err := hex.DecodeString(msg.Reveal)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal string.")
|
||||
}
|
||||
|
||||
cid, err := wnsUtils.CIDFromJSONBytes(revealBytes)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal JSON.")
|
||||
}
|
||||
|
||||
if bid.CommitHash != cid {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Commit hash mismatch.")
|
||||
}
|
||||
|
||||
var reveal map[string]interface{}
|
||||
err = json.Unmarshal(revealBytes, &reveal)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Reveal JSON unmarshal error.")
|
||||
}
|
||||
|
||||
chainID, err := wnsUtils.GetAttributeAsString(reveal, "chainId")
|
||||
if err != nil || chainID != ctx.ChainID() {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal chainID.")
|
||||
}
|
||||
|
||||
auctionID, err := wnsUtils.GetAttributeAsString(reveal, "auctionId")
|
||||
if err != nil || auctionID != msg.AuctionId {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal auction Id.")
|
||||
}
|
||||
|
||||
bidderAddress, err := wnsUtils.GetAttributeAsString(reveal, "bidderAddress")
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid address.")
|
||||
}
|
||||
|
||||
if bidderAddress != signerAddress.String() {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Reveal bid address mismatch.")
|
||||
}
|
||||
|
||||
bidAmountStr, err := wnsUtils.GetAttributeAsString(reveal, "bidAmount")
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid amount.")
|
||||
}
|
||||
|
||||
bidAmount, err := sdk.ParseCoinNormalized(bidAmountStr)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid reveal bid amount.")
|
||||
}
|
||||
|
||||
if bidAmount.IsLT(auction.MinimumBid) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bid is lower than minimum bid.")
|
||||
}
|
||||
|
||||
// Lock bid amount.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, signerAddress, types.ModuleName, sdk.NewCoins(bidAmount))
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
|
||||
// Update bid.
|
||||
bid.BidAmount = bidAmount
|
||||
bid.RevealTime = ctx.BlockTime()
|
||||
bid.Status = types.BidStatusRevealed
|
||||
k.SaveBid(ctx, &bid)
|
||||
|
||||
return auction, nil
|
||||
}
|
||||
|
||||
// GetAuctionModuleBalances gets the auction module account(s) balances.
|
||||
func (k Keeper) GetAuctionModuleBalances(ctx sdk.Context) sdk.Coins {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(types.ModuleName)
|
||||
balances := k.bankKeeper.GetAllBalances(ctx, moduleAddress)
|
||||
return balances
|
||||
}
|
||||
|
||||
func (k Keeper) EndBlockerProcessAuctions(ctx sdk.Context) {
|
||||
// Transition auction state (commit, reveal, expired, completed).
|
||||
k.processAuctionPhases(ctx)
|
||||
|
||||
// Delete stale auctions.
|
||||
k.deleteCompletedAuctions(ctx)
|
||||
}
|
||||
|
||||
func (k Keeper) processAuctionPhases(ctx sdk.Context) {
|
||||
auctions := k.MatchAuctions(ctx, func(_ *types.Auction) bool {
|
||||
return true
|
||||
})
|
||||
|
||||
for _, auction := range auctions {
|
||||
// Commit -> Reveal state.
|
||||
if auction.Status == types.AuctionStatusCommitPhase && ctx.BlockTime().After(auction.CommitsEndTime) {
|
||||
auction.Status = types.AuctionStatusRevealPhase
|
||||
k.SaveAuction(ctx, auction)
|
||||
ctx.Logger().Info(fmt.Sprintf("Moved auction %s to reveal phase.", auction.Id))
|
||||
}
|
||||
|
||||
// Reveal -> Expired state.
|
||||
if auction.Status == types.AuctionStatusRevealPhase && ctx.BlockTime().After(auction.RevealsEndTime) {
|
||||
auction.Status = types.AuctionStatusExpired
|
||||
k.SaveAuction(ctx, auction)
|
||||
ctx.Logger().Info(fmt.Sprintf("Moved auction %s to expired state.", auction.Id))
|
||||
}
|
||||
|
||||
// If auction has expired, pick a winner from revealed bids.
|
||||
if auction.Status == types.AuctionStatusExpired {
|
||||
k.pickAuctionWinner(ctx, auction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete completed stale auctions.
|
||||
func (k Keeper) deleteCompletedAuctions(ctx sdk.Context) {
|
||||
auctions := k.MatchAuctions(ctx, func(auction *types.Auction) bool {
|
||||
deleteTime := auction.RevealsEndTime.Add(CompletedAuctionDeleteTimeout)
|
||||
return auction.Status == types.AuctionStatusCompleted && ctx.BlockTime().After(deleteTime)
|
||||
})
|
||||
|
||||
for _, auction := range auctions {
|
||||
ctx.Logger().Info(fmt.Sprintf("Deleting completed auction %s after timeout.", auction.Id))
|
||||
k.DeleteAuction(ctx, *auction)
|
||||
}
|
||||
}
|
||||
|
||||
func (k Keeper) pickAuctionWinner(ctx sdk.Context, auction *types.Auction) {
|
||||
ctx.Logger().Info(fmt.Sprintf("Picking auction %s winner.", auction.Id))
|
||||
|
||||
var highestBid *types.Bid
|
||||
var secondHighestBid *types.Bid
|
||||
|
||||
bids := k.GetBids(ctx, auction.Id)
|
||||
for _, bid := range bids {
|
||||
ctx.Logger().Info(fmt.Sprintf("Processing bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
// Only consider revealed bids.
|
||||
if bid.Status != types.BidStatusRevealed {
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring unrevealed bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
continue
|
||||
}
|
||||
|
||||
// Init highest bid.
|
||||
if highestBid == nil {
|
||||
highestBid = bid
|
||||
ctx.Logger().Info(fmt.Sprintf("Initializing 1st bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
continue
|
||||
}
|
||||
|
||||
if highestBid.BidAmount.IsLT(bid.BidAmount) {
|
||||
ctx.Logger().Info(fmt.Sprintf("New highest bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
secondHighestBid = highestBid
|
||||
highestBid = bid
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 1st bid %s %s", highestBid.BidderAddress, highestBid.BidAmount.String()))
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 2nd bid %s %s", secondHighestBid.BidderAddress, secondHighestBid.BidAmount.String()))
|
||||
|
||||
} else if secondHighestBid == nil || secondHighestBid.BidAmount.IsLT(bid.BidAmount) {
|
||||
ctx.Logger().Info(fmt.Sprintf("New 2nd highest bid %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
|
||||
secondHighestBid = bid
|
||||
ctx.Logger().Info(fmt.Sprintf("Updated 2nd bid %s %s", secondHighestBid.BidderAddress, secondHighestBid.BidAmount.String()))
|
||||
} else {
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring bid as it doesn't affect 1st/2nd price %s %s", bid.BidderAddress, bid.BidAmount.String()))
|
||||
}
|
||||
}
|
||||
|
||||
// Highest bid is the winner, but pays second highest bid price.
|
||||
auction.Status = types.AuctionStatusCompleted
|
||||
|
||||
if highestBid != nil {
|
||||
auction.WinnerAddress = highestBid.BidderAddress
|
||||
auction.WinningBid = highestBid.BidAmount
|
||||
|
||||
// Winner pays 2nd price, if a 2nd price exists.
|
||||
auction.WinningPrice = highestBid.BidAmount
|
||||
if secondHighestBid != nil {
|
||||
auction.WinningPrice = secondHighestBid.BidAmount
|
||||
}
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner %s.", auction.Id, auction.WinnerAddress))
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner bid %s.", auction.Id, auction.WinningBid.String()))
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s winner price %s.", auction.Id, auction.WinningPrice.String()))
|
||||
|
||||
} else {
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s has no valid revealed bids (no winner).", auction.Id))
|
||||
}
|
||||
|
||||
k.SaveAuction(ctx, auction)
|
||||
|
||||
for _, bid := range bids {
|
||||
bidderAddress, err := sdk.AccAddressFromBech32(bid.BidderAddress)
|
||||
if err != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Invalid bidderAddress address. %v", err))
|
||||
panic("Invalid bidder address.")
|
||||
}
|
||||
|
||||
if bid.Status == types.BidStatusRevealed {
|
||||
// Send reveal fee back to bidders that've revealed the bid.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, bidderAddress, sdk.NewCoins(bid.RevealFee))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error returning reveal fee: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Send back locked bid amount to all bidders.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, bidderAddress, sdk.NewCoins(bid.BidAmount))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error returning bid amount: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Process winner account (if nobody bids, there won't be a winner).
|
||||
if auction.WinnerAddress != "" {
|
||||
winnerAddress, err := sdk.AccAddressFromBech32(auction.WinnerAddress)
|
||||
if err != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Invalid winner address. %v", err))
|
||||
panic("Invalid winner address.")
|
||||
}
|
||||
|
||||
// Take 2nd price from winner.
|
||||
sdkErr := k.bankKeeper.SendCoinsFromAccountToModule(ctx, winnerAddress, types.ModuleName, sdk.NewCoins(auction.WinningPrice))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error taking funds from winner: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
|
||||
// Burn anything over the min. bid amount.
|
||||
amountToBurn := auction.WinningPrice.Sub(auction.MinimumBid)
|
||||
if amountToBurn.IsNegative() {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction coins to burn cannot be negative."))
|
||||
panic("Auction coins to burn cannot be negative.")
|
||||
}
|
||||
|
||||
// Use auction burn module account instead of actually burning coins to better keep track of supply.
|
||||
sdkErr = k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, types.AuctionBurnModuleAccountName, sdk.NewCoins(amountToBurn))
|
||||
if sdkErr != nil {
|
||||
ctx.Logger().Error(fmt.Sprintf("Auction error burning coins: %v", sdkErr))
|
||||
panic(sdkErr)
|
||||
}
|
||||
}
|
||||
|
||||
// Notify other modules (hook).
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s notifying %d modules.", auction.Id, len(k.usageKeepers)))
|
||||
for _, keeper := range k.usageKeepers {
|
||||
ctx.Logger().Info(fmt.Sprintf("Auction %s notifying module %s.", auction.Id, keeper.ModuleName()))
|
||||
keeper.OnAuctionWinnerSelected(ctx, auction.Id)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
"github.com/tharsis/ethermint/app"
|
||||
auctionkeeper "github.com/tharsis/ethermint/x/auction/keeper"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
type KeeperTestSuite struct {
|
||||
suite.Suite
|
||||
app *app.EthermintApp
|
||||
ctx sdk.Context
|
||||
queryClient types.QueryClient
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
querier := auctionkeeper.Querier{Keeper: testApp.AuctionKeeper}
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, testApp.InterfaceRegistry())
|
||||
types.RegisterQueryServer(queryHelper, querier)
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
|
||||
suite.app, suite.ctx, suite.queryClient = testApp, ctx, queryClient
|
||||
}
|
||||
|
||||
func TestParams(t *testing.T) {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
expParams := types.DefaultParams()
|
||||
params := testApp.AuctionKeeper.GetParams(ctx)
|
||||
require.Equal(t, expParams.CommitsDuration, params.CommitsDuration)
|
||||
require.Equal(t, expParams.RevealsDuration, params.RevealsDuration)
|
||||
require.Equal(t, expParams.CommitFee, params.CommitFee)
|
||||
require.Equal(t, expParams.RevealFee, params.RevealFee)
|
||||
require.Equal(t, expParams.MinimumBid, params.MinimumBid)
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(KeeperTestSuite))
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
type msgServer struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
func NewMsgServer(keeper Keeper) types.MsgServer {
|
||||
return &msgServer{Keeper: keeper}
|
||||
}
|
||||
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
func (s msgServer) CreateAuction(c context.Context, msg *types.MsgCreateAuction) (*types.MsgCreateAuctionResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.Keeper.CreateAuction(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCreateAuction,
|
||||
sdk.NewAttribute(types.AttributeKeyCommitsDuration, msg.CommitsDuration.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyCommitFee, msg.CommitFee.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyRevealFee, msg.RevealFee.String()),
|
||||
sdk.NewAttribute(types.AttributeKeyMinimumBid, msg.MinimumBid.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, signerAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgCreateAuctionResponse{Auction: resp}, nil
|
||||
}
|
||||
|
||||
// CommitBid is the command for committing a bid
|
||||
func (s msgServer) CommitBid(c context.Context, msg *types.MsgCommitBid) (*types.MsgCommitBidResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.Keeper.CommitBid(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCommitBid,
|
||||
sdk.NewAttribute(types.AttributeKeyAuctionID, msg.AuctionId),
|
||||
sdk.NewAttribute(types.AttributeKeyCommitHash, msg.CommitHash),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, signerAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgCommitBidResponse{Bid: resp}, nil
|
||||
}
|
||||
|
||||
//RevealBid is the command for revealing a bid
|
||||
func (s msgServer) RevealBid(c context.Context, msg *types.MsgRevealBid) (*types.MsgRevealBidResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := s.Keeper.RevealBid(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRevealBid,
|
||||
sdk.NewAttribute(types.AttributeKeyAuctionID, msg.AuctionId),
|
||||
sdk.NewAttribute(types.AttributeKeyReveal, msg.Reveal),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, signerAddress.String()),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgRevealBidResponse{Auction: resp}, nil
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
// GetParams - Get all parameteras as types.Params.
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
k.paramSubspace.GetParamSet(ctx, ¶ms)
|
||||
return
|
||||
}
|
||||
|
||||
// SetParams - set the params.
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
k.paramSubspace.SetParamSet(ctx, ¶ms)
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package auction
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
|
||||
"github.com/tharsis/ethermint/x/auction/client/cli"
|
||||
"github.com/tharsis/ethermint/x/auction/keeper"
|
||||
"github.com/tharsis/ethermint/x/auction/types"
|
||||
)
|
||||
|
||||
// type check to ensure the interface is properly implemented
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// app module Basics object
|
||||
type AppModuleBasic struct {
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) Name() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
types.RegisterLegacyAminoCodec(cdc)
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
types.RegisterInterfaces(registry)
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) DefaultGenesis(jsonCodec codec.JSONCodec) json.RawMessage {
|
||||
return jsonCodec.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
// Validation check of the Genesis
|
||||
func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
err := cdc.UnmarshalJSON(bz, &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
||||
}
|
||||
// Once json successfully marshalled, passes along to genesis.go
|
||||
return ValidateGenesis(data)
|
||||
}
|
||||
|
||||
// Register rest routes
|
||||
func (b AppModuleBasic) RegisterRESTRoutes(ctx client.Context, rtr *mux.Router) {
|
||||
// No-op.
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, serveMux *runtime.ServeMux) {
|
||||
err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(clientCtx))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the root query command of this module
|
||||
func (b AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
}
|
||||
|
||||
// Get the root tx command of this module
|
||||
func (b AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.GetTxCmd()
|
||||
}
|
||||
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
keeper keeper.Keeper
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule Object
|
||||
func NewAppModule(cdc codec.Codec, k keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
||||
keeper: k,
|
||||
}
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {
|
||||
keeper.RegisterInvariants(ir, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) Route() sdk.Route {
|
||||
return sdk.Route{}
|
||||
}
|
||||
|
||||
func (am AppModule) QuerierRoute() string {
|
||||
return types.QuerierRoute
|
||||
}
|
||||
|
||||
func (am AppModule) LegacyQuerierHandler(cdc *codec.LegacyAmino) sdk.Querier {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
querier := keeper.Querier{Keeper: am.keeper}
|
||||
types.RegisterQueryServer(cfg.QueryServer(), querier)
|
||||
|
||||
msgServer := keeper.NewMsgServer(am.keeper)
|
||||
types.RegisterMsgServer(cfg.MsgServer(), msgServer)
|
||||
}
|
||||
|
||||
func (am AppModule) ConsensusVersion() uint64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) {}
|
||||
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return EndBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState types.GenesisState
|
||||
cdc.MustUnmarshalJSON(data, &genesisState)
|
||||
InitGenesis(ctx, am.keeper, genesisState)
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
||||
gs := ExportGenesis(ctx, am.keeper)
|
||||
return cdc.MustMarshalJSON(&gs)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package auction_test
|
||||
|
||||
// func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
|
||||
// app := app2.Setup(false)
|
||||
// ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
// app.InitChain(abcitypes.RequestInitChain{
|
||||
// AppStateBytes: []byte("{}"),
|
||||
// ChainId: "test-chain-id",
|
||||
// })
|
||||
|
||||
// acc := app.AccountKeeper.GetModuleAccount(ctx, auctiontypes.ModuleName)
|
||||
// require.NotNil(t, acc)
|
||||
// }
|
||||
@@ -0,0 +1,37 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
)
|
||||
|
||||
// RegisterLegacyAminoCodec registers the necessary x/auction interfaces and concrete types
|
||||
// on the provided LegacyAmino codec. These types are used for Amino JSON serialization.
|
||||
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
cdc.RegisterConcrete(&MsgCreateAuction{}, "auction/MsgCreateAuction", nil)
|
||||
cdc.RegisterConcrete(&MsgCommitBid{}, "auction/MsgCommitBid", nil)
|
||||
cdc.RegisterConcrete(&MsgRevealBid{}, "auction/MsgRevealBid", nil)
|
||||
}
|
||||
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterImplementations((*sdk.Msg)(nil),
|
||||
&MsgCreateAuction{},
|
||||
&MsgCommitBid{},
|
||||
&MsgRevealBid{},
|
||||
)
|
||||
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
|
||||
}
|
||||
|
||||
var (
|
||||
amino = codec.NewLegacyAmino()
|
||||
ModuleCdc = codec.NewAminoCodec(amino)
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterLegacyAminoCodec(amino)
|
||||
cryptocodec.RegisterCrypto(amino)
|
||||
amino.Seal()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
EventTypeCreateAuction = "create-auction"
|
||||
EventTypeCommitBid = "commit-bid"
|
||||
EventTypeRevealBid = "reveal-bid"
|
||||
|
||||
AttributeKeyCommitsDuration = "commits-duration"
|
||||
AttributeKeyRevealsDuration = "reveals-duration"
|
||||
AttributeKeyCommitFee = "commit-fee"
|
||||
AttributeKeyRevealFee = "reveal-fee"
|
||||
AttributeKeyMinimumBid = "minimum-bid"
|
||||
AttributeKeySigner = "signer"
|
||||
AttributeKeyAuctionID = "auction-id"
|
||||
AttributeKeyCommitHash = "commit-hash"
|
||||
AttributeKeyReveal = "reveal"
|
||||
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,16 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// AuctionUsageKeeper keep track of auction usage in other modules.
|
||||
// Used to, for example, prevent deletion of a auction that's in use.
|
||||
type AuctionUsageKeeper interface {
|
||||
ModuleName() string
|
||||
UsesAuction(ctx sdk.Context, auctionID string) bool
|
||||
|
||||
OnAuction(ctx sdk.Context, auctionID string)
|
||||
OnAuctionBid(ctx sdk.Context, auctionID string, bidderAddress string)
|
||||
OnAuctionWinnerSelected(ctx sdk.Context, auctionID string)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package types
|
||||
|
||||
// DefaultGenesisState sets default evm genesis state with empty accounts and default params and
|
||||
// chain config values.
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{
|
||||
Params: DefaultParams(),
|
||||
}
|
||||
}
|
||||
Generated
+389
@@ -0,0 +1,389 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: vulcanize/auction/v1beta1/genesis.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState defines the genesis state of the auction module
|
||||
type GenesisState struct {
|
||||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
|
||||
Auctions []*Auction `protobuf:"bytes,2,rep,name=auctions,proto3" json:"auctions,omitempty" json:"bonds" yaml:"bonds"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState) ProtoMessage() {}
|
||||
func (*GenesisState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_23ebfbd3a1e67fe6, []int{0}
|
||||
}
|
||||
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
|
||||
|
||||
func (m *GenesisState) GetParams() Params {
|
||||
if m != nil {
|
||||
return m.Params
|
||||
}
|
||||
return Params{}
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetAuctions() []*Auction {
|
||||
if m != nil {
|
||||
return m.Auctions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "vulcanize.auction.v1beta1.GenesisState")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("vulcanize/auction/v1beta1/genesis.proto", fileDescriptor_23ebfbd3a1e67fe6)
|
||||
}
|
||||
|
||||
var fileDescriptor_23ebfbd3a1e67fe6 = []byte{
|
||||
// 264 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2f, 0x2b, 0xcd, 0x49,
|
||||
0x4e, 0xcc, 0xcb, 0xac, 0x4a, 0xd5, 0x4f, 0x2c, 0x4d, 0x2e, 0xc9, 0xcc, 0xcf, 0xd3, 0x2f, 0x33,
|
||||
0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28,
|
||||
0xca, 0x2f, 0xc9, 0x17, 0x92, 0x84, 0x2b, 0xd4, 0x83, 0x2a, 0xd4, 0x83, 0x2a, 0x94, 0x12, 0x49,
|
||||
0xcf, 0x4f, 0xcf, 0x07, 0xab, 0xd2, 0x07, 0xb1, 0x20, 0x1a, 0xa4, 0x54, 0x71, 0x9b, 0x5c, 0x52,
|
||||
0x59, 0x90, 0x0a, 0x35, 0x57, 0x69, 0x1d, 0x23, 0x17, 0x8f, 0x3b, 0xc4, 0xa6, 0xe0, 0x92, 0xc4,
|
||||
0x92, 0x54, 0x21, 0x7b, 0x2e, 0xb6, 0x82, 0xc4, 0xa2, 0xc4, 0xdc, 0x62, 0x09, 0x46, 0x05, 0x46,
|
||||
0x0d, 0x6e, 0x23, 0x45, 0x3d, 0x9c, 0x36, 0xeb, 0x05, 0x80, 0x15, 0x3a, 0xb1, 0x9c, 0xb8, 0x27,
|
||||
0xcf, 0x10, 0x04, 0xd5, 0x26, 0x14, 0xcb, 0xc5, 0x01, 0x55, 0x57, 0x2c, 0xc1, 0xa4, 0xc0, 0xac,
|
||||
0xc1, 0x6d, 0xa4, 0x84, 0xc7, 0x08, 0x47, 0x08, 0xdf, 0x49, 0xf6, 0xd3, 0x3d, 0x79, 0xc9, 0xac,
|
||||
0xe2, 0xfc, 0x3c, 0x2b, 0xa5, 0xa4, 0xfc, 0xbc, 0x94, 0x62, 0x25, 0x85, 0xca, 0xc4, 0xdc, 0x1c,
|
||||
0x18, 0x27, 0x08, 0x6e, 0xa4, 0x93, 0xdb, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e,
|
||||
0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31,
|
||||
0x44, 0xe9, 0xa4, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x97, 0x64, 0x24,
|
||||
0x16, 0x15, 0x67, 0x16, 0xeb, 0xa7, 0x96, 0x64, 0xa4, 0x16, 0xe5, 0x66, 0xe6, 0x95, 0xe8, 0x57,
|
||||
0xc0, 0x83, 0x01, 0xec, 0xfd, 0x24, 0x36, 0xb0, 0xff, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff,
|
||||
0x40, 0x0a, 0x31, 0x1a, 0x82, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Auctions) > 0 {
|
||||
for iNdEx := len(m.Auctions) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Auctions[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
}
|
||||
{
|
||||
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovGenesis(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *GenesisState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.Params.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
if len(m.Auctions) > 0 {
|
||||
for _, e := range m.Auctions {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenesis(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozGenesis(x uint64) (n int) {
|
||||
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Auctions", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Auctions = append(m.Auctions, &Auction{})
|
||||
if err := m.Auctions[len(m.Auctions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenesis(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenesis
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// ModuleName is the name of the module
|
||||
ModuleName = "auction"
|
||||
|
||||
// AuctionBurnModuleAccountName is the name of the auction burn module account.
|
||||
AuctionBurnModuleAccountName = "auction_burn"
|
||||
|
||||
// StoreKey to be used when creating the KVStore
|
||||
StoreKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for the staking module
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// RouterKey is the msg router key for the staking module
|
||||
RouterKey = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,150 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgCreateAuction{}
|
||||
_ sdk.Msg = &MsgCommitBid{}
|
||||
_ sdk.Msg = &MsgRevealBid{}
|
||||
)
|
||||
|
||||
// NewMsgCreateAuction is the constructor function for MsgCreateAuction.
|
||||
func NewMsgCreateAuction(params Params, signer sdk.AccAddress) MsgCreateAuction {
|
||||
return MsgCreateAuction{
|
||||
CommitsDuration: params.CommitsDuration,
|
||||
RevealsDuration: params.RevealsDuration,
|
||||
CommitFee: params.CommitFee,
|
||||
RevealFee: params.RevealFee,
|
||||
MinimumBid: params.MinimumBid,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgCreateAuction) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgCreateAuction) Type() string { return "create" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgCreateAuction) ValidateBasic() error {
|
||||
if msg.Signer == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
|
||||
if msg.CommitsDuration <= 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commit phase duration invalid.")
|
||||
}
|
||||
|
||||
if msg.RevealsDuration <= 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "reveal phase duration invalid.")
|
||||
}
|
||||
|
||||
if !msg.MinimumBid.IsPositive() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "minimum bid should be greater than zero.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (msg MsgCreateAuction) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgCreateAuction) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgCommitBid is the constructor function for MsgCommitBid.
|
||||
func NewMsgCommitBid(auctionID string, commitHash string, signer sdk.AccAddress) MsgCommitBid {
|
||||
|
||||
return MsgCommitBid{
|
||||
AuctionId: auctionID,
|
||||
CommitHash: commitHash,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgCommitBid) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgCommitBid) Type() string { return "commit" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgCommitBid) ValidateBasic() error {
|
||||
if msg.Signer == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer address.")
|
||||
}
|
||||
|
||||
if msg.AuctionId == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid auction ID.")
|
||||
}
|
||||
|
||||
if msg.CommitHash == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid commit hash.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (msg MsgCommitBid) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgCommitBid) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgRevealBid is the constructor function for MsgRevealBid.
|
||||
func NewMsgRevealBid(auctionID string, reveal string, signer sdk.AccAddress) MsgRevealBid {
|
||||
|
||||
return MsgRevealBid{
|
||||
AuctionId: auctionID,
|
||||
Reveal: reveal,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgRevealBid) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgRevealBid) Type() string { return "reveal" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgRevealBid) ValidateBasic() error {
|
||||
if msg.Signer == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer address.")
|
||||
}
|
||||
|
||||
if msg.AuctionId == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid auction ID.")
|
||||
}
|
||||
|
||||
if msg.Reveal == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid reveal data.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes Implements Msg.
|
||||
func (msg MsgRevealBid) GetSignBytes() []byte {
|
||||
return sdk.MustSortJSON(ModuleCdc.MustMarshalJSON(&msg))
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgRevealBid) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
)
|
||||
|
||||
// Default parameter namespace.
|
||||
const (
|
||||
DefaultParamspace = ModuleName
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultCommitsDuration = 5 * time.Minute
|
||||
DefaultRevealsDuration = 5 * time.Minute
|
||||
DefaultCommitFee = sdk.Coin{Amount: sdk.NewInt(10), Denom: sdk.DefaultBondDenom}
|
||||
DefaultRevealFee = sdk.Coin{Amount: sdk.NewInt(10), Denom: sdk.DefaultBondDenom}
|
||||
DefaultMinimumBid = sdk.Coin{Amount: sdk.NewInt(1000), Denom: sdk.DefaultBondDenom}
|
||||
|
||||
ParamStoreKeyCommitsDuration = []byte("CommitsDuration")
|
||||
ParamStoreKeyRevealsDuration = []byte("RevealsDuration")
|
||||
ParamStoreKeyCommitFee = []byte("CommitFee")
|
||||
ParamStoreKeyRevealFee = []byte("RevealFee")
|
||||
ParamStoreKeyMinimumBid = []byte("MinimumBid")
|
||||
)
|
||||
|
||||
var _ types.ParamSet = &Params{}
|
||||
|
||||
func NewParams() Params {
|
||||
return DefaultParams()
|
||||
}
|
||||
|
||||
// ParamKeyTable - ParamTable for bond module.
|
||||
func ParamKeyTable() types.KeyTable {
|
||||
return types.NewKeyTable().RegisterParamSet(&Params{})
|
||||
}
|
||||
|
||||
// ParamSetPairs - implements params.ParamSet
|
||||
func (p *Params) ParamSetPairs() types.ParamSetPairs {
|
||||
return types.ParamSetPairs{
|
||||
types.NewParamSetPair(ParamStoreKeyCommitsDuration, &p.CommitsDuration, validateCommitsDuration),
|
||||
types.NewParamSetPair(ParamStoreKeyRevealsDuration, &p.RevealsDuration, validateRevealsDuration),
|
||||
types.NewParamSetPair(ParamStoreKeyCommitFee, &p.CommitFee, validateCommitFee),
|
||||
types.NewParamSetPair(ParamStoreKeyRevealFee, &p.RevealFee, validateRevealFee),
|
||||
types.NewParamSetPair(ParamStoreKeyMinimumBid, &p.MinimumBid, validateMinimumBid),
|
||||
}
|
||||
}
|
||||
|
||||
// Equal returns a boolean determining if two Params types are identical.
|
||||
func (p Params) Equal(p2 Params) bool {
|
||||
bz1 := ModuleCdc.MustMarshalLengthPrefixed(&p)
|
||||
bz2 := ModuleCdc.MustMarshalLengthPrefixed(&p2)
|
||||
return bytes.Equal(bz1, bz2)
|
||||
}
|
||||
|
||||
// DefaultParams returns a default set of parameters.
|
||||
func DefaultParams() Params {
|
||||
return Params{
|
||||
CommitsDuration: DefaultCommitsDuration,
|
||||
RevealsDuration: DefaultRevealsDuration,
|
||||
CommitFee: DefaultCommitFee,
|
||||
RevealFee: DefaultRevealFee,
|
||||
MinimumBid: DefaultMinimumBid,
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a human readable string representation of the parameters.
|
||||
func (p Params) String() string {
|
||||
var sb strings.Builder
|
||||
sb.WriteString("Params: \n")
|
||||
sb.WriteString(fmt.Sprintf("CommitsDuration: %s\n", p.CommitsDuration.String()))
|
||||
sb.WriteString(fmt.Sprintf("RevealsDuration: %s\n", p.RevealsDuration.String()))
|
||||
sb.WriteString(fmt.Sprintf("CommitFee: %s\n", p.CommitFee.String()))
|
||||
sb.WriteString(fmt.Sprintf("RevealFee: %s\n", p.RevealFee.String()))
|
||||
sb.WriteString(fmt.Sprintf("MinimumBid: %s\n", p.MinimumBid.String()))
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func validateCommitsDuration(i interface{}) error {
|
||||
v, ok := i.(time.Duration)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v < 0 {
|
||||
return errors.New("commits duration cannot be negative")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRevealsDuration(i interface{}) error {
|
||||
v, ok := i.(time.Duration)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v < 0 {
|
||||
return errors.New("commits duration cannot be negative")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateCommitFee(i interface{}) error {
|
||||
v, ok := i.(sdk.Coin)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v.Amount.IsNegative() {
|
||||
return errors.New("commit fee must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRevealFee(i interface{}) error {
|
||||
v, ok := i.(sdk.Coin)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v.Amount.IsNegative() {
|
||||
return errors.New("reveal fee must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateMinimumBid(i interface{}) error {
|
||||
v, ok := i.(sdk.Coin)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v.Amount.IsNegative() {
|
||||
return errors.New("minimum bid must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate a set of params.
|
||||
func (p Params) Validate() error {
|
||||
if err := validateCommitsDuration(p.CommitsDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateRevealsDuration(p.RevealsDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateCommitFee(p.CommitFee); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateRevealFee(p.RevealFee); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateMinimumBid(p.MinimumBid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
+3390
File diff suppressed because it is too large
Load Diff
Generated
+802
@@ -0,0 +1,802 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: vulcanize/auction/v1beta1/query.proto
|
||||
|
||||
/*
|
||||
Package types is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = descriptor.ForMessage
|
||||
|
||||
var (
|
||||
filter_Query_Auctions_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Query_Auctions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Auctions_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Auctions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Auctions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Auctions_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Auctions(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_GetAuction_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetAuction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetAuction_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetAuction(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_GetBid_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BidRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auction_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auction_id")
|
||||
}
|
||||
|
||||
protoReq.AuctionId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auction_id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["bidder"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bidder")
|
||||
}
|
||||
|
||||
protoReq.Bidder, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bidder", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetBid(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetBid_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BidRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auction_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auction_id")
|
||||
}
|
||||
|
||||
protoReq.AuctionId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auction_id", err)
|
||||
}
|
||||
|
||||
val, ok = pathParams["bidder"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bidder")
|
||||
}
|
||||
|
||||
protoReq.Bidder, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bidder", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetBid(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_GetBids_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BidsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auction_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auction_id")
|
||||
}
|
||||
|
||||
protoReq.AuctionId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auction_id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetBids(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetBids_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BidsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["auction_id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "auction_id")
|
||||
}
|
||||
|
||||
protoReq.AuctionId, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "auction_id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetBids(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_AuctionsByBidder_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsByBidderRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["bidder_address"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bidder_address")
|
||||
}
|
||||
|
||||
protoReq.BidderAddress, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bidder_address", err)
|
||||
}
|
||||
|
||||
msg, err := client.AuctionsByBidder(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_AuctionsByBidder_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsByBidderRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["bidder_address"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "bidder_address")
|
||||
}
|
||||
|
||||
protoReq.BidderAddress, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "bidder_address", err)
|
||||
}
|
||||
|
||||
msg, err := server.AuctionsByBidder(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_AuctionsByOwner_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsByOwnerRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["owner_address"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner_address")
|
||||
}
|
||||
|
||||
protoReq.OwnerAddress, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner_address", err)
|
||||
}
|
||||
|
||||
msg, err := client.AuctionsByOwner(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_AuctionsByOwner_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq AuctionsByOwnerRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["owner_address"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner_address")
|
||||
}
|
||||
|
||||
protoReq.OwnerAddress, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner_address", err)
|
||||
}
|
||||
|
||||
msg, err := server.AuctionsByOwner(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryParamsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.QueryParams(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_QueryParams_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryParamsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.QueryParams(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_Balance_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BalanceRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.Balance(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Balance_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq BalanceRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.Balance(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
|
||||
// UnaryRPC :call QueryServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
|
||||
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Auctions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Auctions_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Auctions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetAuction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetAuction_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetAuction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBid_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetBid_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBid_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBids_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetBids_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBids_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_AuctionsByBidder_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_AuctionsByBidder_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_AuctionsByBidder_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_AuctionsByOwner_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_AuctionsByOwner_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_AuctionsByOwner_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_QueryParams_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Balance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Balance_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Balance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterQueryHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterQueryHandler registers the http handlers for service Query to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerClient registers the http handlers for service Query
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "QueryClient" to call the correct interceptors.
|
||||
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Auctions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Auctions_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Auctions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetAuction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetAuction_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetAuction_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBid_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetBid_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBid_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBids_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetBids_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBids_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_AuctionsByBidder_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_AuctionsByBidder_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_AuctionsByBidder_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_AuctionsByOwner_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_AuctionsByOwner_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_AuctionsByOwner_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_QueryParams_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_QueryParams_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_QueryParams_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Balance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Balance_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Balance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_Query_Auctions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "auction", "v1beta1", "auctions"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetAuction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "auction", "v1beta1", "auctions", "id"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetBid_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"vulcanize", "auction", "v1beta1", "bids", "auction_id", "bidder"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetBids_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "auction", "v1beta1", "bids", "auction_id"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_AuctionsByBidder_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "auction", "v1beta1", "by-bidder", "bidder_address"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_AuctionsByOwner_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "auction", "v1beta1", "by-owner", "owner_address"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_QueryParams_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "auction", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_Balance_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "auction", "v1beta1", "balance"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_Query_Auctions_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetAuction_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetBid_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetBids_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_AuctionsByBidder_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_AuctionsByOwner_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_QueryParams_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_Balance_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
Generated
+1777
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// Auction status values.
|
||||
const (
|
||||
// Auction is in commit phase.
|
||||
AuctionStatusCommitPhase = "commit"
|
||||
|
||||
// Auction is in reveal phase.
|
||||
AuctionStatusRevealPhase = "reveal"
|
||||
|
||||
// Auction has ended (no reveals allowed).
|
||||
AuctionStatusExpired = "expired"
|
||||
|
||||
// Auction has completed (winner selected).
|
||||
AuctionStatusCompleted = "completed"
|
||||
)
|
||||
|
||||
// Bid status values.
|
||||
const (
|
||||
BidStatusCommitted = "commit"
|
||||
BidStatusRevealed = "reveal"
|
||||
)
|
||||
|
||||
// AuctionID simplifies generation of auction IDs.
|
||||
type AuctionID struct {
|
||||
Address sdk.Address
|
||||
AccNum uint64
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
// Generate creates the auction ID.
|
||||
func (auctionID AuctionID) Generate() string {
|
||||
hasher := sha256.New()
|
||||
str := fmt.Sprintf("%s:%d:%d", auctionID.Address.String(), auctionID.AccNum, auctionID.Sequence)
|
||||
hasher.Write([]byte(str))
|
||||
return hex.EncodeToString(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
func (auction Auction) GetCreateTime() string {
|
||||
return string(sdk.FormatTimeBytes(auction.CreateTime))
|
||||
}
|
||||
|
||||
func (auction Auction) GetCommitsEndTime() string {
|
||||
return string(sdk.FormatTimeBytes(auction.CommitsEndTime))
|
||||
}
|
||||
|
||||
func (auction Auction) GetRevealsEndTime() string {
|
||||
return string(sdk.FormatTimeBytes(auction.RevealsEndTime))
|
||||
}
|
||||
|
||||
func (bid Bid) GetCommitTime() string {
|
||||
return string(sdk.FormatTimeBytes(bid.CommitTime))
|
||||
}
|
||||
|
||||
func (bid Bid) GetRevealTime() string {
|
||||
return string(sdk.FormatTimeBytes(bid.RevealTime))
|
||||
}
|
||||
Generated
+1943
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,196 @@
|
||||
# Build chain
|
||||
```bash
|
||||
# it will create binary in build folder with `ethermintd`
|
||||
$ make build
|
||||
```
|
||||
# Setup Chain
|
||||
```bash
|
||||
./build/chibaclonkd keys add root
|
||||
./build/chibaclonkd init test-moniker --chain-id ethermint_9000-1
|
||||
./build/chibaclonkd add-genesis-account $(./build/chibaclonkd keys show root -a) 1000000000000000000aphoton,1000000000000000000stake
|
||||
./build/chibaclonkd gentx root 1000000000000000000stake --chain-id ethermint_9000-1
|
||||
./build/chibaclonkd collect-gentxs
|
||||
./build/chibaclonkd start
|
||||
```
|
||||
|
||||
# Params
|
||||
```
|
||||
$ ./build/chibaclonkd q bond params -o json | jq .
|
||||
|
||||
{
|
||||
"params": {
|
||||
"max_bond_amount": {
|
||||
"denom": "stake",
|
||||
"amount": "100000000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Create Bond
|
||||
```
|
||||
$ ./build/chibaclonkd tx bond create 100aphoton --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
|
||||
{"body":{"messages":[{"@type":"/vulcanize.bond.v1beta1.MsgCreateBond","signer":"ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk","coins":[{"denom":"aphoton","amount":"100"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: C6D362E11D4C9FB06D620F3CCAF363A69A074297A00E9CAECBDA5BE1CC302EB8
|
||||
```
|
||||
# Refill Bond
|
||||
```
|
||||
$ ./build/chibaclonkd tx bond refill c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 1000aphoton --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
{"body":{"messages":[{"@type":"/vulcanize.bond.v1beta1.MsgRefillBond","id":"c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440","signer":"ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk","coins":[{"denom":"aphoton","amount":"1000"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 025B04E2C923EFE2299CD171B40829CB1FE4D1A69DA7563C64AAC3D5C27BDFC9
|
||||
|
||||
```
|
||||
# Withdraw from bond
|
||||
```
|
||||
$ ./build/chibaclonkd tx bond withdraw c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 1000aphoton --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
{"body":{"messages":[{"@type":"/vulcanize.bond.v1beta1.MsgWithdrawBond","id":"c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440","signer":"ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk","coins":[{"denom":"aphoton","amount":"1000"}]}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 7C5E2FE674577CD6BFFF9F92FCCBC61EDFE8F1A00CE29AC84D58FB8F013D2F03
|
||||
```
|
||||
# List Bond
|
||||
```
|
||||
$ ./build/chibaclonkd q bond list -o json | jq .
|
||||
{
|
||||
"bonds": [
|
||||
{
|
||||
"id": "c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440",
|
||||
"owner": "ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk",
|
||||
"balance": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"pagination": null
|
||||
}
|
||||
|
||||
```
|
||||
# Get Bond by Id
|
||||
```
|
||||
$ ./build/chibaclonkd q bond get c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 -o json | jq .
|
||||
{
|
||||
"bond": {
|
||||
"id": "c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440",
|
||||
"owner": "ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk",
|
||||
"balance": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
# Get Bond Module Balance
|
||||
```
|
||||
$ ./build/chibaclonkd q bond balance -o json | jq .
|
||||
{
|
||||
"balance": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
# Get Bonds By Owner
|
||||
```
|
||||
$ ./build/chibaclonkd q bond by-owner ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk -o json | jq .
|
||||
{
|
||||
"bonds": [
|
||||
{
|
||||
"id": "c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440",
|
||||
"owner": "ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk",
|
||||
"balance": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "100"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"pagination": null
|
||||
}
|
||||
```
|
||||
|
||||
# Cancel the bond
|
||||
```
|
||||
$ ./build/chibaclonkd tx bond cancel c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 --from root --chain-id $(./build/chibaclonkd status | jq .NodeInfo.network -r)
|
||||
{"body":{"messages":[{"@type":"/vulcanize.bond.v1beta1.MsgCancelBond","id":"c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440","signer":"ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 06440D0B35A862E3A6783E147F0E1CDD3374870DAE07E471D465E2830DAF7044
|
||||
|
||||
```
|
||||
|
||||
Note : After the bond create and withdraw bond and cancel bond , account amount needs change as per module
|
||||
```
|
||||
$ ./build/chibaclonkd q bank balances $(./build/chibaclonkd keys show root -a) -o json | jq .
|
||||
{
|
||||
"balances": [
|
||||
{
|
||||
"denom": "aphoton",
|
||||
"amount": "1000000000000000000"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"next_key": null,
|
||||
"total": "0"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,17 @@
|
||||
package bond
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/bond/keeper"
|
||||
)
|
||||
|
||||
// BeginBlocker will persist the current header and validator set as a historical entry
|
||||
// and prune the oldest entry based on the HistoricalEntries parameter
|
||||
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
|
||||
}
|
||||
|
||||
// EndBlocker Called every block, update validator set
|
||||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd() *cobra.Command {
|
||||
bondQueryCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Querying commands for the bond module",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
bondQueryCmd.AddCommand(
|
||||
GetQueryParamsCmd(),
|
||||
GetQueryBondLists(),
|
||||
GetBondByIdCmd(),
|
||||
GetBondListByOwnerCmd(),
|
||||
GetBondModuleBalanceCmd(),
|
||||
)
|
||||
|
||||
return bondQueryCmd
|
||||
}
|
||||
|
||||
// GetQueryParamsCmd implements the params query command.
|
||||
func GetQueryParamsCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "params",
|
||||
Args: cobra.NoArgs,
|
||||
Short: "Query the current bond parameters information.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query values set as bond parameters.
|
||||
|
||||
Example:
|
||||
$ %s query %s params
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetQueryBondLists implements the bond lists query command.
|
||||
func GetQueryBondLists() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List bonds.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get bond list .
|
||||
|
||||
Example:
|
||||
$ %s query %s list
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Bonds(cmd.Context(), &types.QueryGetBondsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetBondByIdCmd implements the bond info by id query command.
|
||||
func GetBondByIdCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [bond Id]",
|
||||
Short: "Get bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get bond info by bond id .
|
||||
|
||||
Example:
|
||||
$ %s query bond get {BOND ID}
|
||||
`,
|
||||
version.AppName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
id := args[0]
|
||||
|
||||
res, err := queryClient.GetBondById(cmd.Context(), &types.QueryGetBondByIdRequest{Id: id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetBondListByOwnerCmd queries the bond list by owner.
|
||||
func GetBondListByOwnerCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "by-owner [address]",
|
||||
Short: "Query bonds by owner.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get bond list by owner.
|
||||
|
||||
Example:
|
||||
$ %s query %s query-by-owner [address]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
owner := args[0]
|
||||
res, err := queryClient.GetBondsByOwner(cmd.Context(), &types.QueryGetBondsByOwnerRequest{Owner: owner})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetBondModuleBalanceCmd queries the bond module account balance.
|
||||
func GetBondModuleBalanceCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "balance",
|
||||
Short: "Get bond module account balance.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get bond module balance.
|
||||
|
||||
Example:
|
||||
$ %s query %s balance
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
res, err := queryClient.GetBondsModuleBalance(cmd.Context(), &types.QueryGetBondModuleBalanceRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tharsis/ethermint/server/flags"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// NewTxCmd returns a root CLI command handler for all x/bond transaction commands.
|
||||
func NewTxCmd() *cobra.Command {
|
||||
bondTxCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "bond transaction subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
bondTxCmd.AddCommand(
|
||||
NewCreateBondCmd(),
|
||||
RefillBondCmd(),
|
||||
WithdrawBondCmd(),
|
||||
CancelBondCmd(),
|
||||
)
|
||||
|
||||
return bondTxCmd
|
||||
}
|
||||
|
||||
// NewCreateBondCmd is the CLI command for creating a bond.
|
||||
func NewCreateBondCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "create [amount]",
|
||||
Short: "Create bond.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
coin, err := sdk.ParseCoinNormalized(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgCreateBond(sdk.NewCoins(coin), clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// RefillBondCmd is the CLI command for creating a bond.
|
||||
func RefillBondCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "refill [bond Id] [amount]",
|
||||
Short: "Refill bond.",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bondId := args[0]
|
||||
coin, err := sdk.ParseCoinNormalized(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgRefillBond(bondId, coin, clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// WithdrawBondCmd is the CLI command for withdrawing funds from a bond.
|
||||
func WithdrawBondCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "withdraw [bond Id] [amount]",
|
||||
Short: "Withdraw amount from bond.",
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bondId := args[0]
|
||||
coin, err := sdk.ParseCoinNormalized(args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgWithdrawBond(bondId, coin, clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// CancelBondCmd is the CLI command for cancelling a bond.
|
||||
func CancelBondCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "cancel [bond Id]",
|
||||
Short: "cancel bond.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bondId := args[0]
|
||||
msg := types.NewMsgCancelBond(bondId, clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
)
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
suite.Run(t, NewIntegrationTestSuite(cfg))
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/client/cli"
|
||||
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCGetBonds() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/bond/v1beta1/bonds", val.APIAddress)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
errorMsg string
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"invalid request with headers",
|
||||
reqUrl + "asdasdas",
|
||||
true,
|
||||
"",
|
||||
func() {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func() {
|
||||
s.createBond()
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
if tc.expErr {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response bondtypes.QueryGetBondsResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetBonds()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCGetParams() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/bond/v1beta1/params", val.APIAddress)
|
||||
|
||||
resp, err := rest.GetRequest(reqUrl)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var params bondtypes.QueryParamsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, ¶ms)
|
||||
|
||||
sr.NoError(err)
|
||||
sr.Equal(params.GetParams().MaxBondAmount, bondtypes.DefaultParams().MaxBondAmount)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCGetBondsByOwner() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/bond/v1beta1/by-owner/%s"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"empty list",
|
||||
fmt.Sprintf(reqUrl, "asdasd"),
|
||||
true,
|
||||
func() {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
fmt.Sprintf(reqUrl, s.accountAddress),
|
||||
false,
|
||||
func() {
|
||||
s.createBond()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expErr {
|
||||
tc.preRun()
|
||||
}
|
||||
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var bonds bondtypes.QueryGetBondsByOwnerResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bonds)
|
||||
sr.NoError(err)
|
||||
if tc.expErr {
|
||||
sr.Empty(bonds.GetBonds())
|
||||
} else {
|
||||
bondsList := bonds.GetBonds()
|
||||
sr.NotZero(len(bondsList))
|
||||
sr.Equal(s.accountAddress, bondsList[0].GetOwner())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCGetBondById() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/bond/v1beta1/bonds/%s"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expErr bool
|
||||
preRun func() string
|
||||
}{
|
||||
{
|
||||
"invalid request",
|
||||
fmt.Sprintf(reqUrl, "asdadad"),
|
||||
true,
|
||||
func() string {
|
||||
return ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"valid request",
|
||||
reqUrl,
|
||||
false,
|
||||
func() string {
|
||||
// creating the bond
|
||||
s.createBond()
|
||||
|
||||
// getting the bonds list and returning the bond-id
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetQueryBondLists()
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var queryResponse bondtypes.QueryGetBondsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
return bond.GetId()
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
var bondId string
|
||||
if !tc.expErr {
|
||||
bondId = tc.preRun()
|
||||
tc.url = fmt.Sprintf(reqUrl, bondId)
|
||||
}
|
||||
|
||||
resp, err := rest.GetRequest(tc.url)
|
||||
s.Require().NoError(err)
|
||||
|
||||
var bonds bondtypes.QueryGetBondByIdResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &bonds)
|
||||
|
||||
if tc.expErr {
|
||||
sr.Empty(bonds.GetBond().GetId())
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.NotZero(bonds.GetBond().GetId())
|
||||
sr.Equal(bonds.GetBond().GetId(), bondId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCGetBondModuleBalance() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := fmt.Sprintf("%s/vulcanize/bond/v1beta1/balance", val.APIAddress)
|
||||
|
||||
// creating the bond
|
||||
s.createBond()
|
||||
|
||||
s.Run("valid request", func() {
|
||||
resp, err := rest.GetRequest(reqUrl)
|
||||
sr.NoError(err)
|
||||
|
||||
var response bondtypes.QueryGetBondModuleBalanceResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
|
||||
sr.NoError(err)
|
||||
sr.False(response.GetBalance().IsZero())
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
"github.com/tharsis/ethermint/x/bond/client/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
accountName string
|
||||
accountAddress string
|
||||
}
|
||||
|
||||
func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
|
||||
return &IntegrationTestSuite{cfg: cfg}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
var err error
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = s.network.WaitForHeight(1)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.accountName = "accountName"
|
||||
// setting up random account
|
||||
s.createAccountWithBalance(s.accountName)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryParams() {
|
||||
val := s.network.Validators[0]
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
outputType string
|
||||
}{
|
||||
{
|
||||
"json output",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
"json",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetQueryParamsCmd()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
s.Require().NoError(err)
|
||||
var response types.QueryParamsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(response.Params.MaxBondAmount, types.DefaultParams().MaxBondAmount)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) createAccountWithBalance(accountName string) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
consPrivKey := ed25519.GenPrivKey()
|
||||
consPubKeyBz, err := s.cfg.Codec.MarshalInterfaceJSON(consPrivKey.PubKey())
|
||||
sr.NoError(err)
|
||||
sr.NotNil(consPubKeyBz)
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic(accountName, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
||||
sr.NoError(err)
|
||||
|
||||
newAddr := sdk.AccAddress(info.GetPubKey().Address())
|
||||
_, err = banktestutil.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
newAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(200))),
|
||||
fmt.Sprintf("--%s", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
)
|
||||
sr.NoError(err)
|
||||
s.accountAddress = newAddr.String()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) createBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
createBondCmd := cli.NewCreateBondCmd()
|
||||
args := []string{
|
||||
fmt.Sprintf("10%s", s.cfg.BondDenom),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, createBondCmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
err = s.network.WaitForNextBlock()
|
||||
sr.NoError(err)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetQueryBondLists() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
createBond bool
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"create and get bond lists",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
func() {
|
||||
s.createBond()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
if tc.createBond {
|
||||
tc.preRun()
|
||||
}
|
||||
|
||||
cmd := cli.GetQueryBondLists()
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(queryResponse.GetBonds()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetQueryBondById() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func() string
|
||||
}{
|
||||
{
|
||||
"invalid bond id",
|
||||
[]string{
|
||||
fmt.Sprint("not_found_bond_id"),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
func() string {
|
||||
return ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"create and get bond by id",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
func() string {
|
||||
// creating the bond
|
||||
s.createBond()
|
||||
|
||||
// getting the bonds list and returning the bond-id
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetQueryBondLists()
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
return bond.GetId()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
if !tc.err {
|
||||
bondId := tc.preRun()
|
||||
tc.args = append([]string{bondId}, tc.args...)
|
||||
}
|
||||
cmd := cli.GetBondByIdCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
if tc.err {
|
||||
sr.Zero(len(queryResponse.GetBond().GetId()))
|
||||
} else {
|
||||
sr.NotZero(len(queryResponse.GetBond().GetId()))
|
||||
sr.Equal(s.accountAddress, queryResponse.GetBond().GetOwner())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetQueryBondListsByOwner() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"invalid owner address",
|
||||
[]string{
|
||||
fmt.Sprint("not_found_bond_id"),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
true,
|
||||
func() {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"get bond lists by owner address",
|
||||
[]string{
|
||||
fmt.Sprint(s.accountAddress),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
false,
|
||||
func() {
|
||||
s.createBond()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
if !tc.err {
|
||||
tc.preRun()
|
||||
}
|
||||
cmd := cli.GetBondListByOwnerCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsByOwnerResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
if tc.err {
|
||||
sr.Zero(len(queryResponse.GetBonds()))
|
||||
} else {
|
||||
sr.NotZero(len(queryResponse.GetBonds()))
|
||||
sr.Equal(s.accountAddress, queryResponse.GetBonds()[0].GetOwner())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetQueryBondModuleBalance() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"get bond module balance",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
},
|
||||
false,
|
||||
func() {
|
||||
s.createBond()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
if !tc.err {
|
||||
tc.preRun()
|
||||
}
|
||||
|
||||
cmd := cli.GetBondModuleBalanceCmd()
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondModuleBalanceResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
sr.False(queryResponse.GetBalance().IsZero())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/client/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestTxCreateBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"without deposit",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"create bond",
|
||||
[]string{
|
||||
fmt.Sprintf("10%s", s.cfg.BondDenom),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.NewCreateBondCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.Nil(err)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestTxRefillBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
getBondId bool
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"without refill amount and bond id",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"refill bond",
|
||||
[]string{
|
||||
fmt.Sprintf("10%s", s.cfg.BondDenom),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.RefillBondCmd()
|
||||
if tc.getBondId {
|
||||
cmd := cli.GetQueryBondLists()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
tc.args = append([]string{bond.GetId()}, tc.args...)
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// checking the balance of bond
|
||||
cmd := cli.GetBondByIdCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf(tc.args[0]),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
sr.True(queryResponse.GetBond().GetBalance().IsEqual(
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(20)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestTxWithdrawAmountFromBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
getBondId bool
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"without withdraw amount and bond id",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"withdraw amount from bond",
|
||||
[]string{
|
||||
fmt.Sprintf("10%s", s.cfg.BondDenom),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.WithdrawBondCmd()
|
||||
if tc.getBondId {
|
||||
cmd := cli.GetQueryBondLists()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
tc.args = append([]string{bond.GetId()}, tc.args...)
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// checking the balance of bond
|
||||
cmd := cli.GetBondByIdCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf(tc.args[0]),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
sr.True(queryResponse.GetBond().GetBalance().IsEqual(
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10)))))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestTxCancelBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
getBondId bool
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"without bond id",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"cancel bond",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.accountName),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.CancelBondCmd()
|
||||
if tc.getBondId {
|
||||
cmd := cli.GetQueryBondLists()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
tc.args = append([]string{bond.GetId()}, tc.args...)
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// checking the bond exists or not after cancel
|
||||
cmd := cli.GetBondByIdCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{
|
||||
fmt.Sprintf(tc.args[0]),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
sr.Zero(queryResponse.GetBond().GetId())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package bond
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/bond/keeper"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// InitGenesis initializes genesis state based on exported genesis
|
||||
func InitGenesis(
|
||||
ctx sdk.Context,
|
||||
k keeper.Keeper, data types.GenesisState) []abci.ValidatorUpdate {
|
||||
|
||||
k.SetParams(ctx, data.Params)
|
||||
|
||||
for _, bond := range data.Bonds {
|
||||
k.SaveBond(ctx, bond)
|
||||
}
|
||||
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
// ExportGenesis - output genesis parameters
|
||||
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) types.GenesisState {
|
||||
params := keeper.GetParams(ctx)
|
||||
bonds := keeper.ListBonds(ctx)
|
||||
|
||||
return types.GenesisState{Params: params, Bonds: bonds}
|
||||
}
|
||||
|
||||
// ValidateGenesis - validating the genesis data
|
||||
func ValidateGenesis(data types.GenesisState) error {
|
||||
err := data.Params.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
type Querier struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
var _ types.QueryServer = Querier{}
|
||||
|
||||
func (q Querier) Bonds(c context.Context, _ *types.QueryGetBondsRequest) (*types.QueryGetBondsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
resp := q.Keeper.ListBonds(ctx)
|
||||
return &types.QueryGetBondsResponse{Bonds: resp}, nil
|
||||
}
|
||||
|
||||
func (q Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
params := q.Keeper.GetParams(ctx)
|
||||
return &types.QueryParamsResponse{Params: ¶ms}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetBondById(c context.Context, req *types.QueryGetBondByIdRequest) (*types.QueryGetBondByIdResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
bondId := req.GetId()
|
||||
if len(bondId) == 0 {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bond id required")
|
||||
}
|
||||
bond := q.Keeper.GetBond(ctx, req.GetId())
|
||||
return &types.QueryGetBondByIdResponse{Bond: &bond}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetBondsByOwner(c context.Context, req *types.QueryGetBondsByOwnerRequest) (*types.QueryGetBondsByOwnerResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
owner := req.GetOwner()
|
||||
if len(owner) == 0 {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "owner id required")
|
||||
}
|
||||
bonds := q.Keeper.QueryBondsByOwner(ctx, owner)
|
||||
return &types.QueryGetBondsByOwnerResponse{Bonds: bonds}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetBondsModuleBalance(c context.Context, _ *types.QueryGetBondModuleBalanceRequest) (*types.QueryGetBondModuleBalanceResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
balance := q.Keeper.GetBondModuleBalances(ctx)
|
||||
return &types.QueryGetBondModuleBalanceResponse{Balance: balance}, nil
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/app"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryBondsList() {
|
||||
grpcClient, ctx, k := suite.queryClient, suite.ctx, suite.app.BondKeeper
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryGetBondsRequest
|
||||
resp *types.QueryGetBondsResponse
|
||||
noOfBonds int
|
||||
createBonds bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
&types.QueryGetBondsRequest{},
|
||||
&types.QueryGetBondsResponse{},
|
||||
0,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"Get Bonds",
|
||||
&types.QueryGetBondsRequest{},
|
||||
&types.QueryGetBondsResponse{},
|
||||
1,
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createBonds {
|
||||
account := app.CreateRandomAccounts(1)[0]
|
||||
err := simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(sdk.Coin{
|
||||
Denom: sdk.DefaultBondDenom,
|
||||
Amount: sdk.NewInt(1000),
|
||||
}))
|
||||
_, err = k.CreateBond(ctx, account, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))))
|
||||
suite.Require().NoError(err)
|
||||
}
|
||||
resp, _ := grpcClient.Bonds(context.Background(), test.req)
|
||||
suite.Require().Equal(test.noOfBonds, len(resp.GetBonds()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryParams() {
|
||||
grpcClient := suite.queryClient
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryParamsRequest
|
||||
}{
|
||||
{
|
||||
"Get Params",
|
||||
&types.QueryParamsRequest{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
resp, _ := grpcClient.Params(context.Background(), test.req)
|
||||
suite.Require().Equal(resp.GetParams().MaxBondAmount, types.DefaultParams().MaxBondAmount)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryBondBondId() {
|
||||
grpcClient, ctx, k, suiteRequire := suite.queryClient, suite.ctx, suite.app.BondKeeper, suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryGetBondByIdRequest
|
||||
createBonds bool
|
||||
errResponse bool
|
||||
bondId string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
&types.QueryGetBondByIdRequest{},
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get Bond By ID",
|
||||
&types.QueryGetBondByIdRequest{},
|
||||
true,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createBonds {
|
||||
account := app.CreateRandomAccounts(1)[0]
|
||||
err := simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(sdk.Coin{
|
||||
Denom: sdk.DefaultBondDenom,
|
||||
Amount: sdk.NewInt(1000),
|
||||
}))
|
||||
bond, err := k.CreateBond(ctx, account, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))))
|
||||
suiteRequire.NoError(err)
|
||||
test.req.Id = bond.Id
|
||||
}
|
||||
resp, err := grpcClient.GetBondById(context.Background(), test.req)
|
||||
if !test.errResponse {
|
||||
suiteRequire.Nil(err)
|
||||
suiteRequire.NotNil(resp.GetBond())
|
||||
suiteRequire.Equal(test.req.Id, resp.GetBond().GetId())
|
||||
} else {
|
||||
suiteRequire.NotNil(err)
|
||||
suiteRequire.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetBondsByOwner() {
|
||||
grpcClient, ctx, k, suiteRequire := suite.queryClient, suite.ctx, suite.app.BondKeeper, suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryGetBondsByOwnerRequest
|
||||
noOfBonds int
|
||||
createBonds bool
|
||||
errResponse bool
|
||||
bondId string
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
&types.QueryGetBondsByOwnerRequest{},
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Get Bond By Owner",
|
||||
&types.QueryGetBondsByOwnerRequest{},
|
||||
1,
|
||||
true,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createBonds {
|
||||
account := app.CreateRandomAccounts(1)[0]
|
||||
_ = simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(sdk.Coin{
|
||||
Denom: sdk.DefaultBondDenom,
|
||||
Amount: sdk.NewInt(1000),
|
||||
}))
|
||||
_, err := k.CreateBond(ctx, account, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))))
|
||||
suiteRequire.NoError(err)
|
||||
test.req.Owner = account.String()
|
||||
}
|
||||
resp, err := grpcClient.GetBondsByOwner(context.Background(), test.req)
|
||||
if !test.errResponse {
|
||||
suiteRequire.Nil(err)
|
||||
suiteRequire.NotNil(resp.GetBonds())
|
||||
suiteRequire.Equal(test.noOfBonds, len(resp.GetBonds()))
|
||||
} else {
|
||||
suiteRequire.NotNil(err)
|
||||
suiteRequire.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetModuleBalance() {
|
||||
grpcClient, ctx, k, suiteRequire := suite.queryClient, suite.ctx, suite.app.BondKeeper, suite.Require()
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *types.QueryGetBondModuleBalanceRequest
|
||||
noOfBonds int
|
||||
createBonds bool
|
||||
errResponse bool
|
||||
}{
|
||||
{
|
||||
"empty request",
|
||||
&types.QueryGetBondModuleBalanceRequest{},
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createBonds {
|
||||
account := app.CreateRandomAccounts(1)[0]
|
||||
_ = simapp.FundAccount(suite.app.BankKeeper, ctx, account, sdk.NewCoins(sdk.Coin{
|
||||
Denom: sdk.DefaultBondDenom,
|
||||
Amount: sdk.NewInt(1000),
|
||||
}))
|
||||
_, err := k.CreateBond(ctx, account, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))))
|
||||
suiteRequire.NoError(err)
|
||||
}
|
||||
resp, err := grpcClient.GetBondsModuleBalance(context.Background(), test.req)
|
||||
if !test.errResponse {
|
||||
suiteRequire.Nil(err)
|
||||
suiteRequire.NotNil(resp.GetBalance())
|
||||
suiteRequire.Equal(resp.GetBalance(), sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))))
|
||||
} else {
|
||||
suiteRequire.NotNil(err)
|
||||
suiteRequire.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// RegisterInvariants registers all bond invariants
|
||||
func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
|
||||
ir.RegisterRoute(types.ModuleName, "module-account", ModuleAccountInvariant(k))
|
||||
}
|
||||
|
||||
// ModuleAccountInvariant checks that the 'bond' module account balance is non-negative.
|
||||
func ModuleAccountInvariant(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(types.ModuleName)
|
||||
balances := k.bankKeeper.GetAllBalances(ctx, moduleAddress)
|
||||
for _, balance := range balances {
|
||||
if balance.IsNegative() {
|
||||
return sdk.FormatInvariant(
|
||||
types.ModuleName,
|
||||
"module-account",
|
||||
fmt.Sprintf("Module account '%s' has negative balance.", types.ModuleName)),
|
||||
true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
// AllInvariants runs all invariants of the bonds module.
|
||||
func AllInvariants(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
return ModuleAccountInvariant(k)(ctx)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// prefixIDToBondIndex is the prefix for ID -> Bond index in the KVStore.
|
||||
// Note: This is the primary index in the system.
|
||||
// Note: Golang doesn't support const arrays.
|
||||
var prefixIDToBondIndex = []byte{0x00}
|
||||
|
||||
// prefixOwnerToBondsIndex is the prefix for the Owner -> [Bond] index in the KVStore.
|
||||
var prefixOwnerToBondsIndex = []byte{0x01}
|
||||
|
||||
// Keeper maintains the link to storage and exposes getter/setter methods for the various parts of the state machine
|
||||
type Keeper struct {
|
||||
accountKeeper auth.AccountKeeper
|
||||
bankKeeper bank.Keeper
|
||||
|
||||
// Track bond usage in other cosmos-sdk modules (more like a usage tracker).
|
||||
usageKeepers []types.BondUsageKeeper
|
||||
|
||||
storeKey sdk.StoreKey
|
||||
|
||||
cdc codec.BinaryCodec
|
||||
|
||||
paramSubspace paramtypes.Subspace
|
||||
}
|
||||
|
||||
// NewKeeper creates new instances of the bond Keeper
|
||||
func NewKeeper(cdc codec.BinaryCodec, accountKeeper auth.AccountKeeper, bankKeeper bank.Keeper, usageKeepers []types.BondUsageKeeper, storeKey sdk.StoreKey, ps paramtypes.Subspace) Keeper {
|
||||
// set KeyTable if it has not already been set
|
||||
if !ps.HasKeyTable() {
|
||||
ps = ps.WithKeyTable(types.ParamKeyTable())
|
||||
}
|
||||
|
||||
return Keeper{
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
usageKeepers: usageKeepers,
|
||||
paramSubspace: ps,
|
||||
}
|
||||
}
|
||||
|
||||
// Generates Bond ID -> Bond index key.
|
||||
func getBondIndexKey(id string) []byte {
|
||||
return append(prefixIDToBondIndex, []byte(id)...)
|
||||
}
|
||||
|
||||
// Generates Owner -> Bonds index key.
|
||||
func getOwnerToBondsIndexKey(owner string, bondID string) []byte {
|
||||
return append(append(prefixOwnerToBondsIndex, []byte(owner)...), []byte(bondID)...)
|
||||
}
|
||||
|
||||
// BondID simplifies generation of bond IDs.
|
||||
type BondID struct {
|
||||
Address sdk.Address
|
||||
AccNum uint64
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
// Generate creates the bond ID.
|
||||
func (bondID BondID) Generate() string {
|
||||
hasher := sha256.New()
|
||||
str := fmt.Sprintf("%s:%d:%d", bondID.Address.String(), bondID.AccNum, bondID.Sequence)
|
||||
hasher.Write([]byte(str))
|
||||
return hex.EncodeToString(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
// MatchBonds - get all matching bonds.
|
||||
func (k Keeper) MatchBonds(ctx sdk.Context, matchFn func(*types.Bond) bool) []*types.Bond {
|
||||
var bonds []*types.Bond
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, prefixIDToBondIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Bond
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
if matchFn(&obj) {
|
||||
bonds = append(bonds, &obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bonds
|
||||
}
|
||||
|
||||
// CreateBond creates a new bond.
|
||||
func (k Keeper) CreateBond(ctx sdk.Context, ownerAddress sdk.AccAddress, coins sdk.Coins) (*types.Bond, error) {
|
||||
// Check if account has funds.
|
||||
for _, coin := range coins {
|
||||
balance := k.bankKeeper.HasBalance(ctx, ownerAddress, coin)
|
||||
if !balance {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "failed to create bond; Insufficient funds")
|
||||
}
|
||||
}
|
||||
|
||||
// Generate bond ID.
|
||||
account := k.accountKeeper.GetAccount(ctx, ownerAddress)
|
||||
bondID := BondID{
|
||||
Address: ownerAddress,
|
||||
AccNum: account.GetAccountNumber(),
|
||||
Sequence: account.GetSequence(),
|
||||
}.Generate()
|
||||
|
||||
maxBondAmount, err := k.getMaxBondAmount(ctx)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid max bond amount.")
|
||||
}
|
||||
|
||||
bond := types.Bond{Id: bondID, Owner: ownerAddress.String(), Balance: coins}
|
||||
if bond.Balance.IsAnyGT(maxBondAmount) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Max bond amount exceeded.")
|
||||
}
|
||||
|
||||
// Move funds into the bond account module.
|
||||
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, ownerAddress, types.ModuleName, bond.Balance)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Save bond in store.
|
||||
k.SaveBond(ctx, &bond)
|
||||
|
||||
return &bond, nil
|
||||
}
|
||||
|
||||
// SaveBond - saves a bond to the store.
|
||||
func (k Keeper) SaveBond(ctx sdk.Context, bond *types.Bond) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
// Bond ID -> Bond index.
|
||||
store.Set(getBondIndexKey(bond.Id), k.cdc.MustMarshal(bond))
|
||||
|
||||
// Owner -> [Bond] index.
|
||||
store.Set(getOwnerToBondsIndexKey(bond.Owner, bond.Id), []byte{})
|
||||
}
|
||||
|
||||
// HasBond - checks if a bond by the given ID exists.
|
||||
func (k Keeper) HasBond(ctx sdk.Context, id string) bool {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return store.Has(getBondIndexKey(id))
|
||||
}
|
||||
|
||||
// GetBond - gets a record from the store.
|
||||
func (k Keeper) GetBond(ctx sdk.Context, id string) types.Bond {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
bz := store.Get(getBondIndexKey(id))
|
||||
var obj types.Bond
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// DeleteBond - deletes the bond.
|
||||
func (k Keeper) DeleteBond(ctx sdk.Context, bond types.Bond) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(getBondIndexKey(bond.Id))
|
||||
store.Delete(getOwnerToBondsIndexKey(bond.Owner, bond.Id))
|
||||
}
|
||||
|
||||
// ListBonds - get all bonds.
|
||||
func (k Keeper) ListBonds(ctx sdk.Context) []*types.Bond {
|
||||
var bonds []*types.Bond
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, prefixIDToBondIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Bond
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
bonds = append(bonds, &obj)
|
||||
}
|
||||
}
|
||||
return bonds
|
||||
}
|
||||
|
||||
// QueryBondsByOwner - query bonds by owner.
|
||||
func (k Keeper) QueryBondsByOwner(ctx sdk.Context, ownerAddress string) []types.Bond {
|
||||
var bonds []types.Bond
|
||||
|
||||
ownerPrefix := append(prefixOwnerToBondsIndex, []byte(ownerAddress)...)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, ownerPrefix)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bondID := itr.Key()[len(ownerPrefix):]
|
||||
bz := store.Get(append(prefixIDToBondIndex, bondID...))
|
||||
if bz != nil {
|
||||
var obj types.Bond
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
bonds = append(bonds, obj)
|
||||
}
|
||||
}
|
||||
|
||||
return bonds
|
||||
}
|
||||
|
||||
// RefillBond refills an existing bond.
|
||||
func (k Keeper) RefillBond(ctx sdk.Context, id string, ownerAddress sdk.AccAddress, coins sdk.Coins) (*types.Bond, error) {
|
||||
if !k.HasBond(ctx, id) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
|
||||
bond := k.GetBond(ctx, id)
|
||||
if bond.Owner != ownerAddress.String() {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// Check if account has funds.
|
||||
for _, coin := range coins {
|
||||
if !k.bankKeeper.HasBalance(ctx, ownerAddress, coin) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "Insufficient funds.")
|
||||
}
|
||||
}
|
||||
|
||||
maxBondAmount, err := k.getMaxBondAmount(ctx)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid max bond amount.")
|
||||
}
|
||||
|
||||
updatedBalance := bond.Balance.Add(coins...)
|
||||
if updatedBalance.IsAnyGT(maxBondAmount) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Max bond amount exceeded.")
|
||||
}
|
||||
|
||||
// Move funds into the bond account module.
|
||||
err = k.bankKeeper.SendCoinsFromAccountToModule(ctx, ownerAddress, types.ModuleName, coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update bond balance and save.
|
||||
bond.Balance = updatedBalance
|
||||
k.SaveBond(ctx, &bond)
|
||||
|
||||
return &bond, nil
|
||||
}
|
||||
|
||||
// WithdrawBond withdraws funds from a bond.
|
||||
func (k Keeper) WithdrawBond(ctx sdk.Context, id string, ownerAddress sdk.AccAddress, coins sdk.Coins) (*types.Bond, error) {
|
||||
if !k.HasBond(ctx, id) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
|
||||
bond := k.GetBond(ctx, id)
|
||||
if bond.Owner != ownerAddress.String() {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
updatedBalance, isNeg := bond.Balance.SafeSub(coins)
|
||||
if isNeg {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "Insufficient bond balance.")
|
||||
}
|
||||
|
||||
// Move funds from the bond into the account.
|
||||
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, ownerAddress, coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update bond balance and save.
|
||||
bond.Balance = updatedBalance
|
||||
k.SaveBond(ctx, &bond)
|
||||
|
||||
return &bond, nil
|
||||
}
|
||||
|
||||
// CancelBond cancels a bond, returning funds to the owner.
|
||||
func (k Keeper) CancelBond(ctx sdk.Context, id string, ownerAddress sdk.AccAddress) (*types.Bond, error) {
|
||||
if !k.HasBond(ctx, id) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
|
||||
bond := k.GetBond(ctx, id)
|
||||
if bond.Owner != ownerAddress.String() {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// Check if bond is used in other modules.
|
||||
for _, usageKeeper := range k.usageKeepers {
|
||||
if usageKeeper.UsesBond(ctx, id) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, fmt.Sprintf("Bond in use by the '%s' module.", usageKeeper.ModuleName()))
|
||||
}
|
||||
}
|
||||
|
||||
// Move funds from the bond into the account.
|
||||
err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, ownerAddress, bond.Balance)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k.DeleteBond(ctx, bond)
|
||||
|
||||
return &bond, nil
|
||||
}
|
||||
|
||||
func (k Keeper) getMaxBondAmount(ctx sdk.Context) (sdk.Coins, error) {
|
||||
params := k.GetParams(ctx)
|
||||
maxBondAmount := params.MaxBondAmount
|
||||
return sdk.NewCoins(maxBondAmount), nil
|
||||
}
|
||||
|
||||
// GetBondModuleBalances gets the bond module account(s) balances.
|
||||
func (k Keeper) GetBondModuleBalances(ctx sdk.Context) sdk.Coins {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(types.ModuleName)
|
||||
balances := k.bankKeeper.GetAllBalances(ctx, moduleAddress)
|
||||
return balances
|
||||
}
|
||||
|
||||
// TransferCoinsToModuleAccount moves funds from the bonds module account to another module account.
|
||||
func (k Keeper) TransferCoinsToModuleAccount(ctx sdk.Context, id, moduleAccount string, coins sdk.Coins) error {
|
||||
if !k.HasBond(ctx, id) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond not found.")
|
||||
}
|
||||
|
||||
bondObj := k.GetBond(ctx, id)
|
||||
|
||||
// Deduct rent from bond.
|
||||
updatedBalance, isNeg := bondObj.Balance.SafeSub(coins)
|
||||
|
||||
if isNeg {
|
||||
// Check if bond has sufficient funds.
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, "Insufficient funds.")
|
||||
}
|
||||
|
||||
// Move funds from bond module to record rent module.
|
||||
err := k.bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, moduleAccount, coins)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Error transferring funds.")
|
||||
}
|
||||
|
||||
// Update bond balance.
|
||||
bondObj.Balance = updatedBalance
|
||||
k.SaveBond(ctx, &bondObj)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
"github.com/tharsis/ethermint/app"
|
||||
bondkeeper "github.com/tharsis/ethermint/x/bond/keeper"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
type KeeperTestSuite struct {
|
||||
suite.Suite
|
||||
app *app.EthermintApp
|
||||
ctx sdk.Context
|
||||
queryClient types.QueryClient
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
querier := bondkeeper.Querier{Keeper: testApp.BondKeeper}
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, testApp.InterfaceRegistry())
|
||||
types.RegisterQueryServer(queryHelper, querier)
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
|
||||
suite.app, suite.ctx, suite.queryClient = testApp, ctx, queryClient
|
||||
}
|
||||
|
||||
func TestParams(t *testing.T) {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
expParams := types.DefaultParams()
|
||||
params := testApp.BondKeeper.GetParams(ctx)
|
||||
require.Equal(t, expParams.MaxBondAmount, params.MaxBondAmount)
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(KeeperTestSuite))
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
type msgServer struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
// NewMsgServerImpl returns an implementation of the bond MsgServer interface for the provided Keeper.
|
||||
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
|
||||
return &msgServer{Keeper: keeper}
|
||||
}
|
||||
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
func (k msgServer) CreateBond(c context.Context, msg *types.MsgCreateBond) (*types.MsgCreateBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = k.Keeper.CreateBond(ctx, signerAddress, msg.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCreateBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Coins.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgCreateBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (k msgServer) RefillBond(c context.Context, msg *types.MsgRefillBond) (*types.MsgRefillBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = k.Keeper.RefillBond(ctx, msg.Id, signerAddress, msg.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRefillBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.Id),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Coins.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgRefillBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (k msgServer) WithdrawBond(c context.Context, msg *types.MsgWithdrawBond) (*types.MsgWithdrawBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = k.Keeper.WithdrawBond(ctx, msg.Id, signerAddress, msg.Coins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeWithdrawBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.Id),
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, msg.Coins.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgWithdrawBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (k msgServer) CancelBond(c context.Context, msg *types.MsgCancelBond) (*types.MsgCancelBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = k.Keeper.CancelBond(ctx, msg.Id, signerAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeCancelBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.Id),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgCancelBondResponse{}, nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
// GetMaxBondAmount max bond amount
|
||||
func (k Keeper) GetMaxBondAmount(ctx sdk.Context) (res sdk.Coin) {
|
||||
k.paramSubspace.Get(ctx, types.ParamStoreKeyMaxBondAmount, &res)
|
||||
return
|
||||
}
|
||||
|
||||
// GetParams - Get all parameter as types.Params.
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
getMaxBondAmount := k.GetMaxBondAmount(ctx)
|
||||
return types.Params{MaxBondAmount: getMaxBondAmount}
|
||||
}
|
||||
|
||||
// SetParams - set the params.
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
k.paramSubspace.SetParamSet(ctx, ¶ms)
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package bond
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/bond/client/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/keeper"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// AppModuleBasic defines the basic application module used by the staking module.
|
||||
type AppModuleBasic struct {
|
||||
cdc codec.Codec
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterLegacyAminoCodec(amino *codec.LegacyAmino) {
|
||||
types.RegisterLegacyAminoCodec(amino)
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
types.RegisterInterfaces(registry)
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) DefaultGenesis(jsonCodec codec.JSONCodec) json.RawMessage {
|
||||
return jsonCodec.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
if err := cdc.UnmarshalJSON(message, &data); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
||||
}
|
||||
|
||||
return ValidateGenesis(data)
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterRESTRoutes(context client.Context, router *mux.Router) {
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, serveMux *runtime.ServeMux) {
|
||||
err := types.RegisterQueryHandlerClient(context.Background(), serveMux, types.NewQueryClient(clientCtx))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
}
|
||||
|
||||
func (b AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
}
|
||||
|
||||
// Name returns the staking module's name.
|
||||
func (AppModuleBasic) Name() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
keeper keeper.Keeper
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule Object
|
||||
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{cdc: cdc},
|
||||
keeper: keeper,
|
||||
}
|
||||
}
|
||||
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, message json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState types.GenesisState
|
||||
|
||||
cdc.MustUnmarshalJSON(message, &genesisState)
|
||||
|
||||
return InitGenesis(ctx, am.keeper, genesisState)
|
||||
}
|
||||
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
||||
gs := ExportGenesis(ctx, am.keeper)
|
||||
return cdc.MustMarshalJSON(&gs)
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterInvariants(registry sdk.InvariantRegistry) {
|
||||
keeper.RegisterInvariants(registry, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) Route() sdk.Route {
|
||||
return sdk.Route{}
|
||||
}
|
||||
|
||||
func (am AppModule) QuerierRoute() string {
|
||||
return types.QuerierRoute
|
||||
}
|
||||
|
||||
func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
querier := keeper.Querier{Keeper: am.keeper}
|
||||
types.RegisterQueryServer(cfg.QueryServer(), querier)
|
||||
|
||||
msgServer := keeper.NewMsgServerImpl(am.keeper)
|
||||
types.RegisterMsgServer(cfg.MsgServer(), msgServer)
|
||||
}
|
||||
|
||||
func (am AppModule) ConsensusVersion() uint64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
|
||||
BeginBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return EndBlocker(ctx, am.keeper)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package bond_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/stretchr/testify/require"
|
||||
abcitypes "github.com/tendermint/tendermint/abci/types"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
app "github.com/tharsis/ethermint/app"
|
||||
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
||||
)
|
||||
|
||||
func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
|
||||
app := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
app.InitChain(abcitypes.RequestInitChain{
|
||||
AppStateBytes: []byte("{}"),
|
||||
ChainId: "test-chain-id",
|
||||
})
|
||||
|
||||
acc := app.AccountKeeper.GetModuleAccount(ctx, bondtypes.ModuleName)
|
||||
require.NotNil(t, acc)
|
||||
}
|
||||
Generated
+620
@@ -0,0 +1,620 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: vulcanize/bond/v1beta1/bond.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
|
||||
types "github.com/cosmos/cosmos-sdk/types"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// Params defines the bond module parameters
|
||||
type Params struct {
|
||||
// max_bond_amount is maximum amount to bond
|
||||
MaxBondAmount types.Coin `protobuf:"bytes,1,opt,name=max_bond_amount,json=maxBondAmount,proto3" json:"max_bond_amount" json:"max_bond_amount" yaml:"max_bond_amount"`
|
||||
}
|
||||
|
||||
func (m *Params) Reset() { *m = Params{} }
|
||||
func (m *Params) String() string { return proto.CompactTextString(m) }
|
||||
func (*Params) ProtoMessage() {}
|
||||
func (*Params) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ff3ef02fadb61511, []int{0}
|
||||
}
|
||||
func (m *Params) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_Params.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *Params) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Params.Merge(m, src)
|
||||
}
|
||||
func (m *Params) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *Params) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Params.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Params proto.InternalMessageInfo
|
||||
|
||||
func (m *Params) GetMaxBondAmount() types.Coin {
|
||||
if m != nil {
|
||||
return m.MaxBondAmount
|
||||
}
|
||||
return types.Coin{}
|
||||
}
|
||||
|
||||
// Bond represents funds deposited by an account for record rent payments.
|
||||
type Bond struct {
|
||||
// id is unique identifier of the bond
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
// owner of the bond
|
||||
Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||
// balance of the bond
|
||||
Balance github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,3,rep,name=balance,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"balance" json:"balance" yaml:"balance"`
|
||||
}
|
||||
|
||||
func (m *Bond) Reset() { *m = Bond{} }
|
||||
func (m *Bond) String() string { return proto.CompactTextString(m) }
|
||||
func (*Bond) ProtoMessage() {}
|
||||
func (*Bond) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_ff3ef02fadb61511, []int{1}
|
||||
}
|
||||
func (m *Bond) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *Bond) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_Bond.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *Bond) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Bond.Merge(m, src)
|
||||
}
|
||||
func (m *Bond) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *Bond) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Bond.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Bond proto.InternalMessageInfo
|
||||
|
||||
func (m *Bond) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Bond) GetOwner() string {
|
||||
if m != nil {
|
||||
return m.Owner
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Bond) GetBalance() github_com_cosmos_cosmos_sdk_types.Coins {
|
||||
if m != nil {
|
||||
return m.Balance
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Params)(nil), "vulcanize.bond.v1beta1.Params")
|
||||
proto.RegisterType((*Bond)(nil), "vulcanize.bond.v1beta1.Bond")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("vulcanize/bond/v1beta1/bond.proto", fileDescriptor_ff3ef02fadb61511) }
|
||||
|
||||
var fileDescriptor_ff3ef02fadb61511 = []byte{
|
||||
// 344 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0xc1, 0x4e, 0x32, 0x31,
|
||||
0x14, 0x85, 0xa7, 0xf0, 0xff, 0x18, 0xc7, 0xa8, 0xc9, 0x84, 0x18, 0x24, 0xb1, 0x20, 0x2b, 0x5c,
|
||||
0x30, 0x0d, 0x1a, 0x37, 0xee, 0x84, 0x17, 0x50, 0x96, 0x6e, 0x48, 0x67, 0xa6, 0x81, 0x2a, 0xed,
|
||||
0x25, 0xd3, 0x82, 0x83, 0x4b, 0x17, 0xae, 0x7d, 0x0e, 0xf7, 0xbe, 0x03, 0x4b, 0x96, 0xae, 0xd0,
|
||||
0xc0, 0x1b, 0xf8, 0x04, 0x66, 0xda, 0x19, 0x62, 0x34, 0x71, 0xd5, 0x9e, 0xdb, 0x73, 0xbf, 0x7b,
|
||||
0xd2, 0xeb, 0x1e, 0x4f, 0x27, 0xa3, 0x90, 0x4a, 0xfe, 0xc0, 0x48, 0x00, 0x32, 0x22, 0xd3, 0x76,
|
||||
0xc0, 0x34, 0x6d, 0x1b, 0xe1, 0x8f, 0x63, 0xd0, 0xe0, 0x1d, 0x6c, 0x2c, 0xbe, 0xa9, 0x66, 0x96,
|
||||
0x6a, 0x79, 0x00, 0x03, 0x30, 0x16, 0x92, 0xde, 0xac, 0xbb, 0x8a, 0x43, 0x50, 0x02, 0x14, 0x09,
|
||||
0xa8, 0x62, 0x1b, 0x5a, 0x08, 0x5c, 0xda, 0xf7, 0xc6, 0x23, 0x72, 0x4b, 0x57, 0x34, 0xa6, 0x42,
|
||||
0x79, 0x89, 0xbb, 0x2f, 0x68, 0xd2, 0x4f, 0xa1, 0x7d, 0x2a, 0x60, 0x22, 0x75, 0x05, 0xd5, 0x51,
|
||||
0x73, 0xe7, 0xf4, 0xd0, 0xb7, 0x10, 0x3f, 0x85, 0xe4, 0xf3, 0xfc, 0x2e, 0x70, 0xd9, 0x39, 0x9f,
|
||||
0x2f, 0x6b, 0xce, 0xe7, 0xb2, 0xd6, 0xba, 0x55, 0x20, 0x2f, 0x1a, 0x3f, 0xfa, 0x1b, 0xf5, 0x19,
|
||||
0x15, 0xa3, 0xdf, 0xe5, 0xde, 0xae, 0xa0, 0x49, 0x07, 0x64, 0x74, 0x69, 0xf5, 0x2b, 0x72, 0xff,
|
||||
0xa5, 0xd2, 0xdb, 0x73, 0x0b, 0x3c, 0x32, 0x53, 0xb7, 0x7b, 0x05, 0x1e, 0x79, 0x65, 0xf7, 0x3f,
|
||||
0xdc, 0x4b, 0x16, 0x57, 0x0a, 0xa6, 0x64, 0x85, 0xf7, 0x84, 0xdc, 0xad, 0x80, 0x8e, 0xa8, 0x0c,
|
||||
0x59, 0xa5, 0x58, 0x2f, 0xfe, 0x9d, 0xf0, 0x3a, 0x4b, 0x78, 0x64, 0x13, 0x66, 0x7d, 0x79, 0xb2,
|
||||
0x5c, 0xbe, 0xbc, 0xd7, 0x9a, 0x03, 0xae, 0x87, 0x93, 0xc0, 0x0f, 0x41, 0x90, 0xec, 0xd3, 0xec,
|
||||
0xd1, 0x52, 0xd1, 0x1d, 0xd1, 0xb3, 0x31, 0x53, 0x86, 0xa8, 0x7a, 0xf9, 0xf0, 0x4e, 0x77, 0xbe,
|
||||
0xc2, 0x68, 0xb1, 0xc2, 0xe8, 0x63, 0x85, 0xd1, 0xf3, 0x1a, 0x3b, 0x8b, 0x35, 0x76, 0xde, 0xd6,
|
||||
0xd8, 0xb9, 0x39, 0xf9, 0x06, 0xd3, 0x43, 0x1a, 0x2b, 0xae, 0x08, 0xd3, 0x43, 0x16, 0x0b, 0x2e,
|
||||
0x35, 0x49, 0xec, 0x72, 0x0d, 0x33, 0x28, 0x99, 0x45, 0x9c, 0x7d, 0x05, 0x00, 0x00, 0xff, 0xff,
|
||||
0x45, 0xf7, 0x5e, 0x13, 0xfb, 0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *Params) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Params) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
{
|
||||
size, err := m.MaxBondAmount.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintBond(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *Bond) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *Bond) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *Bond) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Balance) > 0 {
|
||||
for iNdEx := len(m.Balance) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Balance[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintBond(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
}
|
||||
if len(m.Owner) > 0 {
|
||||
i -= len(m.Owner)
|
||||
copy(dAtA[i:], m.Owner)
|
||||
i = encodeVarintBond(dAtA, i, uint64(len(m.Owner)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.Id) > 0 {
|
||||
i -= len(m.Id)
|
||||
copy(dAtA[i:], m.Id)
|
||||
i = encodeVarintBond(dAtA, i, uint64(len(m.Id)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintBond(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovBond(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *Params) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.MaxBondAmount.Size()
|
||||
n += 1 + l + sovBond(uint64(l))
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *Bond) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Id)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovBond(uint64(l))
|
||||
}
|
||||
l = len(m.Owner)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovBond(uint64(l))
|
||||
}
|
||||
if len(m.Balance) > 0 {
|
||||
for _, e := range m.Balance {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovBond(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovBond(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozBond(x uint64) (n int) {
|
||||
return sovBond(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *Params) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Params: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field MaxBondAmount", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.MaxBondAmount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipBond(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *Bond) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: Bond: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: Bond: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Id = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Owner = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Balance", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Balance = append(m.Balance, types.Coin{})
|
||||
if err := m.Balance[len(m.Balance)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipBond(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthBond
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipBond(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowBond
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthBond
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupBond
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthBond
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthBond = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowBond = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupBond = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
@@ -0,0 +1,39 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
)
|
||||
|
||||
// RegisterLegacyAminoCodec registers the necessary x/bond interfaces and concrete types
|
||||
// on the provided LegacyAmino codec. These types are used for Amino JSON serialization.
|
||||
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
cdc.RegisterConcrete(&MsgCreateBond{}, "bond/MsgCreateBond", nil)
|
||||
cdc.RegisterConcrete(&MsgRefillBond{}, "bond/MsgRefillBond", nil)
|
||||
cdc.RegisterConcrete(&MsgWithdrawBond{}, "bond/MsgWithdrawBond", nil)
|
||||
cdc.RegisterConcrete(&MsgCancelBond{}, "bond/MsgCancelBond", nil)
|
||||
}
|
||||
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterImplementations((*sdk.Msg)(nil),
|
||||
&MsgCreateBond{},
|
||||
&MsgRefillBond{},
|
||||
&MsgCancelBond{},
|
||||
&MsgWithdrawBond{},
|
||||
)
|
||||
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
|
||||
}
|
||||
|
||||
var (
|
||||
amino = codec.NewLegacyAmino()
|
||||
ModuleCdc = codec.NewAminoCodec(amino)
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterLegacyAminoCodec(amino)
|
||||
cryptocodec.RegisterCrypto(amino)
|
||||
amino.Seal()
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
// bond module event types
|
||||
|
||||
const (
|
||||
EventTypeCreateBond = "crate_bond"
|
||||
EventTypeRefillBond = "refill_bond"
|
||||
EventTypeCancelBond = "cancel_bond"
|
||||
EventTypeWithdrawBond = "withdraw_bond"
|
||||
|
||||
AttributeKeySigner = "signer"
|
||||
AttributeKeyAmount = "amount"
|
||||
AttributeKeyBondId = "bond_id"
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// BondUsageKeeper keep track of bond usage in other modules.
|
||||
// Used to, for example, prevent deletion of a bond that's in use.
|
||||
type BondUsageKeeper interface {
|
||||
ModuleName() string
|
||||
UsesBond(ctx sdk.Context, bondId string) bool
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package types
|
||||
|
||||
// DefaultGenesisState sets default evm genesis state with empty accounts and default params and
|
||||
// chain config values.
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{
|
||||
Params: DefaultParams(),
|
||||
}
|
||||
}
|
||||
Generated
+391
@@ -0,0 +1,391 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: vulcanize/bond/v1beta1/genesis.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState defines the bond module's genesis state.
|
||||
type GenesisState struct {
|
||||
// params defines all the parameters of the module.
|
||||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
|
||||
// bonds defines all the bonds
|
||||
Bonds []*Bond `protobuf:"bytes,2,rep,name=bonds,proto3" json:"bonds,omitempty" json:"bonds" yaml:"bonds"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState) ProtoMessage() {}
|
||||
func (*GenesisState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f9582eb9edb1dcdf, []int{0}
|
||||
}
|
||||
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
|
||||
|
||||
func (m *GenesisState) GetParams() Params {
|
||||
if m != nil {
|
||||
return m.Params
|
||||
}
|
||||
return Params{}
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetBonds() []*Bond {
|
||||
if m != nil {
|
||||
return m.Bonds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "vulcanize.bond.v1beta1.GenesisState")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("vulcanize/bond/v1beta1/genesis.proto", fileDescriptor_f9582eb9edb1dcdf)
|
||||
}
|
||||
|
||||
var fileDescriptor_f9582eb9edb1dcdf = []byte{
|
||||
// 259 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x29, 0x2b, 0xcd, 0x49,
|
||||
0x4e, 0xcc, 0xcb, 0xac, 0x4a, 0xd5, 0x4f, 0xca, 0xcf, 0x4b, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d,
|
||||
0x49, 0x34, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9,
|
||||
0x17, 0x12, 0x83, 0xab, 0xd2, 0x03, 0xa9, 0xd2, 0x83, 0xaa, 0x92, 0x12, 0x49, 0xcf, 0x4f, 0xcf,
|
||||
0x07, 0x2b, 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0xa5, 0x14, 0x71, 0x98, 0x09, 0xd6, 0x0a, 0x56, 0xa2,
|
||||
0x34, 0x9f, 0x91, 0x8b, 0xc7, 0x1d, 0x62, 0x45, 0x70, 0x49, 0x62, 0x49, 0xaa, 0x90, 0x0d, 0x17,
|
||||
0x5b, 0x41, 0x62, 0x51, 0x62, 0x6e, 0xb1, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x9c, 0x1e,
|
||||
0x76, 0x2b, 0xf5, 0x02, 0xc0, 0xaa, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x11,
|
||||
0x0a, 0xe4, 0x62, 0x05, 0x29, 0x2a, 0x96, 0x60, 0x52, 0x60, 0xd6, 0xe0, 0x36, 0x92, 0xc1, 0xa5,
|
||||
0xd9, 0x29, 0x3f, 0x2f, 0xc5, 0x49, 0xf6, 0xd3, 0x3d, 0x79, 0xc9, 0xac, 0xe2, 0xfc, 0x3c, 0x2b,
|
||||
0x25, 0xb0, 0x26, 0x25, 0x85, 0xca, 0xc4, 0xdc, 0x1c, 0x18, 0x27, 0x08, 0x62, 0x92, 0x93, 0xf3,
|
||||
0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c,
|
||||
0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x69, 0xa6, 0x67, 0x96, 0x64, 0x94,
|
||||
0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x97, 0x64, 0x24, 0x16, 0x15, 0x67, 0x16, 0xeb, 0xa7, 0x96,
|
||||
0x64, 0xa4, 0x16, 0xe5, 0x66, 0xe6, 0x95, 0xe8, 0x57, 0x40, 0xfc, 0x5c, 0x52, 0x59, 0x90, 0x5a,
|
||||
0x9c, 0xc4, 0x06, 0xf6, 0xad, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xaa, 0xe9, 0x23, 0x03, 0x66,
|
||||
0x01, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Bonds) > 0 {
|
||||
for iNdEx := len(m.Bonds) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Bonds[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
}
|
||||
{
|
||||
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovGenesis(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *GenesisState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.Params.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
if len(m.Bonds) > 0 {
|
||||
for _, e := range m.Bonds {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenesis(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozGenesis(x uint64) (n int) {
|
||||
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Bonds", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Bonds = append(m.Bonds, &Bond{})
|
||||
if err := m.Bonds[len(m.Bonds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenesis(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenesis
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// ModuleName is the name of the staking module
|
||||
ModuleName = "bond"
|
||||
|
||||
// StoreKey is the string store representation
|
||||
StoreKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for the staking module
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// RouterKey is the msg router key for the staking module
|
||||
RouterKey = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,161 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgCreateBond{}
|
||||
_ sdk.Msg = &MsgRefillBond{}
|
||||
_ sdk.Msg = &MsgWithdrawBond{}
|
||||
_ sdk.Msg = &MsgCancelBond{}
|
||||
)
|
||||
|
||||
// NewMsgCreateBond is the constructor function for MsgCreateBond.
|
||||
func NewMsgCreateBond(coins sdk.Coins, signer sdk.AccAddress) MsgCreateBond {
|
||||
return MsgCreateBond{
|
||||
Coins: coins,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgCreateBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgCreateBond) Type() string { return "create" }
|
||||
|
||||
func (msg MsgCreateBond) ValidateBasic() error {
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
if len(msg.Coins) == 0 || !msg.Coins.IsValid() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "Invalid amount.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg MsgCreateBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgCreateBond
|
||||
func (msg MsgCreateBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// NewMsgRefillBond is the constructor function for MsgRefillBond.
|
||||
func NewMsgRefillBond(id string, amount sdk.Coin, signer sdk.AccAddress) MsgRefillBond {
|
||||
return MsgRefillBond{
|
||||
Id: id,
|
||||
Coins: sdk.NewCoins(amount),
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgRefillBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgRefillBond) Type() string { return "refill" }
|
||||
|
||||
func (msg MsgRefillBond) ValidateBasic() error {
|
||||
if len(msg.Id) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, msg.Id)
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
if len(msg.Coins) == 0 || !msg.Coins.IsValid() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "Invalid amount.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg MsgRefillBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgCreateBond
|
||||
func (msg MsgRefillBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// NewMsgWithdrawBond is the constructor function for NewMsgWithdrawBond.
|
||||
func NewMsgWithdrawBond(id string, amount sdk.Coin, signer sdk.AccAddress) MsgWithdrawBond {
|
||||
return MsgWithdrawBond{
|
||||
Id: id,
|
||||
Coins: sdk.NewCoins(amount),
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgWithdrawBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgWithdrawBond) Type() string { return "withdraw" }
|
||||
|
||||
func (msg MsgWithdrawBond) ValidateBasic() error {
|
||||
if len(msg.Id) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, msg.Id)
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
if len(msg.Coins) == 0 || !msg.Coins.IsValid() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidCoins, "Invalid amount.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg MsgWithdrawBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgCreateBond
|
||||
func (msg MsgWithdrawBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// NewMsgCancelBond is the constructor function for CalcelBond.
|
||||
func NewMsgCancelBond(id string, signer sdk.AccAddress) MsgCancelBond {
|
||||
return MsgCancelBond{
|
||||
Id: id,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgCancelBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgCancelBond) Type() string { return "cancel" }
|
||||
|
||||
func (msg MsgCancelBond) ValidateBasic() error {
|
||||
if len(msg.Id) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, msg.Id)
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg MsgCancelBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgCreateBond
|
||||
func (msg MsgCancelBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
)
|
||||
|
||||
var _ paramtypes.ParamSet = &Params{}
|
||||
|
||||
// Default parameter values.
|
||||
var (
|
||||
DefaultMaxBondAmountTokens = sdk.NewInt(100000000000)
|
||||
)
|
||||
|
||||
// Parameter keys
|
||||
var (
|
||||
ParamStoreKeyMaxBondAmount = []byte("MaxBondAmount")
|
||||
)
|
||||
|
||||
// ParamKeyTable ParamTable for staking module
|
||||
func ParamKeyTable() paramtypes.KeyTable {
|
||||
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
|
||||
}
|
||||
|
||||
func NewParams(maxBondAmount sdk.Coin) Params {
|
||||
return Params{MaxBondAmount: maxBondAmount}
|
||||
}
|
||||
|
||||
// DefaultParams returns default evm parameters
|
||||
// ExtraEIPs is empty to prevent overriding the latest hard fork instruction set
|
||||
func DefaultParams() Params {
|
||||
return NewParams(sdk.NewCoin(sdk.DefaultBondDenom, DefaultMaxBondAmountTokens))
|
||||
}
|
||||
|
||||
// ParamSetPairs returns the parameter set pairs.
|
||||
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
|
||||
return paramtypes.ParamSetPairs{
|
||||
paramtypes.NewParamSetPair(ParamStoreKeyMaxBondAmount, &p.MaxBondAmount, validateMaxBondAmount),
|
||||
}
|
||||
}
|
||||
|
||||
func validateMaxBondAmount(i interface{}) error {
|
||||
v, ok := i.(sdk.Coin)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v.Amount.IsNegative() {
|
||||
return errors.New("max bond amount must be positive")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate checks that the parameters have valid values.
|
||||
func (p Params) Validate() error {
|
||||
if err := validateMaxBondAmount(p.MaxBondAmount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
+2280
File diff suppressed because it is too large
Load Diff
Generated
+504
@@ -0,0 +1,504 @@
|
||||
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||
// source: vulcanize/bond/v1beta1/query.proto
|
||||
|
||||
/*
|
||||
Package types is a reverse proxy.
|
||||
|
||||
It translates gRPC into RESTful JSON APIs.
|
||||
*/
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/golang/protobuf/descriptor"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/utilities"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/grpclog"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// Suppress "imported and not used" errors
|
||||
var _ codes.Code
|
||||
var _ io.Reader
|
||||
var _ status.Status
|
||||
var _ = runtime.String
|
||||
var _ = utilities.NewDoubleArray
|
||||
var _ = descriptor.ForMessage
|
||||
|
||||
func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryParamsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryParamsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.Params(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Query_Bonds_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||
)
|
||||
|
||||
func request_Query_Bonds_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Bonds_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.Bonds(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_Bonds_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Bonds_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.Bonds(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_GetBondById_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondByIdRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetBondById(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetBondById_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondByIdRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["id"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||
}
|
||||
|
||||
protoReq.Id, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetBondById(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
filter_Query_GetBondsByOwner_0 = &utilities.DoubleArray{Encoding: map[string]int{"owner": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
|
||||
)
|
||||
|
||||
func request_Query_GetBondsByOwner_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondsByOwnerRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["owner"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner")
|
||||
}
|
||||
|
||||
protoReq.Owner, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetBondsByOwner_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.GetBondsByOwner(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetBondsByOwner_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondsByOwnerRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
var (
|
||||
val string
|
||||
ok bool
|
||||
err error
|
||||
_ = err
|
||||
)
|
||||
|
||||
val, ok = pathParams["owner"]
|
||||
if !ok {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "owner")
|
||||
}
|
||||
|
||||
protoReq.Owner, err = runtime.String(val)
|
||||
|
||||
if err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "owner", err)
|
||||
}
|
||||
|
||||
if err := req.ParseForm(); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetBondsByOwner_0); err != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.GetBondsByOwner(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_Query_GetBondsModuleBalance_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondModuleBalanceRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := client.GetBondsModuleBalance(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_Query_GetBondsModuleBalance_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq QueryGetBondModuleBalanceRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
msg, err := server.GetBondsModuleBalance(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
|
||||
// UnaryRPC :call QueryServer directly.
|
||||
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
|
||||
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Bonds_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_Bonds_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Bonds_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondById_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetBondById_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondById_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondsByOwner_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetBondsByOwner_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondsByOwner_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondsModuleBalance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_Query_GetBondsModuleBalance_0(rctx, inboundMarshaler, server, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondsModuleBalance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
|
||||
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
|
||||
return RegisterQueryHandler(ctx, mux, conn)
|
||||
}
|
||||
|
||||
// RegisterQueryHandler registers the http handlers for service Query to "mux".
|
||||
// The handlers forward requests to the grpc endpoint over "conn".
|
||||
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
|
||||
}
|
||||
|
||||
// RegisterQueryHandlerClient registers the http handlers for service Query
|
||||
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
|
||||
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
|
||||
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||
// "QueryClient" to call the correct interceptors.
|
||||
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
|
||||
|
||||
mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_Bonds_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_Bonds_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_Bonds_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondById_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetBondById_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondById_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondsByOwner_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetBondsByOwner_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondsByOwner_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("GET", pattern_Query_GetBondsModuleBalance_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_Query_GetBondsModuleBalance_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_Query_GetBondsModuleBalance_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "bond", "v1beta1", "params"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_Bonds_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "bond", "v1beta1", "bonds"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetBondById_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "bond", "v1beta1", "bonds", "id"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetBondsByOwner_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"vulcanize", "bond", "v1beta1", "by-owner", "owner"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
|
||||
pattern_Query_GetBondsModuleBalance_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"vulcanize", "bond", "v1beta1", "balance"}, "", runtime.AssumeColonVerbOpt(true)))
|
||||
)
|
||||
|
||||
var (
|
||||
forward_Query_Params_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_Bonds_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetBondById_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetBondsByOwner_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_GetBondsModuleBalance_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
Generated
+1921
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,340 @@
|
||||
# Build chain
|
||||
|
||||
```bash
|
||||
# it will create binary in build folder with `ethermintd`
|
||||
$ make build
|
||||
```
|
||||
|
||||
# Setup Chain
|
||||
|
||||
```bash
|
||||
./build/chibaclonkd keys add root
|
||||
./build/chibaclonkd init test-moniker --chain-id ethermint_9000-1
|
||||
./build/chibaclonkd add-genesis-account $(./build/chibaclonkd keys show root -a) 1000000000000000000aphoton,1000000000000000000stake
|
||||
./build/chibaclonkd gentx root 1000000000000000000stake --chain-id ethermint_9000-1
|
||||
./build/chibaclonkd collect-gentxs
|
||||
./build/chibaclonkd start
|
||||
```
|
||||
|
||||
## Get Params
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice params -o json | jq .
|
||||
{
|
||||
"params": {
|
||||
"record_rent": {
|
||||
"denom": "stake",
|
||||
"amount": "1000000"
|
||||
},
|
||||
|
||||
"record_rent_duration": "31536000s",
|
||||
"authority_rent": {
|
||||
"denom": "stake",
|
||||
"amount": "1000000"
|
||||
},
|
||||
"authority_rent_duration": "31536000s",
|
||||
"authority_grace_period": "172800s",
|
||||
"authority_auction_enabled": false,
|
||||
"authority_auction_commits_duration": "86400s",
|
||||
"authority_auction_reveals_duration": "86400s",
|
||||
"authority_auction_commit_fee": {
|
||||
"denom": "stake",
|
||||
"amount": "1000000"
|
||||
},
|
||||
"authority_auction_reveal_fee": {
|
||||
"denom": "stake",
|
||||
"amount": "1000000"
|
||||
},
|
||||
"authority_auction_minimum_bid": {
|
||||
"denom": "stake",
|
||||
"amount": "5000000"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Create (Set) Record
|
||||
|
||||
> First you have to Create bond
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd tx nameservice set ~/Desktop/examples/records/example1.yml 95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d --from root --chain-id ethermint_9000-1 --yes -o json
|
||||
{
|
||||
"height": "0",
|
||||
"txhash": "BA44ABE1194724694E7CB290F9F3121DB4E63E1A030D95CB84813EEA132CF95F",
|
||||
"codespace": "",
|
||||
"code": 0,
|
||||
"data": "",
|
||||
"raw_log": "[]",
|
||||
"logs": [],
|
||||
"info": "",
|
||||
"gas_wanted": "0",
|
||||
"gas_used": "0",
|
||||
"tx": null,
|
||||
"timestamp": ""
|
||||
}
|
||||
```
|
||||
|
||||
## Get records list
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice list -o json | jq
|
||||
[
|
||||
{
|
||||
"id": "bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae",
|
||||
"bondId": "c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440",
|
||||
"createTime": "2021-10-04T06:50:06.369025861Z",
|
||||
"expiryTime": "2022-10-04T06:50:06.369025861Z",
|
||||
"attributes": {
|
||||
"attr1": "value1",
|
||||
"attr2": "value2",
|
||||
"link1": {
|
||||
"/": "QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D"
|
||||
},
|
||||
"link2": {
|
||||
"/": "QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Get record by id
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice get bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae -o json | jq .
|
||||
{
|
||||
"record": {
|
||||
"id": "bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae",
|
||||
"bond_id": "95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d",
|
||||
"create_time": "2021-09-27T07:23:25.558111606Z",
|
||||
"expiry_time": "2022-09-27T07:23:25.558111606Z",
|
||||
"deleted": false,
|
||||
"owners": [],
|
||||
"attributes": "eyJhdHRyMSI6InZhbHVlMSIsImF0dHIyIjoidmFsdWUyIiwibGluazEiOnsiLyI6IlFtU251V214cHRKWmRMSnBLUmFyeEJNUzJKdTJvQU5WcmdicjJ4V2JpZTliMkQifSwibGluazIiOnsiLyI6IlFtUDhqVEcxbTlHU0RKTENiZVdoVlNWZ0V6Q1BQd1hSZENSdUp0UTVUejlLYzkifX0="
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Reserve name
|
||||
|
||||
```bash
|
||||
./build/chibaclonkd tx nameservice reserve-name hello --from root --chain-id ethermint_9000-1 --owner $(./build/chibaclonkd key
|
||||
s show root -a) -y -o json | jq .
|
||||
{
|
||||
"height": "0",
|
||||
"txhash": "7EC19157AC89279DEBE840EA3384FC95D1E2A0931C27746CA42AC23AE285B7ED",
|
||||
"codespace": "",
|
||||
"code": 0,
|
||||
"data": "",
|
||||
"raw_log": "[]",
|
||||
"logs": [],
|
||||
"info": "",
|
||||
"gas_wanted": "0",
|
||||
"gas_used": "0",
|
||||
"tx": null,
|
||||
"timestamp": ""
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Query Whois for name authority
|
||||
|
||||
```bash
|
||||
./build/chibaclonkd q nameservice whois hello -o json | jq .
|
||||
{
|
||||
"name_authority": {
|
||||
"owner_public_key": "Au3hH1tzL1KgZfXfA71jGYSe5RV9Wg95kwhBWs8V+N+h",
|
||||
"owner_address": "ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk",
|
||||
"height": "174",
|
||||
"status": "active",
|
||||
"auction_id": "",
|
||||
"bond_id": "",
|
||||
"expiry_time": "2021-09-29T07:34:36.304545965Z"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Query the nameservice module balance
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice balance -o json | jq .
|
||||
{
|
||||
"balances": [
|
||||
{
|
||||
"account_name": "record_rent",
|
||||
"balance": [
|
||||
{
|
||||
"denom": "stake",
|
||||
"amount": "1000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## add bond to the authority
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd tx nameservice authority-bond [Authority Name] [Bond ID ] --from root --chain-id ethermint_9000-1 -y -o json | jq .
|
||||
$ ./build/chibaclonkd tx nameservice authority-bond hello 95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d --from root --chain-id ethermint_9000-1 -y -o json | jq .
|
||||
```
|
||||
|
||||
## Query the records by associate bond id
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice query-by-bond 95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d -o json | jq .
|
||||
{
|
||||
"records": [
|
||||
{
|
||||
"id": "bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae",
|
||||
"bond_id": "95f68b1b862bfd1609b0c9aaf7300287b92fec90ac64027092c3e723af36e83d",
|
||||
"create_time": "2021-09-27T08:25:32.893155609Z",
|
||||
"expiry_time": "2022-09-27T08:25:32.893155609Z",
|
||||
"deleted": false,
|
||||
"owners": [],
|
||||
"attributes": "eyJhdHRyMSI6InZhbHVlMSIsImF0dHIyIjoidmFsdWUyIiwibGluazEiOnsiLyI6IlFtU251V214cHRKWmRMSnBLUmFyeEJNUzJKdTJvQU5WcmdicjJ4V2JpZTliMkQifSwibGluazIiOnsiLyI6IlFtUDhqVEcxbTlHU0RKTENiZVdoVlNWZ0V6Q1BQd1hSZENSdUp0UTVUejlLYzkifX0="
|
||||
}
|
||||
],
|
||||
"pagination": null
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## dissociate bond from record
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd tx nameservice dissociate-bond bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae --from root --chain-id ethermint_9000-1
|
||||
{"body":{"messages":[{"@type":"/vulcanize.nameservice.v1beta1.MsgDissociateBond","record_id":"bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae","signer":"ethm1mfdjngh5jvjs9lqtt9a7y2hlgw8v3syh3hsqzk"}],"memo":"","timeout_height":"0","extension_options":[],"non_critical_extension_options":[]},"auth_info":{"signer_infos":[],"fee":{"amount":[],"gas_limit":"200000","payer":"","granter":""}},"signatures":[]}
|
||||
|
||||
confirm transaction before signing and broadcasting [y/N]: y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: 7AFEF524CB0D92D6576FC08601A787786E802449888FD8DDAA7635698CC85060
|
||||
|
||||
```
|
||||
|
||||
## Associate bond with record
|
||||
|
||||
```bash
|
||||
./build/chibaclonkd tx nameservice associate-bond bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 --from root --chain-id ethermint_9000-1 -y -o json | jq .
|
||||
{
|
||||
"height": "0",
|
||||
"txhash": "F75C2BF2FE73668AE1332E1237F924AC549E31E822A56394DE5AC17200B199F9",
|
||||
"codespace": "",
|
||||
"code": 0,
|
||||
"data": "",
|
||||
"raw_log": "[]",
|
||||
"logs": [],
|
||||
"info": "",
|
||||
"gas_wanted": "0",
|
||||
"gas_used": "0",
|
||||
"tx": null,
|
||||
"timestamp": ""
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## dissociate-records => remove all record from bond
|
||||
|
||||
```bash
|
||||
$./build/chibaclonkd tx nameservice dissociate-records c3f7a78c5042d2003880962ba31ff3b01fcf5942960e0bc3ca331f816346a440 --from root --chain-id ethermint_9000-1 -y -o json | jq .
|
||||
{
|
||||
"height": "0",
|
||||
"txhash": "0316F503E5DEA47CB108AE6C7C7FFAF3F71CC56BC22F63CB97322E1BE48B33B9",
|
||||
"codespace": "",
|
||||
"code": 0,
|
||||
"data": "",
|
||||
"raw_log": "[]",
|
||||
"logs": [],
|
||||
"info": "",
|
||||
"gas_wanted": "0",
|
||||
"gas_used": "0",
|
||||
"tx": null,
|
||||
"timestamp": ""
|
||||
}
|
||||
```
|
||||
|
||||
## Renew a record
|
||||
|
||||
> When a record is expires , needs to renew record
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd tx nameservice renew-record bafyreih7un2ntk235wshncebus5emlozdhdixrrv675my5umb6fgdergae --from root --chain-id ethermint_9000-1
|
||||
|
||||
```
|
||||
|
||||
## Set the authority name
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd tx nameservice set-name crn://hello/test test_hello_cid --from root --chain-id ethermint_9000-1 -y -o json | jq .
|
||||
{
|
||||
"height": "0",
|
||||
"txhash": "66A63C73B076EEE9A2F7605354448EDEB161F0115D4D03AF68C01BA28DB97486",
|
||||
"codespace": "",
|
||||
"code": 0,
|
||||
"data": "",
|
||||
"raw_log": "[]",
|
||||
"logs": [],
|
||||
"info": "",
|
||||
"gas_wanted": "0",
|
||||
"gas_used": "0",
|
||||
"tx": null,
|
||||
"timestamp": ""
|
||||
}
|
||||
```
|
||||
|
||||
## Delete the name
|
||||
|
||||
```bash
|
||||
$./build/chibaclonkd tx nameservice delete-name crn://hello/test --from root --chain-id ethermint_9000-1 -y
|
||||
code: 0
|
||||
codespace: ""
|
||||
data: ""
|
||||
gas_used: "0"
|
||||
gas_wanted: "0"
|
||||
height: "0"
|
||||
info: ""
|
||||
logs: []
|
||||
raw_log: '[]'
|
||||
timestamp: ""
|
||||
tx: null
|
||||
txhash: A3FF4C46BAC7BD6E54BBB743A49830AE8C6F6FE59282384789CBA323C1FE540C
|
||||
|
||||
```
|
||||
|
||||
## List of Authorities Expire Queue
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice authority-expiry -o json | jq .
|
||||
{
|
||||
"authorities": [],
|
||||
"pagination": null
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## List of Records Expire Queue
|
||||
|
||||
```bash
|
||||
$ ./build/chibaclonkd q nameservice record-expiry -o json | jq .
|
||||
{
|
||||
"records": [],
|
||||
"pagination": null
|
||||
}
|
||||
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
package nameservice
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/keeper"
|
||||
)
|
||||
|
||||
// BeginBlocker will persist the current header and validator set as a historical entry
|
||||
// and prune the oldest entry based on the HistoricalEntries parameter
|
||||
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
|
||||
}
|
||||
|
||||
// EndBlocker Called every block, update validator set
|
||||
func EndBlocker(ctx sdk.Context, k keeper.Keeper) []abci.ValidatorUpdate {
|
||||
k.ProcessRecordExpiryQueue(ctx)
|
||||
k.ProcessAuthorityExpiryQueue(ctx)
|
||||
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// GetQueryCmd returns the cli query commands for this module
|
||||
func GetQueryCmd() *cobra.Command {
|
||||
bondQueryCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "Querying commands for the nameservice module",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
bondQueryCmd.AddCommand(
|
||||
GetCmdWhoIs(),
|
||||
GetCmdResolve(),
|
||||
GetCmdLookupCRN(),
|
||||
GetRecordExpiryQueue(),
|
||||
GetAuthorityExpiryQueue(),
|
||||
GetQueryParamsCmd(),
|
||||
GetCmdList(),
|
||||
GetCmdGetResource(),
|
||||
GetCmdQueryByBond(),
|
||||
GetCmdBalance(),
|
||||
GetCmdNames(),
|
||||
)
|
||||
return bondQueryCmd
|
||||
}
|
||||
|
||||
// GetCmdWhoIs queries a whois info for a name.
|
||||
func GetCmdWhoIs() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "whois [name]",
|
||||
Short: "Get name owner info.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get name owner info.
|
||||
Example:
|
||||
$ %s query %s whois [name]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Whois(cmd.Context(), &types.QueryWhoisRequest{Name: args[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdLookupCRN queries naming info for a CRN.
|
||||
func GetCmdLookupCRN() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "lookup [crn]",
|
||||
Short: "Get naming info for CRN.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get naming info for CRN.
|
||||
Example:
|
||||
$ %s query %s lookup [crn]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.LookupCrn(cmd.Context(), &types.QueryLookupCrn{Crn: args[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetQueryParamsCmd implements the params query command.
|
||||
func GetQueryParamsCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "params",
|
||||
Args: cobra.NoArgs,
|
||||
Short: "Query the current bond parameters information.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Query values set as bond parameters.
|
||||
Example:
|
||||
$ %s query %s params
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdList queries all records.
|
||||
func GetCmdList() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List records.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get the records.
|
||||
Example:
|
||||
$ %s query %s list
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.ListRecords(cmd.Context(), &types.QueryListRecordsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordsList := res.GetRecords()
|
||||
records := make([]types.RecordType, len(recordsList))
|
||||
for i, record := range res.GetRecords() {
|
||||
records[i] = record.ToRecordType()
|
||||
}
|
||||
bytesResult, err := json.Marshal(records)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintBytes(bytesResult)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdGetResource queries a record record.
|
||||
func GetCmdGetResource() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "get [ID]",
|
||||
Short: "Get record.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get the record by id.
|
||||
Example:
|
||||
$ %s query %s get [ID]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
record, err := queryClient.GetRecord(cmd.Context(), &types.QueryRecordByIdRequest{Id: args[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(record)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdResolve resolves a CRN to a record.
|
||||
func GetCmdResolve() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "resolve [crn]",
|
||||
Short: "Resolve CRN to record.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Resolve CRN to record.
|
||||
Example:
|
||||
$ %s query %s resolve [crn]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
record, err := queryClient.ResolveCrn(cmd.Context(), &types.QueryResolveCrn{Crn: args[0]})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(record)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdQueryByBond queries records by bond ID.
|
||||
func GetCmdQueryByBond() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query-by-bond [bond-id]",
|
||||
Short: "Query records by bond ID.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get the record by bond id.
|
||||
Example:
|
||||
$ %s query %s query-by-bond [bond id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
|
||||
bondID := args[0]
|
||||
res, err := queryClient.GetRecordByBondId(cmd.Context(), &types.QueryRecordByBondIdRequest{Id: bondID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(res)
|
||||
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdBalance queries the bond module account balance.
|
||||
func GetCmdBalance() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "balance",
|
||||
Short: "Get record rent module account balance.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get the record rent module account balance.
|
||||
Example:
|
||||
$ %s query %s balance
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetNameServiceModuleBalance(cmd.Context(), &types.GetNameServiceModuleBalanceRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdNames queries all naming records.
|
||||
func GetCmdNames() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "names",
|
||||
Short: "List name records.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get the names list.
|
||||
Example:
|
||||
$ %s query %s names
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.ListNameRecords(cmd.Context(), &types.QueryListNameRecordsRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetRecordExpiryQueue gets the record expiry queue.
|
||||
func GetRecordExpiryQueue() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "record-expiry",
|
||||
Short: "Get record expiry queue.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get record expiry queue.
|
||||
Example:
|
||||
$ %s query %s record-expiry
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetRecordExpiryQueue(cmd.Context(), &types.QueryGetRecordExpiryQueue{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetAuthorityExpiryQueue gets the authority expiry queue.
|
||||
func GetAuthorityExpiryQueue() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authority-expiry",
|
||||
Short: "Get authority expiry queue.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Get authority expiry queue.
|
||||
Example:
|
||||
$ %s query %s authority-expiry
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
queryClient := types.NewQueryClient(clientCtx)
|
||||
res, err := queryClient.GetAuthorityExpiryQueue(cmd.Context(), &types.QueryGetAuthorityExpiryQueue{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return clientCtx.PrintProto(res)
|
||||
},
|
||||
}
|
||||
flags.AddQueryFlagsToCmd(cmd)
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/tharsis/ethermint/server/flags"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// NewTxCmd returns a root CLI command handler for all x/bond transaction commands.
|
||||
func NewTxCmd() *cobra.Command {
|
||||
bondTxCmd := &cobra.Command{
|
||||
Use: types.ModuleName,
|
||||
Short: "nameservice transaction subcommands",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
bondTxCmd.AddCommand(
|
||||
GetCmdSetRecord(),
|
||||
GetCmdRenewRecord(),
|
||||
GetCmdAssociateBond(),
|
||||
GetCmdDissociateBond(),
|
||||
GetCmdDissociateRecords(),
|
||||
GetCmdReAssociateRecords(),
|
||||
GetCmdSetName(),
|
||||
GetCmdReserveName(),
|
||||
GetCmdSetAuthorityBond(),
|
||||
GetCmdDeleteName(),
|
||||
)
|
||||
|
||||
return bondTxCmd
|
||||
}
|
||||
|
||||
// GetCmdSetRecord is the CLI command for creating/updating a record.
|
||||
func GetCmdSetRecord() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "set [payload file path] [bond-id]",
|
||||
Short: "Set record.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Create a new record with payload and bond id.
|
||||
Example:
|
||||
$ %s tx %s set [payload file path] [bond-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payload, err := GetPayloadFromFile(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgSetRecord(payload.ToPayload(), args[1], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdRenewRecord is the CLI command for renewing an expired record.
|
||||
func GetCmdRenewRecord() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "renew-record [record-id]",
|
||||
Short: "Renew (expired) record.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Renew record.
|
||||
Example:
|
||||
$ %s tx %s renew-record [record-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgRenewRecord(args[0], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdAssociateBond is the CLI command for associating a record with a bond.
|
||||
func GetCmdAssociateBond() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "associate-bond [record-id] [bond-id]",
|
||||
Short: "Associate record with bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Associate record with bond.
|
||||
Example:
|
||||
$ %s tx %s associate-bond [record-id] [bond-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgAssociateBond(args[0], args[1], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdDissociateBond is the CLI command for dissociating a record from a bond.
|
||||
func GetCmdDissociateBond() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "dissociate-bond [record-id]",
|
||||
Short: "Dissociate record from (existing) bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Dissociate record from (existing) bond.
|
||||
Example:
|
||||
$ %s tx %s dissociate-bond [record-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgDissociateBond(args[0], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdDissociateRecords is the CLI command for dissociating all records from a bond.
|
||||
func GetCmdDissociateRecords() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "dissociate-records [bond-id]",
|
||||
Short: "Dissociate all records from bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Dissociate all records from bond.
|
||||
Example:
|
||||
$ %s tx %s dissociate-bond [record-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgDissociateRecords(args[0], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdReAssociateRecords is the CLI command for reassociating all records from old to new bond.
|
||||
func GetCmdReAssociateRecords() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reassociate-records [old-bond-id] [new-bond-id]",
|
||||
Short: "Re-Associates all records from old to new bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Re-Associates all records from old to new bond.
|
||||
Example:
|
||||
$ %s tx %s reassociate-records [old-bond-id] [new-bond-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgReAssociateRecords(args[0], args[1], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdSetName is the CLI command for mapping a name to a CID.
|
||||
func GetCmdSetName() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "set-name [crn] [cid]",
|
||||
Short: "Set CRN to CID mapping.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Set name with crn and cid.
|
||||
Example:
|
||||
$ %s tx %s set-name [crn] [cid]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgSetName(args[0], args[1], clientCtx.GetFromAddress())
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdReserveName is the CLI command for reserving a name.
|
||||
func GetCmdReserveName() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reserve-name [name]",
|
||||
Short: "Reserve name.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Reserver name with owner address .
|
||||
Example:
|
||||
$ %s tx %s reserve-name [name] --owner [ownerAddress]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
owner, err := cmd.Flags().GetString("owner")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ownerAddress, err := sdk.AccAddressFromBech32(owner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msg := types.NewMsgReserveAuthority(args[0], clientCtx.GetFromAddress(), ownerAddress)
|
||||
err = msg.ValidateBasic()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().String("owner", "", "Owner address, if creating a sub-authority.")
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
// GetCmdSetAuthorityBond is the CLI command for associating a bond with an authority.
|
||||
func GetCmdSetAuthorityBond() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "authority-bond [name] [bond-id]",
|
||||
Short: "Associate authority with bond.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Reserver name with owner address .
|
||||
Example:
|
||||
$ %s tx %s authority-bond [name] [bond-id]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(2),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgSetAuthorityBond(args[0], args[1], clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func GetCmdDeleteName() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete-name [crn]",
|
||||
Short: "Delete CRN.",
|
||||
Long: strings.TrimSpace(
|
||||
fmt.Sprintf(`Delete CRN.
|
||||
Example:
|
||||
$ %s tx %s delete-name [crn]
|
||||
`,
|
||||
version.AppName, types.ModuleName,
|
||||
),
|
||||
),
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
clientCtx, err := client.GetClientTxContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg := types.NewMsgDeleteNameAuthority(args[0], clientCtx.GetFromAddress())
|
||||
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
|
||||
},
|
||||
}
|
||||
|
||||
flags.AddTxFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
//GetPayloadFromFile Load payload object from YAML file.
|
||||
func GetPayloadFromFile(filePath string) (*types.PayloadType, error) {
|
||||
var payload types.PayloadType
|
||||
|
||||
data, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(data, &payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &payload, nil
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIntegrationTestSuite(t *testing.T) {
|
||||
cfg := network.DefaultConfig()
|
||||
cfg.NumValidators = 1
|
||||
suite.Run(t, NewIntegrationTestSuite(cfg))
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
record:
|
||||
attr1: value1
|
||||
attr2: value2
|
||||
link1:
|
||||
/: QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D
|
||||
link2:
|
||||
/: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9
|
||||
@@ -0,0 +1,651 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/rest"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/nameservice/client/cli"
|
||||
nstypes "github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryParams() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/params"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryParamsResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
params := nstypes.DefaultParams()
|
||||
params.RecordRent = sdk.NewCoin(s.cfg.BondDenom, nstypes.DefaultRecordRent)
|
||||
params.RecordRentDuration = 10 * time.Second
|
||||
params.AuthorityGracePeriod = 10 * time.Second
|
||||
sr.Equal(response.GetParams().String(), params.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryWhoIs() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/whois/%s"
|
||||
var authorityName = "QueryWhoIS"
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(authorityName)
|
||||
tc.url = fmt.Sprintf(tc.url, authorityName)
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryWhoisResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.Equal(nstypes.AuthorityActive, response.GetNameAuthority().Status)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryLookup() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/lookup?crn=%s"
|
||||
var authorityName = "QueryLookUp"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
// create name record
|
||||
createNameRecord(authorityName, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(authorityName)
|
||||
tc.url = fmt.Sprintf(reqUrl, fmt.Sprintf("crn://%s/", authorityName))
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
if tc.expectErr {
|
||||
sr.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryLookupCrnResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.Name.Latest.Id))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryRecordExpiryQueue() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/record-expiry"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(bondId string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(bondId string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(bondId string) {
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
args = append([]string{payloadPath, bondId}, args...)
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(s.bondId)
|
||||
}
|
||||
// wait 12 seconds for records expires
|
||||
time.Sleep(time.Second * 12)
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryGetRecordExpiryQueueResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetRecords()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryAuthorityExpiryQueue() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/authority-expiry"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun("QueryAuthorityExpiryQueue")
|
||||
}
|
||||
// wait 12 seconds to name authorites expires
|
||||
time.Sleep(time.Second * 12)
|
||||
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryGetAuthorityExpiryQueueResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
// removed from expiry queue as no bond set
|
||||
sr.Zero(len(response.GetAuthorities()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryListRecords() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/records"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(bondId string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(bondId string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(bondId string) {
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
args = append([]string{payloadPath, bondId}, args...)
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(s.bondId)
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryListRecordsResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetRecords()))
|
||||
sr.Equal(s.bondId, response.GetRecords()[0].GetBondId())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryGetRecordByID() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/records/%s"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(bondId string) string
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(bondId string) string {
|
||||
return ""
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(bondId string) string {
|
||||
// creating the record
|
||||
createRecord(bondId, s)
|
||||
|
||||
// list the records
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdList()
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var records []nstypes.RecordType
|
||||
err = json.Unmarshal(out.Bytes(), &records)
|
||||
sr.NoError(err)
|
||||
return records[0].Id
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
var recordId string
|
||||
if !tc.expectErr {
|
||||
recordId = tc.preRun(s.bondId)
|
||||
tc.url = fmt.Sprintf(reqUrl, recordId)
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryRecordByIdResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
record := response.GetRecord()
|
||||
sr.NotZero(len(record.GetId()))
|
||||
sr.Equal(record.GetId(), recordId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryGetRecordByBondID() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/records-by-bond-id/%s"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(bondId string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(bondId string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(bondId string) {
|
||||
// creating the record
|
||||
createRecord(bondId, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(s.bondId)
|
||||
tc.url = fmt.Sprintf(reqUrl, s.bondId)
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryRecordByBondIdResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
records := response.GetRecords()
|
||||
sr.NotZero(len(records))
|
||||
sr.Equal(records[0].GetBondId(), s.bondId)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryGetNameServiceModuleBalance() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/balance"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(bondId string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(bondId string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(bondId string) {
|
||||
// creating the record
|
||||
createRecord(bondId, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun(s.bondId)
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.GetNameServiceModuleBalanceResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetBalances()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGRPCQueryNamesList() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
reqUrl := val.APIAddress + "/vulcanize/nameservice/v1beta1/names"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
url string
|
||||
expectErr bool
|
||||
errorMsg string
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid url",
|
||||
reqUrl + "/asdasd",
|
||||
true,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
reqUrl,
|
||||
false,
|
||||
"",
|
||||
func(authorityName string) {
|
||||
// create name record
|
||||
createNameRecord(authorityName, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expectErr {
|
||||
tc.preRun("ListNameRecords")
|
||||
}
|
||||
resp, _ := rest.GetRequest(tc.url)
|
||||
require := s.Require()
|
||||
if tc.expectErr {
|
||||
require.Contains(string(resp), tc.errorMsg)
|
||||
} else {
|
||||
var response nstypes.QueryListNameRecordsResponse
|
||||
err := val.ClientCtx.Codec.UnmarshalJSON(resp, &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetNames()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createRecord(bondId string, s *IntegrationTestSuite) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
args := []string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
args = append([]string{payloadPath, bondId}, args...)
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
@@ -0,0 +1,585 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/x/nameservice/client/cli"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryParams() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
}{
|
||||
{
|
||||
"params",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetQueryParamsCmd()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
sr.NoError(err)
|
||||
var param types.QueryParamsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), ¶m)
|
||||
sr.NoError(err)
|
||||
params := types.DefaultParams()
|
||||
params.RecordRent = sdk.NewCoin(s.cfg.BondDenom, types.DefaultRecordRent)
|
||||
params.RecordRentDuration = 10 * time.Second
|
||||
params.AuthorityGracePeriod = 10 * time.Second
|
||||
sr.Equal(param.GetParams().String(), params.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdQueryForRecords() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var recordID string
|
||||
var bondId string
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
preRun func()
|
||||
}{
|
||||
{
|
||||
"invalid request",
|
||||
[]string{"invalid", fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
0,
|
||||
func() {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"get records list",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
func() {
|
||||
CreateBond(s)
|
||||
// get the bond id from bond list
|
||||
bondId := GetBondId(s)
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
args := []string{
|
||||
payloadPath, bondId,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
clientCtx := val.ClientCtx
|
||||
if !tc.expErr {
|
||||
tc.preRun()
|
||||
}
|
||||
cmd := cli.GetCmdList()
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var records []types.RecordType
|
||||
err := json.Unmarshal(out.Bytes(), &records)
|
||||
sr.NoError(err)
|
||||
sr.Equal(tc.noOfRecords, len(records))
|
||||
recordID = records[0].Id
|
||||
bondId = GetBondId(s)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
s.T().Log("Test Cases for getting records by record-id")
|
||||
testCasesByRecordID := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
}{
|
||||
{
|
||||
"invalid request without record id",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"get records by id",
|
||||
[]string{recordID, fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesByRecordID {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdGetResource()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryRecordByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
sr.NotNil(response.GetRecord())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
s.T().Log("Test Cases for getting records by bond-id")
|
||||
testCasesByRecordByBondID := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
}{
|
||||
{
|
||||
"invalid request without bond-id",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"get records by bond-id",
|
||||
[]string{bondId, fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesByRecordByBondID {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdQueryByBond()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryRecordByBondIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
s.T().Log("Test Cases for getting nameservice module account balance")
|
||||
testCasesForNameServiceModuleBalance := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"get nameservice module accounts balance",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForNameServiceModuleBalance {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdBalance()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.GetNameServiceModuleBalanceResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
sr.Equal(tc.noOfRecords, len(response.GetBalances()))
|
||||
balance := response.GetBalances()[0]
|
||||
sr.Equal(balance.AccountName, types.RecordRentModuleAccountName)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdWhoIs() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "test2"
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid request without name",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
1,
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"success query with name",
|
||||
[]string{authorityName, fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expErr {
|
||||
tc.preRun(authorityName)
|
||||
}
|
||||
cmd := cli.GetCmdWhoIs()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryWhoisResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
nameAuthority := response.GetNameAuthority()
|
||||
nameAuthority.OwnerAddress = accountAddress
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdLookupCRN() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "test1"
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid request without crn",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
0,
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"success query with name",
|
||||
[]string{fmt.Sprintf("crn://%s/", authorityName), fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
createNameRecord(authorityName, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expErr {
|
||||
// set-name with crn and bond-id
|
||||
tc.preRun(authorityName)
|
||||
}
|
||||
cmd := cli.GetCmdLookupCRN()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryLookupCrnResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
nameRecord := response.GetName()
|
||||
sr.NotNil(nameRecord.Latest.Id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
testCasesForNamesList := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"invalid request without crn",
|
||||
[]string{"invalid", fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"success query with name",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForNamesList {
|
||||
s.Run(tc.name, func() {
|
||||
cmd := cli.GetCmdNames()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryListNameRecordsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetNames()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) GetRecordExpiryQueue() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "GetRecordExpiryQueue"
|
||||
|
||||
testCasesForRecordsExpiry := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
preRun func(authorityName string, s *IntegrationTestSuite)
|
||||
}{
|
||||
{
|
||||
"invalid request",
|
||||
[]string{"invalid", fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
0,
|
||||
func(authorityName string, s *IntegrationTestSuite) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"get expiry records ",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
1,
|
||||
func(authorityName string, s *IntegrationTestSuite) {
|
||||
createNameRecord(authorityName, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForRecordsExpiry {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expErr {
|
||||
tc.preRun(authorityName, s)
|
||||
time.Sleep(time.Second * 12)
|
||||
}
|
||||
cmd := cli.GetRecordExpiryQueue()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryGetRecordExpiryQueueResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
sr.Equal(tc.noOfRecords, len(response.GetRecords()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
func (s *IntegrationTestSuite) TestGetAuthorityExpiryQueue() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "TestGetAuthorityExpiryQueue"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expErr bool
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid request without name",
|
||||
[]string{"invalid", fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
true,
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"success query",
|
||||
[]string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)},
|
||||
false,
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.name, func() {
|
||||
if !tc.expErr {
|
||||
tc.preRun(authorityName)
|
||||
time.Sleep(time.Second * 6)
|
||||
}
|
||||
cmd := cli.GetAuthorityExpiryQueue()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.expErr {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var response types.QueryGetAuthorityExpiryQueueResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
sr.NotZero(len(response.GetAuthorities()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func createNameRecord(authorityName string, s *IntegrationTestSuite) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// creating the bond
|
||||
CreateBond(s)
|
||||
|
||||
// Get the bond-id
|
||||
bondId := GetBondId(s)
|
||||
|
||||
// adding bond-id to name authority
|
||||
args = []string{
|
||||
authorityName, bondId,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
cmd = cli.GetCmdSetAuthorityBond()
|
||||
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
args = []string{
|
||||
fmt.Sprintf("crn://%s/", authorityName),
|
||||
"test_hello_cid",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
|
||||
cmd = cli.GetCmdSetName()
|
||||
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
@@ -0,0 +1,913 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
|
||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
banktestutil "github.com/cosmos/cosmos-sdk/x/bank/client/testutil"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
"github.com/tharsis/ethermint/testutil/network"
|
||||
bondcli "github.com/tharsis/ethermint/x/bond/client/cli"
|
||||
"github.com/tharsis/ethermint/x/bond/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/client/cli"
|
||||
nstypes "github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
var (
|
||||
accountName = "accountName"
|
||||
accountAddress string
|
||||
)
|
||||
|
||||
type IntegrationTestSuite struct {
|
||||
suite.Suite
|
||||
|
||||
cfg network.Config
|
||||
network *network.Network
|
||||
bondId string
|
||||
}
|
||||
|
||||
func NewIntegrationTestSuite(cfg network.Config) *IntegrationTestSuite {
|
||||
return &IntegrationTestSuite{cfg: cfg}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) SetupSuite() {
|
||||
s.T().Log("setting up integration test suite")
|
||||
|
||||
var genesisState = s.cfg.GenesisState
|
||||
var nsData nstypes.GenesisState
|
||||
s.Require().NoError(s.cfg.Codec.UnmarshalJSON(genesisState[nstypes.ModuleName], &nsData))
|
||||
|
||||
nsData.Params.RecordRent = sdk.NewCoin(s.cfg.BondDenom, nstypes.DefaultRecordRent)
|
||||
nsData.Params.RecordRentDuration = 10 * time.Second
|
||||
nsData.Params.AuthorityGracePeriod = 10 * time.Second
|
||||
nsDataBz, err := s.cfg.Codec.MarshalJSON(&nsData)
|
||||
s.Require().NoError(err)
|
||||
genesisState[nstypes.ModuleName] = nsDataBz
|
||||
s.cfg.GenesisState = genesisState
|
||||
|
||||
s.network, err = network.New(s.T(), s.T().TempDir(), s.cfg)
|
||||
s.Require().NoError(err)
|
||||
|
||||
_, err = s.network.WaitForHeight(2)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// setting up random account
|
||||
s.createAccountWithBalance(accountName)
|
||||
CreateBond(s)
|
||||
s.bondId = GetBondId(s)
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) createAccountWithBalance(accountName string) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
consPrivKey := ed25519.GenPrivKey()
|
||||
consPubKeyBz, err := s.cfg.Codec.MarshalInterfaceJSON(consPrivKey.PubKey())
|
||||
sr.NoError(err)
|
||||
sr.NotNil(consPubKeyBz)
|
||||
|
||||
info, _, err := val.ClientCtx.Keyring.NewMnemonic(accountName, keyring.English, sdk.FullFundraiserPath, keyring.DefaultBIP39Passphrase, hd.Secp256k1)
|
||||
sr.NoError(err)
|
||||
|
||||
// account key
|
||||
newAddr := sdk.AccAddress(info.GetPubKey().Address())
|
||||
_, err = banktestutil.MsgSendExec(
|
||||
val.ClientCtx,
|
||||
val.Address,
|
||||
newAddr,
|
||||
sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(1000000000000000000))),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()),
|
||||
)
|
||||
sr.NoError(err)
|
||||
accountAddress = newAddr.String()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TearDownSuite() {
|
||||
s.T().Log("tearing down integration test suite")
|
||||
s.network.Cleanup()
|
||||
}
|
||||
|
||||
func CreateBond(s *IntegrationTestSuite) {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"create bond",
|
||||
[]string{
|
||||
fmt.Sprintf("100000000000%s", s.cfg.BondDenom),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := bondcli.NewCreateBondCmd()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func GetBondId(s *IntegrationTestSuite) string {
|
||||
cmd := bondcli.GetQueryBondLists()
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
clientCtx := val.ClientCtx
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, []string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)})
|
||||
sr.NoError(err)
|
||||
var queryResponse types.QueryGetBondsResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &queryResponse)
|
||||
sr.NoError(err)
|
||||
|
||||
// extract bond id from bonds list
|
||||
bond := queryResponse.GetBonds()[0]
|
||||
return bond.GetId()
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdSetRecord() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"invalid request without bond id/without payload",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"success",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
if !tc.err {
|
||||
// create the bond
|
||||
CreateBond(s)
|
||||
// get the bond id from bond list
|
||||
bondId := GetBondId(s)
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
|
||||
tc.args = append([]string{payloadPath, bondId}, tc.args...)
|
||||
}
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdReserveName() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "testtest"
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
"invalid request without name",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"success for parent name",
|
||||
[]string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"success for sub domains",
|
||||
[]string{
|
||||
"sub." + authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdSetName() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "TestGetCmdSetName"
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid request without name",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"success",
|
||||
[]string{
|
||||
fmt.Sprintf("crn://%s/", authorityName),
|
||||
"test_hello_cid",
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// creating the bond
|
||||
CreateBond(s)
|
||||
|
||||
// Get the bond-id
|
||||
bondId := GetBondId(s)
|
||||
|
||||
// adding bond-id to name authority
|
||||
args = []string{
|
||||
authorityName, bondId,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
cmd = cli.GetCmdSetAuthorityBond()
|
||||
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
if !tc.err {
|
||||
tc.preRun(authorityName)
|
||||
}
|
||||
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetName()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdSetAuthorityBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "TestGetCmdSetAuthorityBond"
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func(authorityName string)
|
||||
}{
|
||||
{
|
||||
"invalid request without name",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
func(authorityName string) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"success with name and bond-id",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
func(authorityName string) {
|
||||
// reserving the name
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdReserveName()
|
||||
args := []string{
|
||||
authorityName,
|
||||
fmt.Sprintf("--owner=%s", accountAddress),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
if !tc.err {
|
||||
// reserve the name
|
||||
tc.preRun(authorityName)
|
||||
// creating the bond
|
||||
CreateBond(s)
|
||||
// getting the bond-id
|
||||
bondId := GetBondId(s)
|
||||
tc.args = append([]string{authorityName, bondId}, tc.args...)
|
||||
}
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetAuthorityBond()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdDeleteName() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
var authorityName = "TestGetCmdDeleteName"
|
||||
testCasesForDeletingName := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func(authorityName string, s *IntegrationTestSuite)
|
||||
}{
|
||||
{
|
||||
"invalid request without crn",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
func(authorityName string, s *IntegrationTestSuite) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"successfully delete name",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
func(authorityName string, s *IntegrationTestSuite) {
|
||||
createNameRecord(authorityName, s)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForDeletingName {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
if !tc.err {
|
||||
tc.preRun(authorityName, s)
|
||||
tc.args = append([]string{fmt.Sprintf("crn://%s/", authorityName)}, tc.args...)
|
||||
}
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdDeleteName()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdDissociateBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
testCasesForDeletingName := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func(s *IntegrationTestSuite) string
|
||||
postRun func(recordId string, s *IntegrationTestSuite)
|
||||
}{
|
||||
{
|
||||
"invalid request without crn",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
func(s *IntegrationTestSuite) string {
|
||||
return ""
|
||||
},
|
||||
func(recordId string, s *IntegrationTestSuite) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"successfully dissociate bond-id from record ",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
func(s *IntegrationTestSuite) string {
|
||||
// create the bond
|
||||
CreateBond(s)
|
||||
// get the bond id from bond list
|
||||
bondId := GetBondId(s)
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
|
||||
args := []string{
|
||||
payloadPath, bondId,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// retrieving the record-id
|
||||
args = []string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
cmd = cli.GetCmdList()
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var records []nstypes.RecordType
|
||||
err = json.Unmarshal(out.Bytes(), &records)
|
||||
sr.NoError(err)
|
||||
return records[0].Id
|
||||
},
|
||||
func(recordId string, s *IntegrationTestSuite) {
|
||||
// checking the bond-id removed or not
|
||||
clientCtx := val.ClientCtx
|
||||
args := []string{recordId, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
cmd := cli.GetCmdGetResource()
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var response nstypes.QueryRecordByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
record := response.GetRecord()
|
||||
sr.NotNil(record)
|
||||
sr.Zero(len(record.GetBondId()))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForDeletingName {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
var recordId string
|
||||
if !tc.err {
|
||||
recordId = tc.preRun(s)
|
||||
tc.args = append([]string{recordId}, tc.args...)
|
||||
}
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdDissociateBond()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
// post-run
|
||||
tc.postRun(recordId, s)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//func (s *IntegrationTestSuite) TestGetCmdDissociateRecords() {
|
||||
// val := s.network.Validators[0]
|
||||
// sr := s.Require()
|
||||
// testCasesForDeletingName := []struct {
|
||||
// name string
|
||||
// args []string
|
||||
// err bool
|
||||
// preRun func(s *IntegrationTestSuite) (string, string)
|
||||
// postRun func(recordId string, s *IntegrationTestSuite)
|
||||
// }{
|
||||
// {
|
||||
// "invalid request without crn",
|
||||
// []string{
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
// fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
// fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
// },
|
||||
// true,
|
||||
// func(s *IntegrationTestSuite) (string, string) {
|
||||
// return "", ""
|
||||
// },
|
||||
// func(recordId string, s *IntegrationTestSuite) {
|
||||
//
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// "successfully dissociate records from bond-id",
|
||||
// []string{
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
// fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
// fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
// },
|
||||
// false,
|
||||
// func(s *IntegrationTestSuite) (string, string) {
|
||||
// // create the bond
|
||||
// CreateBond(s)
|
||||
// // get the bond id from bond list
|
||||
// bondId := GetBondId(s)
|
||||
// dir, err := os.Getwd()
|
||||
// sr.NoError(err)
|
||||
// payloadPath := dir + "/example1.yml"
|
||||
//
|
||||
// args := []string{
|
||||
// payloadPath, bondId,
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
// fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
// fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
// fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
// }
|
||||
//
|
||||
// clientCtx := val.ClientCtx
|
||||
// cmd := cli.GetCmdSetRecord()
|
||||
//
|
||||
// out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
// sr.NoError(err)
|
||||
// var d sdk.TxResponse
|
||||
// err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
// sr.NoError(err)
|
||||
// sr.Zero(d.Code)
|
||||
//
|
||||
// // retrieving the record-id
|
||||
// args = []string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
// cmd = cli.GetCmdList()
|
||||
// out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
// sr.NoError(err)
|
||||
// var records []nstypes.RecordType
|
||||
// err = json.Unmarshal(out.Bytes(), &records)
|
||||
// sr.NoError(err)
|
||||
// for _, record := range records {
|
||||
// if len(record.BondId) != 0 {
|
||||
// return record.Id, record.BondId
|
||||
// }
|
||||
// }
|
||||
// return records[0].Id, records[0].BondId
|
||||
// },
|
||||
// func(recordId string, s *IntegrationTestSuite) {
|
||||
// // checking the bond-id removed or not
|
||||
// clientCtx := val.ClientCtx
|
||||
// args := []string{recordId, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
// cmd := cli.GetCmdGetResource()
|
||||
// out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
// sr.NoError(err)
|
||||
// var response nstypes.QueryRecordByIdResponse
|
||||
// err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
// sr.NoError(err)
|
||||
// record := response.GetRecord()
|
||||
// sr.NotNil(record)
|
||||
// sr.Zero(len(record.GetBondId()))
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// for _, tc := range testCasesForDeletingName {
|
||||
// s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
// var bondId string
|
||||
// var recordId string
|
||||
// if !tc.err {
|
||||
// recordId, bondId = tc.preRun(s)
|
||||
// tc.args = append([]string{bondId}, tc.args...)
|
||||
// }
|
||||
// clientCtx := val.ClientCtx
|
||||
// cmd := cli.GetCmdDissociateRecords()
|
||||
//
|
||||
// out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
// if tc.err {
|
||||
// sr.Error(err)
|
||||
// } else {
|
||||
// sr.NoError(err)
|
||||
// var d sdk.TxResponse
|
||||
// err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
// sr.NoError(err)
|
||||
// sr.Zero(d.Code)
|
||||
// // post-run
|
||||
// tc.postRun(recordId, s)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//}
|
||||
|
||||
func (s *IntegrationTestSuite) TestGetCmdAssociateBond() {
|
||||
val := s.network.Validators[0]
|
||||
sr := s.Require()
|
||||
testCasesForDeletingName := []struct {
|
||||
name string
|
||||
args []string
|
||||
err bool
|
||||
preRun func(s *IntegrationTestSuite) (string, string)
|
||||
postRun func(recordId, bondId string, s *IntegrationTestSuite)
|
||||
}{
|
||||
{
|
||||
"invalid request without crn",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
true,
|
||||
func(s *IntegrationTestSuite) (string, string) {
|
||||
return "", ""
|
||||
},
|
||||
func(recordId, bondId string, s *IntegrationTestSuite) {
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
"successfully dissociate records from bond-id",
|
||||
[]string{
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
},
|
||||
false,
|
||||
func(s *IntegrationTestSuite) (string, string) {
|
||||
// create the bond
|
||||
CreateBond(s)
|
||||
// get the bond id from bond list
|
||||
bondId := GetBondId(s)
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payloadPath := dir + "/example1.yml"
|
||||
|
||||
txArgs := []string{
|
||||
payloadPath, bondId,
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, accountName),
|
||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||
fmt.Sprintf("--%s=json", tmcli.OutputFlag),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, fmt.Sprintf("3%s", s.cfg.BondDenom)),
|
||||
}
|
||||
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdSetRecord()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, txArgs)
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
// retrieving the record-id
|
||||
args := []string{fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
cmd = cli.GetCmdList()
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var records []nstypes.RecordType
|
||||
err = json.Unmarshal(out.Bytes(), &records)
|
||||
sr.NoError(err)
|
||||
|
||||
// GetCmdDissociateBond bond
|
||||
cmd = cli.GetCmdDissociateBond()
|
||||
txArgs = append([]string{records[0].Id}, txArgs[2:]...)
|
||||
out, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, txArgs)
|
||||
sr.NoError(err)
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
|
||||
return records[0].Id, records[0].BondId
|
||||
},
|
||||
func(recordId, bondId string, s *IntegrationTestSuite) {
|
||||
// checking the bond-id removed or not
|
||||
clientCtx := val.ClientCtx
|
||||
args := []string{recordId, fmt.Sprintf("--%s=json", tmcli.OutputFlag)}
|
||||
cmd := cli.GetCmdGetResource()
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
|
||||
sr.NoError(err)
|
||||
var response nstypes.QueryRecordByIdResponse
|
||||
err = clientCtx.Codec.UnmarshalJSON(out.Bytes(), &response)
|
||||
sr.NoError(err)
|
||||
record := response.GetRecord()
|
||||
sr.NotNil(record)
|
||||
sr.Equal(record.GetBondId(), bondId)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCasesForDeletingName {
|
||||
s.Run(fmt.Sprintf("Case %s", tc.name), func() {
|
||||
var recordId string
|
||||
var bondId string
|
||||
if !tc.err {
|
||||
recordId, bondId = tc.preRun(s)
|
||||
tc.args = append([]string{recordId, bondId}, tc.args...)
|
||||
}
|
||||
clientCtx := val.ClientCtx
|
||||
cmd := cli.GetCmdAssociateBond()
|
||||
|
||||
out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
|
||||
if tc.err {
|
||||
sr.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
var d sdk.TxResponse
|
||||
err = val.ClientCtx.Codec.UnmarshalJSON(out.Bytes(), &d)
|
||||
sr.NoError(err)
|
||||
sr.Zero(d.Code)
|
||||
// post-run
|
||||
tc.postRun(recordId, bondId, s)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package nameservice
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/keeper"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func InitGenesis(ctx sdk.Context, keeper keeper.Keeper, data types.GenesisState) []abci.ValidatorUpdate {
|
||||
keeper.SetParams(ctx, data.Params)
|
||||
|
||||
for _, record := range data.Records {
|
||||
keeper.PutRecord(ctx, record)
|
||||
|
||||
// Add to record expiry queue if expiry time is in the future.
|
||||
expiryTime, err := time.Parse(time.RFC3339, record.ExpiryTime)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if expiryTime.After(ctx.BlockTime()) {
|
||||
keeper.InsertRecordExpiryQueue(ctx, record)
|
||||
}
|
||||
|
||||
// Note: Bond genesis runs first, so bonds will already be present.
|
||||
if record.BondId != "" {
|
||||
keeper.AddBondToRecordIndexEntry(ctx, record.BondId, record.Id)
|
||||
}
|
||||
}
|
||||
|
||||
for _, authority := range data.Authorities {
|
||||
//Only import authorities that are marked active.
|
||||
if authority.Entry.Status == types.AuthorityActive {
|
||||
keeper.SetNameAuthority(ctx, authority.Name, authority.Entry)
|
||||
|
||||
// Add authority name to expiry queue.
|
||||
keeper.InsertAuthorityExpiryQueue(ctx, authority.Name, authority.Entry.ExpiryTime)
|
||||
|
||||
// Note: Bond genesis runs first, so bonds will already be present.
|
||||
if authority.Entry.BondId != "" {
|
||||
keeper.AddBondToAuthorityIndexEntry(ctx, authority.Entry.BondId, authority.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, nameEntry := range data.Names {
|
||||
keeper.SetNameRecord(ctx, nameEntry.Name, nameEntry.Entry.Latest.Id)
|
||||
}
|
||||
|
||||
return []abci.ValidatorUpdate{}
|
||||
}
|
||||
|
||||
func ExportGenesis(ctx sdk.Context, keeper keeper.Keeper) types.GenesisState {
|
||||
params := keeper.GetParams(ctx)
|
||||
|
||||
records := keeper.ListRecords(ctx)
|
||||
|
||||
authorities := keeper.ListNameAuthorityRecords(ctx)
|
||||
var authorityEntries []types.AuthorityEntry
|
||||
for name, record := range authorities {
|
||||
authorityEntries = append(authorityEntries, types.AuthorityEntry{
|
||||
Name: name,
|
||||
Entry: &record,
|
||||
})
|
||||
}
|
||||
|
||||
names := keeper.ListNameRecords(ctx)
|
||||
|
||||
return types.GenesisState{
|
||||
Params: params,
|
||||
Records: records,
|
||||
Authorities: authorityEntries,
|
||||
Names: names,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
record:
|
||||
attr1: value1
|
||||
attr2: value2
|
||||
link1:
|
||||
/: QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D
|
||||
link2:
|
||||
/: QmP8jTG1m9GSDJLCbeWhVSVgEzCPPwXRdCRuJtQ5Tz9Kc9
|
||||
@@ -0,0 +1,144 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/gob"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
set "github.com/deckarep/golang-set"
|
||||
cbor "github.com/ipfs/go-ipld-cbor"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
|
||||
"sort"
|
||||
)
|
||||
|
||||
func StringToBytes(val string) []byte {
|
||||
return []byte(val)
|
||||
}
|
||||
|
||||
func BytesToString(val []byte) string {
|
||||
return string(val)
|
||||
}
|
||||
|
||||
func StrArrToBytesArr(val []string) ([]byte, error) {
|
||||
buffer := &bytes.Buffer{}
|
||||
|
||||
err := gob.NewEncoder(buffer).Encode(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
func BytesArrToStringArr(val []byte) ([]string, error) {
|
||||
buffer := bytes.NewReader(val)
|
||||
var v []string
|
||||
err := gob.NewDecoder(buffer).Decode(&v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func Int64ToBytes(num int64) []byte {
|
||||
buf := new(bytes.Buffer)
|
||||
binary.Write(buf, binary.BigEndian, num)
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// MarshalMapToJSONBytes converts map[string]interface{} to bytes.
|
||||
func MarshalMapToJSONBytes(val map[string]interface{}) (bytes []byte) {
|
||||
bytes, err := json.Marshal(val)
|
||||
if err != nil {
|
||||
panic("Marshal error.")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UnMarshalMapFromJSONBytes converts bytes to map[string]interface{}.
|
||||
func UnMarshalMapFromJSONBytes(bytes []byte) map[string]interface{} {
|
||||
var val map[string]interface{}
|
||||
err := json.Unmarshal(bytes, &val)
|
||||
|
||||
if err != nil {
|
||||
panic("Marshal error.")
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
// GetCid gets the content ID.
|
||||
func GetCid(content []byte) (string, error) {
|
||||
node, err := cbor.FromJSON(bytes.NewReader(content), mh.SHA2_256, -1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return node.Cid().String(), nil
|
||||
}
|
||||
|
||||
// BytesToBase64 encodes a byte array as a base64 string.
|
||||
func BytesToBase64(bytes []byte) string {
|
||||
return base64.StdEncoding.EncodeToString(bytes)
|
||||
}
|
||||
|
||||
// BytesFromBase64 decodes a byte array from a base64 string.
|
||||
func BytesFromBase64(str string) []byte {
|
||||
bytes, err := base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
panic("Error decoding string to bytes.")
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
// BytesToHex encodes a byte array as a hex string.
|
||||
func BytesToHex(bytes []byte) string {
|
||||
return hex.EncodeToString(bytes)
|
||||
}
|
||||
|
||||
// BytesFromHex decodes a byte array from a hex string.
|
||||
func BytesFromHex(str string) []byte {
|
||||
bytes, err := hex.DecodeString(str)
|
||||
if err != nil {
|
||||
panic("Error decoding hex to bytes.")
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
func SetToSlice(set set.Set) []string {
|
||||
names := []string{}
|
||||
|
||||
for name := range set.Iter() {
|
||||
if name, ok := name.(string); ok && name != "" {
|
||||
names = append(names, name)
|
||||
}
|
||||
}
|
||||
|
||||
sort.SliceStable(names, func(i, j int) bool { return names[i] < names[j] })
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func SliceToSet(names []string) set.Set {
|
||||
set := set.NewThreadUnsafeSet()
|
||||
|
||||
for _, name := range names {
|
||||
if name != "" {
|
||||
set.Add(name)
|
||||
}
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func AppendUnique(list []string, element string) []string {
|
||||
set := SliceToSet(list)
|
||||
set.Add(element)
|
||||
|
||||
return SetToSlice(set)
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// BondIDAttributeName denotes the record bond ID.
|
||||
const BondIDAttributeName = "bondId"
|
||||
|
||||
// ExpiryTimeAttributeName denotes the record expiry time.
|
||||
const ExpiryTimeAttributeName = "expiryTime"
|
||||
|
||||
type Querier struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
var _ types.QueryServer = Querier{}
|
||||
|
||||
func (q Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
params := q.Keeper.GetParams(ctx)
|
||||
return &types.QueryParamsResponse{Params: ¶ms}, nil
|
||||
}
|
||||
|
||||
func (q Querier) ListRecords(c context.Context, req *types.QueryListRecordsRequest) (*types.QueryListRecordsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
attributes := req.GetAttributes()
|
||||
all := req.GetAll()
|
||||
records := []types.Record{}
|
||||
|
||||
if len(attributes) > 0 {
|
||||
records = q.Keeper.MatchRecords(ctx, func(record *types.RecordType) bool {
|
||||
return MatchOnAttributes(record, attributes, all)
|
||||
})
|
||||
} else {
|
||||
records = q.Keeper.ListRecords(ctx)
|
||||
}
|
||||
|
||||
return &types.QueryListRecordsResponse{Records: records}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetRecord(c context.Context, req *types.QueryRecordByIdRequest) (*types.QueryRecordByIdResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
id := req.GetId()
|
||||
if !q.Keeper.HasRecord(ctx, id) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "Record not found.")
|
||||
}
|
||||
record := q.Keeper.GetRecord(ctx, id)
|
||||
return &types.QueryRecordByIdResponse{Record: record}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetRecordByBondId(c context.Context, req *types.QueryRecordByBondIdRequest) (*types.QueryRecordByBondIdResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
records := q.recordKeeper.QueryRecordsByBond(ctx, req.GetId())
|
||||
return &types.QueryRecordByBondIdResponse{Records: records}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetNameServiceModuleBalance(c context.Context, _ *types.GetNameServiceModuleBalanceRequest) (*types.GetNameServiceModuleBalanceResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
balances := q.Keeper.GetModuleBalances(ctx)
|
||||
return &types.GetNameServiceModuleBalanceResponse{
|
||||
Balances: balances,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (q Querier) ListNameRecords(c context.Context, _ *types.QueryListNameRecordsRequest) (*types.QueryListNameRecordsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
nameRecords := q.Keeper.ListNameRecords(ctx)
|
||||
return &types.QueryListNameRecordsResponse{Names: nameRecords}, nil
|
||||
}
|
||||
|
||||
func (q Querier) Whois(c context.Context, request *types.QueryWhoisRequest) (*types.QueryWhoisResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
nameAuthority := q.Keeper.GetNameAuthority(ctx, request.GetName())
|
||||
return &types.QueryWhoisResponse{NameAuthority: nameAuthority}, nil
|
||||
}
|
||||
|
||||
func (q Querier) LookupCrn(c context.Context, req *types.QueryLookupCrn) (*types.QueryLookupCrnResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
crn := req.GetCrn()
|
||||
if !q.Keeper.HasNameRecord(ctx, crn) {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "CRN not found.")
|
||||
}
|
||||
nameRecord := q.Keeper.GetNameRecord(ctx, crn)
|
||||
if nameRecord == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "name record not found.")
|
||||
}
|
||||
return &types.QueryLookupCrnResponse{Name: nameRecord}, nil
|
||||
}
|
||||
|
||||
func (q Querier) ResolveCrn(c context.Context, req *types.QueryResolveCrn) (*types.QueryResolveCrnResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
crn := req.GetCrn()
|
||||
record := q.Keeper.ResolveCRN(ctx, crn)
|
||||
if record == nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, "record not found.")
|
||||
}
|
||||
return &types.QueryResolveCrnResponse{Record: record}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetRecordExpiryQueue(c context.Context, _ *types.QueryGetRecordExpiryQueue) (*types.QueryGetRecordExpiryQueueResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
records := q.Keeper.GetRecordExpiryQueue(ctx)
|
||||
return &types.QueryGetRecordExpiryQueueResponse{Records: records}, nil
|
||||
}
|
||||
|
||||
func (q Querier) GetAuthorityExpiryQueue(c context.Context, _ *types.QueryGetAuthorityExpiryQueue) (*types.QueryGetAuthorityExpiryQueueResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
authorities := q.Keeper.GetAuthorityExpiryQueue(ctx)
|
||||
return &types.QueryGetAuthorityExpiryQueueResponse{Authorities: authorities}, nil
|
||||
}
|
||||
|
||||
func matchOnRecordField(record *types.RecordType, attr *types.QueryListRecordsRequest_KeyValueInput) (fieldFound bool, matched bool) {
|
||||
fieldFound = false
|
||||
matched = true
|
||||
|
||||
switch attr.Key {
|
||||
case BondIDAttributeName:
|
||||
{
|
||||
fieldFound = true
|
||||
if record.BondId != attr.Value.GetString_() {
|
||||
matched = false
|
||||
return
|
||||
}
|
||||
}
|
||||
case ExpiryTimeAttributeName:
|
||||
{
|
||||
fieldFound = true
|
||||
if record.ExpiryTime != attr.Value.GetString_() {
|
||||
matched = false
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func MatchOnAttributes(record *types.RecordType, attributes []*types.QueryListRecordsRequest_KeyValueInput, all bool) bool {
|
||||
// Filter deleted records.
|
||||
if record.Deleted {
|
||||
return false
|
||||
}
|
||||
|
||||
// If ONLY named records are requested, check for that condition first.
|
||||
if !all && len(record.Names) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
recAttrs := record.Attributes
|
||||
|
||||
for _, attr := range attributes {
|
||||
// First try matching on record struct fields.
|
||||
fieldFound, matched := matchOnRecordField(record, attr)
|
||||
|
||||
if fieldFound {
|
||||
if !matched {
|
||||
return false
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
recAttrVal, recAttrFound := recAttrs[attr.Key]
|
||||
if !recAttrFound {
|
||||
return false
|
||||
}
|
||||
|
||||
if attr.Value.Type == "int" {
|
||||
recAttrValInt, ok := recAttrVal.(int)
|
||||
if !ok || int(attr.Value.GetInt()) != recAttrValInt {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "float" {
|
||||
recAttrValFloat, ok := recAttrVal.(float64)
|
||||
if !ok || attr.Value.GetFloat() != recAttrValFloat {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "string" {
|
||||
recAttrValString, ok := recAttrVal.(string)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
if attr.Value.GetString_() != recAttrValString {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "boolean" {
|
||||
recAttrValBool, ok := recAttrVal.(bool)
|
||||
if !ok || attr.Value.GetBoolean() != recAttrValBool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if attr.Value.Type == "reference" {
|
||||
obj, ok := recAttrVal.(map[string]interface{})
|
||||
if !ok {
|
||||
// Attr value is not an object.
|
||||
return false
|
||||
}
|
||||
|
||||
if _, ok := obj["/"].(string); !ok {
|
||||
// Attr value is not a reference.
|
||||
return false
|
||||
}
|
||||
|
||||
recAttrValRefID := obj["/"].(string)
|
||||
if recAttrValRefID != attr.Value.GetReference().GetId() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle arrays.
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/tharsis/ethermint/x/nameservice/client/cli"
|
||||
nameservicetypes "github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryParams() {
|
||||
grpcClient := suite.queryClient
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.QueryParamsRequest
|
||||
}{
|
||||
{
|
||||
"Get Params",
|
||||
&nameservicetypes.QueryParamsRequest{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
resp, _ := grpcClient.Params(context.Background(), test.req)
|
||||
defaultParams := nameservicetypes.DefaultParams()
|
||||
suite.Require().Equal(defaultParams.String(), resp.GetParams().String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcGetRecordLists() {
|
||||
grpcClient, ctx := suite.queryClient, suite.ctx
|
||||
sr := suite.Require()
|
||||
var recordId string
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.QueryListRecordsRequest
|
||||
createRecord bool
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"Empty Records",
|
||||
&nameservicetypes.QueryListRecordsRequest{},
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"List Records",
|
||||
&nameservicetypes.QueryListRecordsRequest{},
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createRecord {
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payload, err := cli.GetPayloadFromFile(dir + "/../helpers/examples/example1.yml")
|
||||
sr.NoError(err)
|
||||
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
|
||||
BondId: suite.bond.GetId(),
|
||||
Signer: suite.accounts[0].String(),
|
||||
Payload: payload.ToPayload(),
|
||||
})
|
||||
sr.NoError(err)
|
||||
sr.NotNil(record.Id)
|
||||
}
|
||||
resp, err := grpcClient.ListRecords(context.Background(), test.req)
|
||||
if test.expErr {
|
||||
suite.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.Equal(test.noOfRecords, len(resp.GetRecords()))
|
||||
if test.createRecord {
|
||||
recordId = resp.GetRecords()[0].GetId()
|
||||
sr.NotZero(resp.GetRecords())
|
||||
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetId())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Get the records by record id
|
||||
testCases1 := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.QueryRecordByIdRequest
|
||||
createRecord bool
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"Invalid Request without record id",
|
||||
&nameservicetypes.QueryRecordByIdRequest{},
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"With Record ID",
|
||||
&nameservicetypes.QueryRecordByIdRequest{
|
||||
Id: recordId,
|
||||
},
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases1 {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
resp, err := grpcClient.GetRecord(context.Background(), test.req)
|
||||
if test.expErr {
|
||||
suite.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.NotNil(resp.GetRecord())
|
||||
if test.createRecord {
|
||||
sr.Equal(resp.GetRecord().BondId, suite.bond.GetId())
|
||||
sr.Equal(resp.GetRecord().Id, recordId)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Get the records by record id
|
||||
testCasesByBondID := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.QueryRecordByBondIdRequest
|
||||
createRecord bool
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"Invalid Request without bond id",
|
||||
&nameservicetypes.QueryRecordByBondIdRequest{},
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"With Bond ID",
|
||||
&nameservicetypes.QueryRecordByBondIdRequest{
|
||||
Id: suite.bond.GetId(),
|
||||
},
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCasesByBondID {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
resp, err := grpcClient.GetRecordByBondId(context.Background(), test.req)
|
||||
if test.expErr {
|
||||
sr.Zero(resp.GetRecords())
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.NotNil(resp.GetRecords())
|
||||
if test.createRecord {
|
||||
sr.NotZero(resp.GetRecords())
|
||||
sr.Equal(resp.GetRecords()[0].GetBondId(), suite.bond.GetId())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryNameserviceModuleBalance() {
|
||||
grpcClient, ctx := suite.queryClient, suite.ctx
|
||||
sr := suite.Require()
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.GetNameServiceModuleBalanceRequest
|
||||
createRecord bool
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"Get Module Balance",
|
||||
&nameservicetypes.GetNameServiceModuleBalanceRequest{},
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createRecord {
|
||||
dir, err := os.Getwd()
|
||||
sr.NoError(err)
|
||||
payload, err := cli.GetPayloadFromFile(dir + "/../helpers/examples/example1.yml")
|
||||
sr.NoError(err)
|
||||
record, err := suite.app.NameServiceKeeper.ProcessSetRecord(ctx, nameservicetypes.MsgSetRecord{
|
||||
BondId: suite.bond.GetId(),
|
||||
Signer: suite.accounts[0].String(),
|
||||
Payload: payload.ToPayload(),
|
||||
})
|
||||
sr.NoError(err)
|
||||
sr.NotNil(record.Id)
|
||||
}
|
||||
resp, err := grpcClient.GetNameServiceModuleBalance(context.Background(), test.req)
|
||||
if test.expErr {
|
||||
suite.Error(err)
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
sr.Equal(test.noOfRecords, len(resp.GetBalances()))
|
||||
if test.createRecord {
|
||||
balance := resp.GetBalances()[0]
|
||||
sr.Equal(balance.AccountName, nameservicetypes.RecordRentModuleAccountName)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGrpcQueryWhoIS() {
|
||||
grpcClient, ctx := suite.queryClient, suite.ctx
|
||||
sr := suite.Require()
|
||||
var authorityName = "TestGrpcQueryWhoIS"
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
req *nameservicetypes.QueryWhoisRequest
|
||||
createName bool
|
||||
expErr bool
|
||||
noOfRecords int
|
||||
}{
|
||||
{
|
||||
"Invalid Request without name",
|
||||
&nameservicetypes.QueryWhoisRequest{},
|
||||
false,
|
||||
true,
|
||||
1,
|
||||
},
|
||||
{
|
||||
"Success",
|
||||
&nameservicetypes.QueryWhoisRequest{},
|
||||
true,
|
||||
false,
|
||||
1,
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
suite.Run(fmt.Sprintf("Case %s ", test.msg), func() {
|
||||
if test.createName {
|
||||
err := suite.app.NameServiceKeeper.ProcessReserveAuthority(ctx, nameservicetypes.MsgReserveAuthority{
|
||||
Name: authorityName,
|
||||
Signer: suite.accounts[0].String(),
|
||||
Owner: suite.accounts[0].String(),
|
||||
})
|
||||
sr.NoError(err)
|
||||
test.req = &nameservicetypes.QueryWhoisRequest{Name: authorityName}
|
||||
}
|
||||
resp, err := grpcClient.Whois(context.Background(), test.req)
|
||||
if test.expErr {
|
||||
sr.Zero(len(resp.NameAuthority.AuctionId))
|
||||
} else {
|
||||
sr.NoError(err)
|
||||
if test.createName {
|
||||
nameAuth := resp.NameAuthority
|
||||
sr.NotNil(nameAuth)
|
||||
sr.Equal(nameAuth.OwnerAddress, suite.accounts[0].String())
|
||||
sr.Equal(nameservicetypes.AuthorityActive, nameAuth.Status)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// RegisterInvariants registers all nameservice module invariants.
|
||||
func RegisterInvariants(ir sdk.InvariantRegistry, k Keeper) {
|
||||
ir.RegisterRoute(types.ModuleName, "record", RecordInvariants(k))
|
||||
}
|
||||
|
||||
// RecordInvariants checks that every record:
|
||||
// (1) has a corresponding naming record &
|
||||
// (2) associated bond exists, if bondID is not null.
|
||||
func RecordInvariants(k Keeper) sdk.Invariant {
|
||||
return func(ctx sdk.Context) (string, bool) {
|
||||
//store := ctx.KVStore(k.storeKey)
|
||||
//itr := sdk.KVStorePrefixIterator(store, PrefixCIDToRecordIndex)
|
||||
//defer itr.Close()
|
||||
//for ; itr.Valid(); itr.Next() {
|
||||
// bz := store.Get(itr.Key())
|
||||
// if bz != nil {
|
||||
// var obj types.RecordObj
|
||||
// k.cdc.MustUnmarshalBinaryBare(bz, &obj)
|
||||
// record := obj.ToRecord()
|
||||
//
|
||||
// if record.BondID != "" && !k.bondKeeper.HasBond(ctx, record.BondID) {
|
||||
// return sdk.FormatInvariant(types.ModuleName, "record-bond", fmt.Sprintf("Bond not found for record ID: '%s'.", record.ID)), true
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,437 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/legacy"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
auctionkeeper "github.com/tharsis/ethermint/x/auction/keeper"
|
||||
bondkeeper "github.com/tharsis/ethermint/x/bond/keeper"
|
||||
"github.com/tharsis/ethermint/x/nameservice/helpers"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// PrefixCIDToRecordIndex is the prefix for CID -> Record index.
|
||||
// Note: This is the primary index in the system.
|
||||
// Note: Golang doesn't support const arrays.
|
||||
PrefixCIDToRecordIndex = []byte{0x00}
|
||||
|
||||
// PrefixNameAuthorityRecordIndex is the prefix for the name -> NameAuthority index.
|
||||
PrefixNameAuthorityRecordIndex = []byte{0x01}
|
||||
|
||||
// PrefixCRNToNameRecordIndex is the prefix for the CRN -> NamingRecord index.
|
||||
PrefixCRNToNameRecordIndex = []byte{0x02}
|
||||
|
||||
// PrefixBondIDToRecordsIndex is the prefix for the Bond ID -> [Record] index.
|
||||
PrefixBondIDToRecordsIndex = []byte{0x03}
|
||||
|
||||
// PrefixBlockChangesetIndex is the prefix for the block changeset index.
|
||||
PrefixBlockChangesetIndex = []byte{0x04}
|
||||
|
||||
// PrefixAuctionToAuthorityNameIndex is the prefix for the auction ID -> authority name index.
|
||||
PrefixAuctionToAuthorityNameIndex = []byte{0x05}
|
||||
|
||||
// PrefixBondIDToAuthoritiesIndex is the prefix for the Bond ID -> [Authority] index.
|
||||
PrefixBondIDToAuthoritiesIndex = []byte{0x06}
|
||||
|
||||
// PrefixExpiryTimeToRecordsIndex is the prefix for the Expiry Time -> [Record] index.
|
||||
PrefixExpiryTimeToRecordsIndex = []byte{0x10}
|
||||
|
||||
// PrefixExpiryTimeToAuthoritiesIndex is the prefix for the Expiry Time -> [Authority] index.
|
||||
PrefixExpiryTimeToAuthoritiesIndex = []byte{0x11}
|
||||
|
||||
// PrefixCIDToNamesIndex the the reverse index for naming, i.e. maps CID -> []Names.
|
||||
// TODO(ashwin): Move out of WNS once we have an indexing service.
|
||||
PrefixCIDToNamesIndex = []byte{0xe0}
|
||||
)
|
||||
|
||||
// Keeper maintains the link to storage and exposes getter/setter methods for the various parts of the state machine
|
||||
type Keeper struct {
|
||||
accountKeeper auth.AccountKeeper
|
||||
bankKeeper bank.Keeper
|
||||
recordKeeper RecordKeeper
|
||||
bondKeeper bondkeeper.Keeper
|
||||
auctionKeeper auctionkeeper.Keeper
|
||||
|
||||
storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context
|
||||
|
||||
cdc codec.BinaryCodec // The wire codec for binary encoding/decoding.
|
||||
|
||||
paramSubspace paramtypes.Subspace
|
||||
}
|
||||
|
||||
// NewKeeper creates new instances of the nameservice Keeper
|
||||
func NewKeeper(cdc codec.BinaryCodec, accountKeeper auth.AccountKeeper, bankKeeper bank.Keeper, recordKeeper RecordKeeper,
|
||||
bondKeeper bondkeeper.Keeper, auctionKeeper auctionkeeper.Keeper, storeKey sdk.StoreKey, ps paramtypes.Subspace) Keeper {
|
||||
// set KeyTable if it has not already been set
|
||||
if !ps.HasKeyTable() {
|
||||
ps = ps.WithKeyTable(types.ParamKeyTable())
|
||||
}
|
||||
return Keeper{
|
||||
accountKeeper: accountKeeper,
|
||||
bankKeeper: bankKeeper,
|
||||
recordKeeper: recordKeeper,
|
||||
bondKeeper: bondKeeper,
|
||||
auctionKeeper: auctionKeeper,
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
paramSubspace: ps,
|
||||
}
|
||||
}
|
||||
|
||||
// GetRecordIndexKey Generates Bond ID -> Bond index key.
|
||||
func GetRecordIndexKey(id string) []byte {
|
||||
return append(PrefixCIDToRecordIndex, []byte(id)...)
|
||||
}
|
||||
|
||||
// HasRecord - checks if a record by the given ID exists.
|
||||
func (k Keeper) HasRecord(ctx sdk.Context, id string) bool {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return store.Has(GetRecordIndexKey(id))
|
||||
}
|
||||
|
||||
// GetRecord - gets a record from the store.
|
||||
func (k Keeper) GetRecord(ctx sdk.Context, id string) (record types.Record) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
result := store.Get(GetRecordIndexKey(id))
|
||||
k.cdc.MustUnmarshal(result, &record)
|
||||
return record
|
||||
}
|
||||
|
||||
// ListRecords - get all records.
|
||||
func (k Keeper) ListRecords(ctx sdk.Context) []types.Record {
|
||||
var records []types.Record
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixCIDToRecordIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Record
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
records = append(records, recordObjToRecord(store, k.cdc, obj))
|
||||
}
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
// MatchRecords - get all matching records.
|
||||
func (k Keeper) MatchRecords(ctx sdk.Context, matchFn func(*types.RecordType) bool) []types.Record {
|
||||
var records []types.Record
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixCIDToRecordIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var obj types.Record
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
obj = recordObjToRecord(store, k.cdc, obj)
|
||||
record := obj.ToRecordType()
|
||||
if matchFn(&record) {
|
||||
records = append(records, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
func (k Keeper) GetRecordExpiryQueue(ctx sdk.Context) []*types.ExpiryQueueRecord {
|
||||
var records []*types.ExpiryQueueRecord
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixExpiryTimeToRecordsIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
record, err := helpers.BytesArrToStringArr(itr.Value())
|
||||
if err != nil {
|
||||
return records
|
||||
}
|
||||
records = append(records, &types.ExpiryQueueRecord{
|
||||
Id: string(itr.Key()[len(PrefixExpiryTimeToRecordsIndex):]),
|
||||
Value: record,
|
||||
})
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
// ProcessSetRecord creates a record.
|
||||
func (k Keeper) ProcessSetRecord(ctx sdk.Context, msg types.MsgSetRecord) (*types.RecordType, error) {
|
||||
payload := msg.Payload.ToReadablePayload()
|
||||
record := types.RecordType{Attributes: payload.Record, BondId: msg.BondId}
|
||||
|
||||
// Check signatures.
|
||||
resourceSignBytes, _ := record.GetSignBytes()
|
||||
cid, err := record.GetCID()
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid record JSON")
|
||||
}
|
||||
|
||||
record.Id = cid
|
||||
|
||||
if exists := k.HasRecord(ctx, record.Id); exists {
|
||||
// Immutable record already exists. No-op.
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
record.Owners = []string{}
|
||||
for _, sig := range payload.Signatures {
|
||||
pubKey, err := legacy.PubKeyFromBytes(helpers.BytesFromBase64(sig.PubKey))
|
||||
if err != nil {
|
||||
fmt.Println("Error decoding pubKey from bytes: ", err)
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Invalid public key.")
|
||||
}
|
||||
|
||||
sigOK := pubKey.VerifySignature(resourceSignBytes, helpers.BytesFromBase64(sig.Sig))
|
||||
if !sigOK {
|
||||
fmt.Println("Signature mismatch: ", sig.PubKey)
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Invalid signature.")
|
||||
}
|
||||
record.Owners = append(record.Owners, pubKey.Address().String())
|
||||
}
|
||||
|
||||
// Sort owners list.
|
||||
sort.Strings(record.Owners)
|
||||
sdkErr := k.processRecord(ctx, &record, false)
|
||||
if sdkErr != nil {
|
||||
return nil, sdkErr
|
||||
}
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
func (k Keeper) processRecord(ctx sdk.Context, record *types.RecordType, isRenewal bool) error {
|
||||
params := k.GetParams(ctx)
|
||||
rent := params.RecordRent
|
||||
|
||||
err := k.bondKeeper.TransferCoinsToModuleAccount(ctx, record.BondId, types.RecordRentModuleAccountName, sdk.NewCoins(rent))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record.CreateTime = ctx.BlockHeader().Time.Format(time.RFC3339)
|
||||
record.ExpiryTime = ctx.BlockHeader().Time.Add(params.RecordRentDuration).Format(time.RFC3339)
|
||||
record.Deleted = false
|
||||
|
||||
k.PutRecord(ctx, record.ToRecordObj())
|
||||
k.InsertRecordExpiryQueue(ctx, record.ToRecordObj())
|
||||
|
||||
// Renewal doesn't change the name and bond indexes.
|
||||
if !isRenewal {
|
||||
k.AddBondToRecordIndexEntry(ctx, record.BondId, record.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PutRecord - saves a record to the store and updates ID -> Record index.
|
||||
func (k Keeper) PutRecord(ctx sdk.Context, record types.Record) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(GetRecordIndexKey(record.Id), k.cdc.MustMarshal(&record))
|
||||
k.updateBlockChangeSetForRecord(ctx, record.Id)
|
||||
}
|
||||
|
||||
// AddBondToRecordIndexEntry adds the Bond ID -> [Record] index entry.
|
||||
func (k Keeper) AddBondToRecordIndexEntry(ctx sdk.Context, bondID string, id string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(getBondIDToRecordsIndexKey(bondID, id), []byte{})
|
||||
}
|
||||
|
||||
// Generates Bond ID -> Records index key.
|
||||
func getBondIDToRecordsIndexKey(bondID string, id string) []byte {
|
||||
return append(append(PrefixBondIDToRecordsIndex, []byte(bondID)...), []byte(id)...)
|
||||
}
|
||||
|
||||
// getRecordExpiryQueueTimeKey gets the prefix for the record expiry queue.
|
||||
func getRecordExpiryQueueTimeKey(timestamp time.Time) []byte {
|
||||
timeBytes := sdk.FormatTimeBytes(timestamp)
|
||||
return append(PrefixExpiryTimeToRecordsIndex, timeBytes...)
|
||||
}
|
||||
|
||||
// SetRecordExpiryQueueTimeSlice sets a specific record expiry queue timeslice.
|
||||
func (k Keeper) SetRecordExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time, cids []string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz, _ := helpers.StrArrToBytesArr(cids)
|
||||
store.Set(getRecordExpiryQueueTimeKey(timestamp), bz)
|
||||
}
|
||||
|
||||
// DeleteRecordExpiryQueueTimeSlice deletes a specific record expiry queue timeslice.
|
||||
func (k Keeper) DeleteRecordExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(getRecordExpiryQueueTimeKey(timestamp))
|
||||
}
|
||||
|
||||
// GetRecordExpiryQueueTimeSlice gets a specific record queue timeslice.
|
||||
// A timeslice is a slice of CIDs corresponding to records that expire at a certain time.
|
||||
func (k Keeper) GetRecordExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time) []string {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
bz := store.Get(getRecordExpiryQueueTimeKey(timestamp))
|
||||
if bz == nil {
|
||||
return []string{}
|
||||
}
|
||||
cids, err := helpers.BytesArrToStringArr(bz)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
return cids
|
||||
}
|
||||
|
||||
// InsertRecordExpiryQueue inserts a record CID to the appropriate timeslice in the record expiry queue.
|
||||
func (k Keeper) InsertRecordExpiryQueue(ctx sdk.Context, val types.Record) {
|
||||
expiryTime, err := time.Parse(time.RFC3339, val.ExpiryTime)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
timeSlice := k.GetRecordExpiryQueueTimeSlice(ctx, expiryTime)
|
||||
timeSlice = append(timeSlice, val.Id)
|
||||
k.SetRecordExpiryQueueTimeSlice(ctx, expiryTime, timeSlice)
|
||||
}
|
||||
|
||||
// DeleteRecordExpiryQueue deletes a record CID from the record expiry queue.
|
||||
func (k Keeper) DeleteRecordExpiryQueue(ctx sdk.Context, record types.Record) {
|
||||
expiryTime, err := time.Parse(time.RFC3339, record.ExpiryTime)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
timeSlice := k.GetRecordExpiryQueueTimeSlice(ctx, expiryTime)
|
||||
var newTimeSlice []string
|
||||
|
||||
for _, cid := range timeSlice {
|
||||
if !bytes.Equal([]byte(cid), []byte(record.Id)) {
|
||||
newTimeSlice = append(newTimeSlice, cid)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newTimeSlice) == 0 {
|
||||
k.DeleteRecordExpiryQueueTimeSlice(ctx, expiryTime)
|
||||
} else {
|
||||
k.SetRecordExpiryQueueTimeSlice(ctx, expiryTime, newTimeSlice)
|
||||
}
|
||||
}
|
||||
|
||||
// RecordExpiryQueueIterator returns all the record expiry queue timeslices from time 0 until endTime.
|
||||
func (k Keeper) RecordExpiryQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
rangeEndBytes := sdk.InclusiveEndBytes(getRecordExpiryQueueTimeKey(endTime))
|
||||
return store.Iterator(PrefixExpiryTimeToRecordsIndex, rangeEndBytes)
|
||||
}
|
||||
|
||||
// GetAllExpiredRecords returns a concatenated list of all the timeslices before currTime.
|
||||
func (k Keeper) GetAllExpiredRecords(ctx sdk.Context, currTime time.Time) (expiredRecordCIDs []string) {
|
||||
// Gets an iterator for all timeslices from time 0 until the current block header time.
|
||||
itr := k.RecordExpiryQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
defer itr.Close()
|
||||
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
timeslice, err := helpers.BytesArrToStringArr(itr.Value())
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
expiredRecordCIDs = append(expiredRecordCIDs, timeslice...)
|
||||
}
|
||||
|
||||
return expiredRecordCIDs
|
||||
}
|
||||
|
||||
// ProcessRecordExpiryQueue tries to renew expiring records (by collecting rent) else marks them as deleted.
|
||||
func (k Keeper) ProcessRecordExpiryQueue(ctx sdk.Context) {
|
||||
cids := k.GetAllExpiredRecords(ctx, ctx.BlockHeader().Time)
|
||||
for _, cid := range cids {
|
||||
record := k.GetRecord(ctx, cid)
|
||||
|
||||
// If record doesn't have an associated bond or if bond no longer exists, mark it deleted.
|
||||
if record.BondId == "" || !k.bondKeeper.HasBond(ctx, record.BondId) {
|
||||
record.Deleted = true
|
||||
k.PutRecord(ctx, record)
|
||||
k.DeleteRecordExpiryQueue(ctx, record)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Try to renew the record by taking rent.
|
||||
k.TryTakeRecordRent(ctx, record)
|
||||
}
|
||||
}
|
||||
|
||||
// TryTakeRecordRent tries to take rent from the record bond.
|
||||
func (k Keeper) TryTakeRecordRent(ctx sdk.Context, record types.Record) {
|
||||
params := k.GetParams(ctx)
|
||||
rent := params.RecordRent
|
||||
sdkErr := k.bondKeeper.TransferCoinsToModuleAccount(ctx, record.BondId, types.RecordRentModuleAccountName, sdk.NewCoins(rent))
|
||||
|
||||
if sdkErr != nil {
|
||||
// Insufficient funds, mark record as deleted.
|
||||
record.Deleted = true
|
||||
k.PutRecord(ctx, record)
|
||||
k.DeleteRecordExpiryQueue(ctx, record)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Delete old expiry queue entry, create new one.
|
||||
k.DeleteRecordExpiryQueue(ctx, record)
|
||||
record.ExpiryTime = ctx.BlockHeader().Time.Add(params.RecordRentDuration).Format(time.RFC3339)
|
||||
k.InsertRecordExpiryQueue(ctx, record)
|
||||
|
||||
// Save record.
|
||||
record.Deleted = false
|
||||
k.PutRecord(ctx, record)
|
||||
k.AddBondToRecordIndexEntry(ctx, record.BondId, record.Id)
|
||||
}
|
||||
|
||||
// GetModuleBalances gets the nameservice module account(s) balances.
|
||||
func (k Keeper) GetModuleBalances(ctx sdk.Context) []*types.AccountBalance {
|
||||
var balances []*types.AccountBalance
|
||||
accountNames := []string{types.RecordRentModuleAccountName, types.AuthorityRentModuleAccountName}
|
||||
|
||||
for _, accountName := range accountNames {
|
||||
moduleAddress := k.accountKeeper.GetModuleAddress(accountName)
|
||||
moduleAccount := k.accountKeeper.GetAccount(ctx, moduleAddress)
|
||||
if moduleAccount != nil {
|
||||
accountBalance := k.bankKeeper.GetAllBalances(ctx, moduleAddress)
|
||||
balances = append(balances, &types.AccountBalance{
|
||||
AccountName: accountName,
|
||||
Balance: accountBalance,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return balances
|
||||
}
|
||||
|
||||
func recordObjToRecord(store sdk.KVStore, codec codec.BinaryCodec, record types.Record) types.Record {
|
||||
reverseNameIndexKey := GetCIDToNamesIndexKey(record.Id)
|
||||
|
||||
if store.Has(reverseNameIndexKey) {
|
||||
names, err := helpers.BytesArrToStringArr(store.Get(reverseNameIndexKey))
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
record.Names = names
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
"github.com/tharsis/ethermint/app"
|
||||
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
||||
nameservicekeeper "github.com/tharsis/ethermint/x/nameservice/keeper"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
type KeeperTestSuite struct {
|
||||
suite.Suite
|
||||
app *app.EthermintApp
|
||||
ctx sdk.Context
|
||||
queryClient types.QueryClient
|
||||
accounts []sdk.AccAddress
|
||||
bond bondtypes.Bond
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) SetupTest() {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
querier := nameservicekeeper.Querier{Keeper: testApp.NameServiceKeeper}
|
||||
|
||||
queryHelper := baseapp.NewQueryServerTestHelper(ctx, testApp.InterfaceRegistry())
|
||||
types.RegisterQueryServer(queryHelper, querier)
|
||||
queryClient := types.NewQueryClient(queryHelper)
|
||||
|
||||
suite.accounts = app.CreateRandomAccounts(1)
|
||||
account := suite.accounts[0]
|
||||
_ = simapp.FundAccount(testApp.BankKeeper, ctx, account, sdk.NewCoins(sdk.Coin{
|
||||
Denom: sdk.DefaultBondDenom,
|
||||
Amount: sdk.NewInt(100000000000),
|
||||
}))
|
||||
|
||||
bond, err := testApp.BondKeeper.CreateBond(ctx, account, sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(1000000000))))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
suite.bond = *bond
|
||||
suite.app, suite.ctx, suite.queryClient = testApp, ctx, queryClient
|
||||
}
|
||||
|
||||
func TestParams(t *testing.T) {
|
||||
testApp := app.Setup(false, func(ea *app.EthermintApp, genesis simapp.GenesisState) simapp.GenesisState {
|
||||
return genesis
|
||||
})
|
||||
ctx := testApp.BaseApp.NewContext(false, tmproto.Header{})
|
||||
|
||||
expParams := types.DefaultParams()
|
||||
params := testApp.NameServiceKeeper.GetParams(ctx)
|
||||
require.True(t, params.Equal(expParams))
|
||||
}
|
||||
|
||||
func TestKeeperTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(KeeperTestSuite))
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
type msgServer struct {
|
||||
Keeper
|
||||
}
|
||||
|
||||
// NewMsgServerImpl returns an implementation of the bond MsgServer interface for the provided Keeper.
|
||||
func NewMsgServerImpl(keeper Keeper) types.MsgServer {
|
||||
return &msgServer{Keeper: keeper}
|
||||
}
|
||||
|
||||
var _ types.MsgServer = msgServer{}
|
||||
|
||||
func (m msgServer) SetRecord(c context.Context, msg *types.MsgSetRecord) (*types.MsgSetRecordResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record, err := m.Keeper.ProcessSetRecord(ctx, types.MsgSetRecord{
|
||||
BondId: msg.GetBondId(),
|
||||
Signer: msg.GetSigner(),
|
||||
Payload: msg.GetPayload(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSetRecord,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.GetSigner()),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.GetBondId()),
|
||||
sdk.NewAttribute(types.AttributeKeyPayload, msg.Payload.String()),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
|
||||
return &types.MsgSetRecordResponse{Id: record.Id}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) SetName(c context.Context, msg *types.MsgSetName) (*types.MsgSetNameResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessSetName(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeSetRecord,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyCRN, msg.Crn),
|
||||
sdk.NewAttribute(types.AttributeKeyCID, msg.Cid),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgSetNameResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) ReserveName(c context.Context, msg *types.MsgReserveAuthority) (*types.MsgReserveAuthorityResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = sdk.AccAddressFromBech32(msg.Owner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessReserveAuthority(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeReserveNameAuthority,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyName, msg.Name),
|
||||
sdk.NewAttribute(types.AttributeKeyOwner, msg.Owner),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgReserveAuthorityResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) SetAuthorityBond(c context.Context, msg *types.MsgSetAuthorityBond) (*types.MsgSetAuthorityBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessSetAuthorityBond(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeAuthorityBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyName, msg.Name),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.BondId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgSetAuthorityBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) DeleteName(c context.Context, msg *types.MsgDeleteNameAuthority) (*types.MsgDeleteNameAuthorityResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessDeleteName(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeDeleteName,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyCRN, msg.Crn),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgDeleteNameAuthorityResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) RenewRecord(c context.Context, msg *types.MsgRenewRecord) (*types.MsgRenewRecordResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
err = m.Keeper.ProcessRenewRecord(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeRenewRecord,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyRecordId, msg.RecordId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgRenewRecordResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) AssociateBond(c context.Context, msg *types.MsgAssociateBond) (*types.MsgAssociateBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = m.Keeper.ProcessAssociateBond(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeAssociateBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyRecordId, msg.RecordId),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.BondId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgAssociateBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) DissociateBond(c context.Context, msg *types.MsgDissociateBond) (*types.MsgDissociateBondResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessDissociateBond(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeDissociateBond,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyRecordId, msg.RecordId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgDissociateBondResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) DissociateRecords(c context.Context, msg *types.MsgDissociateRecords) (*types.MsgDissociateRecordsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessDissociateRecords(ctx, *msg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeDissociateRecords,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyBondId, msg.BondId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgDissociateRecordsResponse{}, nil
|
||||
}
|
||||
|
||||
func (m msgServer) ReAssociateRecords(c context.Context, msg *types.MsgReAssociateRecords) (*types.MsgReAssociateRecordsResponse, error) {
|
||||
ctx := sdk.UnwrapSDKContext(c)
|
||||
_, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = m.Keeper.ProcessReAssociateRecords(ctx, *msg)
|
||||
ctx.EventManager().EmitEvents(sdk.Events{
|
||||
sdk.NewEvent(
|
||||
types.EventTypeReAssociateRecords,
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
sdk.NewAttribute(types.AttributeKeyOldBondId, msg.OldBondId),
|
||||
sdk.NewAttribute(types.AttributeKeyNewBondId, msg.NewBondId),
|
||||
),
|
||||
sdk.NewEvent(
|
||||
sdk.EventTypeMessage,
|
||||
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
|
||||
sdk.NewAttribute(types.AttributeKeySigner, msg.Signer),
|
||||
),
|
||||
})
|
||||
return &types.MsgReAssociateRecordsResponse{}, nil
|
||||
}
|
||||
@@ -0,0 +1,723 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
auctiontypes "github.com/tharsis/ethermint/x/auction/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/helpers"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func getAuthorityPubKey(pubKey cryptotypes.PubKey) string {
|
||||
if pubKey != nil {
|
||||
return helpers.BytesToBase64(pubKey.Bytes())
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetNameAuthorityIndexKey Generates name -> NameAuthority index key.
|
||||
func GetNameAuthorityIndexKey(name string) []byte {
|
||||
return append(PrefixNameAuthorityRecordIndex, []byte(name)...)
|
||||
}
|
||||
|
||||
// GetNameRecordIndexKey Generates CRN -> NameRecord index key.
|
||||
func GetNameRecordIndexKey(crn string) []byte {
|
||||
return append(PrefixCRNToNameRecordIndex, []byte(crn)...)
|
||||
}
|
||||
|
||||
func GetCIDToNamesIndexKey(id string) []byte {
|
||||
return append(PrefixCIDToNamesIndex, []byte(id)...)
|
||||
}
|
||||
|
||||
func SetNameAuthority(ctx sdk.Context, store sdk.KVStore, codec codec.BinaryCodec, name string, authority *types.NameAuthority) {
|
||||
store.Set(GetNameAuthorityIndexKey(name), codec.MustMarshal(authority))
|
||||
updateBlockChangeSetForNameAuthority(ctx, codec, store, name)
|
||||
}
|
||||
|
||||
// SetNameAuthority creates the NameAuthority record.
|
||||
func (k Keeper) SetNameAuthority(ctx sdk.Context, name string, authority *types.NameAuthority) {
|
||||
SetNameAuthority(ctx, ctx.KVStore(k.storeKey), k.cdc, name, authority)
|
||||
}
|
||||
|
||||
func removeAuctionToAuthorityMapping(store sdk.KVStore, auctionID string) {
|
||||
store.Delete(GetAuctionToAuthorityIndexKey(auctionID))
|
||||
}
|
||||
|
||||
func (k Keeper) RemoveAuctionToAuthorityMapping(ctx sdk.Context, auctionID string) {
|
||||
removeAuctionToAuthorityMapping(ctx.KVStore(k.storeKey), auctionID)
|
||||
}
|
||||
|
||||
// GetNameAuthority - gets a name authority from the store.
|
||||
func GetNameAuthority(store sdk.KVStore, codec codec.BinaryCodec, name string) types.NameAuthority {
|
||||
authorityKey := GetNameAuthorityIndexKey(name)
|
||||
if !store.Has(authorityKey) {
|
||||
return types.NameAuthority{}
|
||||
}
|
||||
|
||||
bz := store.Get(authorityKey)
|
||||
var obj types.NameAuthority
|
||||
codec.MustUnmarshal(bz, &obj)
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
// GetNameAuthority - gets a name authority from the store.
|
||||
func (k Keeper) GetNameAuthority(ctx sdk.Context, name string) types.NameAuthority {
|
||||
return GetNameAuthority(ctx.KVStore(k.storeKey), k.cdc, name)
|
||||
}
|
||||
|
||||
// HasNameAuthority - checks if a name authority entry exists.
|
||||
func HasNameAuthority(store sdk.KVStore, name string) bool {
|
||||
return store.Has(GetNameAuthorityIndexKey(name))
|
||||
}
|
||||
|
||||
// HasNameAuthority - checks if a name/authority exists.
|
||||
func (k Keeper) HasNameAuthority(ctx sdk.Context, name string) bool {
|
||||
return HasNameAuthority(ctx.KVStore(k.storeKey), name)
|
||||
}
|
||||
|
||||
func getBondIDToAuthoritiesIndexKey(bondID string, name string) []byte {
|
||||
return append(append(PrefixBondIDToAuthoritiesIndex, []byte(bondID)...), []byte(name)...)
|
||||
}
|
||||
|
||||
// AddBondToAuthorityIndexEntry adds the Bond ID -> [Authority] index entry.
|
||||
func (k Keeper) AddBondToAuthorityIndexEntry(ctx sdk.Context, bondID string, name string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(getBondIDToAuthoritiesIndexKey(bondID, name), []byte{})
|
||||
}
|
||||
|
||||
// RemoveBondToAuthorityIndexEntry removes the Bond ID -> [Authority] index entry.
|
||||
func (k Keeper) RemoveBondToAuthorityIndexEntry(ctx sdk.Context, bondID string, name string) {
|
||||
RemoveBondToAuthorityIndexEntry(ctx.KVStore(k.storeKey), bondID, name)
|
||||
}
|
||||
|
||||
func RemoveBondToAuthorityIndexEntry(store sdk.KVStore, bondID string, name string) {
|
||||
store.Delete(getBondIDToAuthoritiesIndexKey(bondID, name))
|
||||
}
|
||||
|
||||
func (k Keeper) updateBlockChangeSetForName(ctx sdk.Context, crn string) {
|
||||
changeSet := k.getOrCreateBlockChangeSet(ctx, ctx.BlockHeight())
|
||||
changeSet.Names = append(changeSet.Names, crn)
|
||||
k.saveBlockChangeSet(ctx, changeSet)
|
||||
}
|
||||
|
||||
func (k Keeper) getAuthority(ctx sdk.Context, crn string) (string, *url.URL, *types.NameAuthority, error) {
|
||||
parsedCRN, err := url.Parse(crn)
|
||||
if err != nil {
|
||||
return "", nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid CRN.")
|
||||
}
|
||||
|
||||
name := parsedCRN.Host
|
||||
if !k.HasNameAuthority(ctx, name) {
|
||||
return name, nil, nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Name authority not found.")
|
||||
}
|
||||
authority := k.GetNameAuthority(ctx, name)
|
||||
return name, parsedCRN, &authority, nil
|
||||
}
|
||||
|
||||
func (k Keeper) checkCRNAccess(ctx sdk.Context, signer sdk.AccAddress, crn string) error {
|
||||
name, parsedCRN, authority, err := k.getAuthority(ctx, crn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
formattedCRN := fmt.Sprintf("crn://%s%s", name, parsedCRN.RequestURI())
|
||||
if formattedCRN != crn {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid CRN.")
|
||||
}
|
||||
|
||||
if authority.OwnerAddress != signer.String() {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Access denied.")
|
||||
}
|
||||
|
||||
if authority.Status != types.AuthorityActive {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Authority is not active.")
|
||||
}
|
||||
|
||||
if authority.BondId == "" || len(authority.BondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Authority bond not found.")
|
||||
}
|
||||
|
||||
if authority.OwnerPublicKey == "" {
|
||||
// Try to set owner public key if account has it available now.
|
||||
ownerAccount := k.accountKeeper.GetAccount(ctx, signer)
|
||||
pubKey := ownerAccount.GetPubKey()
|
||||
if pubKey != nil {
|
||||
// Update public key in authority record.
|
||||
authority.OwnerPublicKey = getAuthorityPubKey(pubKey)
|
||||
k.SetNameAuthority(ctx, name, authority)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasNameRecord - checks if a name record exists.
|
||||
func (k Keeper) HasNameRecord(ctx sdk.Context, crn string) bool {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
return store.Has(GetNameRecordIndexKey(crn))
|
||||
}
|
||||
|
||||
// GetNameRecord - gets a name record from the store.
|
||||
func GetNameRecord(store sdk.KVStore, codec codec.BinaryCodec, crn string) *types.NameRecord {
|
||||
nameRecordKey := GetNameRecordIndexKey(crn)
|
||||
if !store.Has(nameRecordKey) {
|
||||
return nil
|
||||
}
|
||||
|
||||
bz := store.Get(nameRecordKey)
|
||||
var obj types.NameRecord
|
||||
codec.MustUnmarshal(bz, &obj)
|
||||
|
||||
return &obj
|
||||
}
|
||||
|
||||
// GetNameRecord - gets a name record from the store.
|
||||
func (k Keeper) GetNameRecord(ctx sdk.Context, crn string) *types.NameRecord {
|
||||
_, _, authority, err := k.getAuthority(ctx, crn)
|
||||
if err != nil || authority.Status != types.AuthorityActive {
|
||||
// If authority is not active (or any other error), lookup fails.
|
||||
return nil
|
||||
}
|
||||
|
||||
nameRecord := GetNameRecord(ctx.KVStore(k.storeKey), k.cdc, crn)
|
||||
|
||||
// Name record may not exist.
|
||||
if nameRecord == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name lookup should fail if the name record is stale.
|
||||
// i.e. authority was registered later than the name.
|
||||
if authority.Height > nameRecord.Latest.Height {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nameRecord
|
||||
}
|
||||
|
||||
// RemoveRecordToNameMapping removes a name from the record ID -> []names index.
|
||||
func RemoveRecordToNameMapping(store sdk.KVStore, id string, crn string) {
|
||||
reverseNameIndexKey := GetCIDToNamesIndexKey(id)
|
||||
|
||||
names, _ := helpers.BytesArrToStringArr(store.Get(reverseNameIndexKey))
|
||||
nameSet := helpers.SliceToSet(names)
|
||||
nameSet.Remove(crn)
|
||||
|
||||
if nameSet.Cardinality() == 0 {
|
||||
// Delete as storing empty slice throws error from baseapp.
|
||||
store.Delete(reverseNameIndexKey)
|
||||
} else {
|
||||
data, _ := helpers.StrArrToBytesArr(helpers.SetToSlice(nameSet))
|
||||
store.Set(reverseNameIndexKey, data)
|
||||
}
|
||||
}
|
||||
|
||||
// AddRecordToNameMapping adds a name to the record ID -> []names index.
|
||||
func AddRecordToNameMapping(store sdk.KVStore, id string, crn string) {
|
||||
reverseNameIndexKey := GetCIDToNamesIndexKey(id)
|
||||
|
||||
var names []string
|
||||
if store.Has(reverseNameIndexKey) {
|
||||
names, _ = helpers.BytesArrToStringArr(store.Get(reverseNameIndexKey))
|
||||
}
|
||||
|
||||
nameSet := helpers.SliceToSet(names)
|
||||
nameSet.Add(crn)
|
||||
bz, _ := helpers.StrArrToBytesArr(helpers.SetToSlice(nameSet))
|
||||
store.Set(reverseNameIndexKey, bz)
|
||||
}
|
||||
|
||||
// SetNameRecord - sets a name record.
|
||||
func SetNameRecord(store sdk.KVStore, codec codec.BinaryCodec, crn string, id string, height int64) {
|
||||
nameRecordIndexKey := GetNameRecordIndexKey(crn)
|
||||
|
||||
var nameRecord types.NameRecord
|
||||
if store.Has(nameRecordIndexKey) {
|
||||
bz := store.Get(nameRecordIndexKey)
|
||||
codec.MustUnmarshal(bz, &nameRecord)
|
||||
nameRecord.History = append(nameRecord.History, nameRecord.Latest)
|
||||
|
||||
// Update old CID -> []Name index.
|
||||
if nameRecord.Latest.Id != "" || len(nameRecord.Latest.Id) != 0 {
|
||||
RemoveRecordToNameMapping(store, nameRecord.Latest.Id, crn)
|
||||
}
|
||||
}
|
||||
|
||||
nameRecord.Latest = &types.NameRecordEntry{
|
||||
Id: id,
|
||||
Height: uint64(height),
|
||||
}
|
||||
|
||||
store.Set(nameRecordIndexKey, codec.MustMarshal(&nameRecord))
|
||||
|
||||
// Update new CID -> []Name index.
|
||||
if id != "" {
|
||||
AddRecordToNameMapping(store, id, crn)
|
||||
}
|
||||
}
|
||||
|
||||
// SetNameRecord - sets a name record.
|
||||
func (k Keeper) SetNameRecord(ctx sdk.Context, crn string, id string) {
|
||||
SetNameRecord(ctx.KVStore(k.storeKey), k.cdc, crn, id, ctx.BlockHeight())
|
||||
|
||||
// Update changeSet for name.
|
||||
k.updateBlockChangeSetForName(ctx, crn)
|
||||
}
|
||||
|
||||
// ProcessSetName creates a CRN -> Record ID mapping.
|
||||
func (k Keeper) ProcessSetName(ctx sdk.Context, msg types.MsgSetName) error {
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = k.checkCRNAccess(ctx, signerAddress, msg.Crn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nameRecord := k.GetNameRecord(ctx, msg.Crn)
|
||||
if nameRecord != nil && nameRecord.Latest.Id == msg.Cid {
|
||||
return nil
|
||||
}
|
||||
|
||||
k.SetNameRecord(ctx, msg.Crn, msg.Cid)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListNameRecords - get all name records.
|
||||
func (k Keeper) ListNameRecords(ctx sdk.Context) []types.NameEntry {
|
||||
var nameEntries []types.NameEntry
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixCRNToNameRecordIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var record types.NameRecord
|
||||
k.cdc.MustUnmarshal(bz, &record)
|
||||
nameEntries = append(nameEntries, types.NameEntry{
|
||||
Name: string(itr.Key()[len(PrefixCRNToNameRecordIndex):]),
|
||||
Entry: &record,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nameEntries
|
||||
}
|
||||
|
||||
// ProcessReserveSubAuthority reserves a sub-authority.
|
||||
func (k Keeper) ProcessReserveSubAuthority(ctx sdk.Context, name string, msg types.MsgReserveAuthority) error {
|
||||
// Get parent authority name.
|
||||
names := strings.Split(name, ".")
|
||||
parent := strings.Join(names[1:], ".")
|
||||
|
||||
// Check if parent authority exists.
|
||||
if !k.HasNameAuthority(ctx, parent) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Parent authority not found.")
|
||||
}
|
||||
parentAuthority := k.GetNameAuthority(ctx, parent)
|
||||
|
||||
// Sub-authority creator needs to be the owner of the parent authority.
|
||||
if parentAuthority.OwnerAddress != msg.Signer {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Access denied.")
|
||||
}
|
||||
|
||||
// Sub-authority owner defaults to parent authority owner.
|
||||
subAuthorityOwner := msg.Signer
|
||||
if len(msg.Owner) != 0 {
|
||||
// Override sub-authority owner if provided in message.
|
||||
subAuthorityOwner = msg.Owner
|
||||
}
|
||||
|
||||
sdkErr := k.createAuthority(ctx, name, subAuthorityOwner, false)
|
||||
if sdkErr != nil {
|
||||
return sdkErr
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetAuctionToAuthorityIndexKey(auctionID string) []byte {
|
||||
return append(PrefixAuctionToAuthorityNameIndex, []byte(auctionID)...)
|
||||
}
|
||||
|
||||
func (k Keeper) AddAuctionToAuthorityMapping(ctx sdk.Context, auctionID string, name string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Set(GetAuctionToAuthorityIndexKey(auctionID), []byte(name))
|
||||
}
|
||||
|
||||
func (k Keeper) createAuthority(ctx sdk.Context, name string, owner string, isRoot bool) error {
|
||||
moduleParams := k.GetParams(ctx)
|
||||
|
||||
if k.HasNameAuthority(ctx, name) {
|
||||
authority := k.GetNameAuthority(ctx, name)
|
||||
if authority.Status != types.AuthorityExpired {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Name already reserved.")
|
||||
}
|
||||
}
|
||||
|
||||
ownerAddress, err := sdk.AccAddressFromBech32(owner)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid owner address.")
|
||||
}
|
||||
ownerAccount := k.accountKeeper.GetAccount(ctx, ownerAddress)
|
||||
if ownerAccount == nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnknownAddress, "Account not found.")
|
||||
}
|
||||
|
||||
authority := types.NameAuthority{
|
||||
OwnerPublicKey: getAuthorityPubKey(ownerAccount.GetPubKey()),
|
||||
OwnerAddress: owner,
|
||||
Height: uint64(ctx.BlockHeight()),
|
||||
Status: types.AuthorityActive,
|
||||
AuctionId: "",
|
||||
BondId: "",
|
||||
ExpiryTime: ctx.BlockTime().Add(moduleParams.AuthorityGracePeriod),
|
||||
}
|
||||
|
||||
if isRoot && moduleParams.AuthorityAuctionEnabled {
|
||||
// If auctions are enabled, clear out owner fields. They will be set after a winner is picked.
|
||||
authority.OwnerAddress = ""
|
||||
authority.OwnerPublicKey = ""
|
||||
// Reset bond ID if required.
|
||||
if authority.BondId != "" || len(authority.BondId) != 0 {
|
||||
k.RemoveBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
authority.BondId = ""
|
||||
}
|
||||
|
||||
params := auctiontypes.Params{
|
||||
CommitsDuration: moduleParams.AuthorityAuctionCommitsDuration,
|
||||
RevealsDuration: moduleParams.AuthorityAuctionRevealsDuration,
|
||||
CommitFee: moduleParams.AuthorityAuctionCommitFee,
|
||||
RevealFee: moduleParams.AuthorityAuctionRevealFee,
|
||||
MinimumBid: moduleParams.AuthorityAuctionMinimumBid,
|
||||
}
|
||||
|
||||
// Create an auction.
|
||||
msg := auctiontypes.NewMsgCreateAuction(params, ownerAddress)
|
||||
|
||||
auction, sdkErr := k.auctionKeeper.CreateAuction(ctx, msg)
|
||||
if sdkErr != nil {
|
||||
return sdkErr
|
||||
}
|
||||
|
||||
// Create auction ID -> authority name index.
|
||||
k.AddAuctionToAuthorityMapping(ctx, auction.Id, name)
|
||||
|
||||
authority.Status = types.AuthorityUnderAuction
|
||||
authority.AuctionId = auction.Id
|
||||
authority.ExpiryTime = auction.RevealsEndTime.Add(moduleParams.AuthorityGracePeriod)
|
||||
}
|
||||
|
||||
k.SetNameAuthority(ctx, name, &authority)
|
||||
k.InsertAuthorityExpiryQueue(ctx, name, authority.ExpiryTime)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessReserveAuthority reserves a name authority.
|
||||
func (k Keeper) ProcessReserveAuthority(ctx sdk.Context, msg types.MsgReserveAuthority) error {
|
||||
crn := fmt.Sprintf("crn://%s", msg.GetName())
|
||||
parsedCrn, err := url.Parse(crn)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid name")
|
||||
}
|
||||
name := parsedCrn.Host
|
||||
if fmt.Sprintf("crn://%s", name) != crn {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Invalid name")
|
||||
}
|
||||
if strings.Contains(name, ".") {
|
||||
return k.ProcessReserveSubAuthority(ctx, name, msg)
|
||||
}
|
||||
err = k.createAuthority(ctx, name, msg.GetSigner(), true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) ProcessSetAuthorityBond(ctx sdk.Context, msg types.MsgSetAuthorityBond) error {
|
||||
name := msg.GetName()
|
||||
signer := msg.GetSigner()
|
||||
if !k.HasNameAuthority(ctx, name) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Name authority not found.")
|
||||
}
|
||||
authority := k.GetNameAuthority(ctx, name)
|
||||
if authority.OwnerAddress != signer {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Access denied")
|
||||
}
|
||||
|
||||
if !k.bondKeeper.HasBond(ctx, msg.BondId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
//
|
||||
bond := k.bondKeeper.GetBond(ctx, msg.BondId)
|
||||
if bond.Owner != signer {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// No-op if bond hasn't changed.
|
||||
if authority.BondId == msg.BondId {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove old bond ID mapping, if any.
|
||||
if authority.BondId != "" {
|
||||
k.RemoveBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
}
|
||||
|
||||
// Update bond ID for authority.
|
||||
authority.BondId = bond.Id
|
||||
k.SetNameAuthority(ctx, name, &authority)
|
||||
// Add new bond ID mapping.
|
||||
k.AddBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessDeleteName removes a CRN -> Record ID mapping.
|
||||
func (k Keeper) ProcessDeleteName(ctx sdk.Context, msg types.MsgDeleteNameAuthority) error {
|
||||
signerAddress, err := sdk.AccAddressFromBech32(msg.Signer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = k.checkCRNAccess(ctx, signerAddress, msg.Crn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !k.HasNameRecord(ctx, msg.Crn) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Name not found.")
|
||||
}
|
||||
|
||||
// Set CID to empty string.
|
||||
k.SetNameRecord(ctx, msg.Crn, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k Keeper) GetAuthorityExpiryQueue(ctx sdk.Context) []*types.ExpiryQueueRecord {
|
||||
var authorities []*types.ExpiryQueueRecord
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixExpiryTimeToAuthoritiesIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
var record []string
|
||||
record, err := helpers.BytesArrToStringArr(itr.Value())
|
||||
if err != nil {
|
||||
return authorities
|
||||
}
|
||||
authorities = append(authorities, &types.ExpiryQueueRecord{
|
||||
Id: string(itr.Key()[len(PrefixExpiryTimeToAuthoritiesIndex):]),
|
||||
Value: record,
|
||||
})
|
||||
}
|
||||
|
||||
return authorities
|
||||
}
|
||||
|
||||
// ResolveCRN resolves a CRN to a record.
|
||||
func (k Keeper) ResolveCRN(ctx sdk.Context, crn string) *types.Record {
|
||||
_, _, authority, err := k.getAuthority(ctx, crn)
|
||||
if err != nil || authority.Status != types.AuthorityActive {
|
||||
// If authority is not active (or any other error), resolution fails.
|
||||
return nil
|
||||
}
|
||||
|
||||
// Name should not resolve if it's stale.
|
||||
// i.e. authority was registered later than the name.
|
||||
record, nameRecord := ResolveCRN(ctx.KVStore(k.storeKey), crn, k, ctx)
|
||||
if authority.Height > nameRecord.Latest.Height {
|
||||
return nil
|
||||
}
|
||||
|
||||
return record
|
||||
}
|
||||
|
||||
// ResolveCRN resolves a CRN to a record.
|
||||
func ResolveCRN(store sdk.KVStore, crn string, k Keeper, c sdk.Context) (*types.Record, *types.NameRecord) {
|
||||
nameKey := GetNameRecordIndexKey(crn)
|
||||
|
||||
if store.Has(nameKey) {
|
||||
bz := store.Get(nameKey)
|
||||
var obj types.NameRecord
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
|
||||
recordExists := k.HasRecord(c, obj.Latest.Id)
|
||||
if !recordExists || obj.Latest.Id == "" {
|
||||
return nil, &obj
|
||||
}
|
||||
|
||||
record := k.GetRecord(c, obj.Latest.Id)
|
||||
return &record, &obj
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getAuthorityExpiryQueueTimeKey(timestamp time.Time) []byte {
|
||||
timeBytes := sdk.FormatTimeBytes(timestamp)
|
||||
return append(PrefixExpiryTimeToAuthoritiesIndex, timeBytes...)
|
||||
}
|
||||
|
||||
func (k Keeper) InsertAuthorityExpiryQueue(ctx sdk.Context, name string, expiryTime time.Time) {
|
||||
timeSlice := k.GetAuthorityExpiryQueueTimeSlice(ctx, expiryTime)
|
||||
timeSlice = append(timeSlice, name)
|
||||
k.SetAuthorityExpiryQueueTimeSlice(ctx, expiryTime, timeSlice)
|
||||
}
|
||||
|
||||
func (k Keeper) GetAuthorityExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time) []string {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
bz := store.Get(getAuthorityExpiryQueueTimeKey(timestamp))
|
||||
if bz == nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
names, err := helpers.BytesArrToStringArr(bz)
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
return names
|
||||
}
|
||||
|
||||
func (k Keeper) SetAuthorityExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time, names []string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz, _ := helpers.StrArrToBytesArr(names)
|
||||
store.Set(getAuthorityExpiryQueueTimeKey(timestamp), bz)
|
||||
}
|
||||
|
||||
// ProcessAuthorityExpiryQueue tries to renew expiring authorities (by collecting rent) else marks them as expired.
|
||||
func (k Keeper) ProcessAuthorityExpiryQueue(ctx sdk.Context) {
|
||||
names := k.GetAllExpiredAuthorities(ctx, ctx.BlockHeader().Time)
|
||||
for _, name := range names {
|
||||
authority := k.GetNameAuthority(ctx, name)
|
||||
|
||||
// If authority doesn't have an associated bond or if bond no longer exists, mark it expired.
|
||||
if authority.BondId == "" || !k.bondKeeper.HasBond(ctx, authority.BondId) {
|
||||
authority.Status = types.AuthorityExpired
|
||||
k.SetNameAuthority(ctx, name, &authority)
|
||||
k.DeleteAuthorityExpiryQueue(ctx, name, authority)
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Marking authority expired as no bond present: %s", name))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Try to renew the authority by taking rent.
|
||||
k.TryTakeAuthorityRent(ctx, name, authority)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteAuthorityExpiryQueueTimeSlice deletes a specific authority expiry queue timeslice.
|
||||
func (k Keeper) DeleteAuthorityExpiryQueueTimeSlice(ctx sdk.Context, timestamp time.Time) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(getAuthorityExpiryQueueTimeKey(timestamp))
|
||||
}
|
||||
|
||||
// DeleteAuthorityExpiryQueue deletes an authority name from the authority expiry queue.
|
||||
func (k Keeper) DeleteAuthorityExpiryQueue(ctx sdk.Context, name string, authority types.NameAuthority) {
|
||||
timeSlice := k.GetAuthorityExpiryQueueTimeSlice(ctx, authority.ExpiryTime)
|
||||
newTimeSlice := []string{}
|
||||
|
||||
for _, existingName := range timeSlice {
|
||||
if !bytes.Equal([]byte(existingName), []byte(name)) {
|
||||
newTimeSlice = append(newTimeSlice, existingName)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newTimeSlice) == 0 {
|
||||
k.DeleteAuthorityExpiryQueueTimeSlice(ctx, authority.ExpiryTime)
|
||||
} else {
|
||||
k.SetAuthorityExpiryQueueTimeSlice(ctx, authority.ExpiryTime, newTimeSlice)
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllExpiredAuthorities returns a concatenated list of all the timeslices before currTime.
|
||||
func (k Keeper) GetAllExpiredAuthorities(ctx sdk.Context, currTime time.Time) (expiredAuthorityNames []string) {
|
||||
// Gets an iterator for all timeslices from time 0 until the current block header time.
|
||||
itr := k.AuthorityExpiryQueueIterator(ctx, ctx.BlockHeader().Time)
|
||||
defer itr.Close()
|
||||
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
timeslice := []string{}
|
||||
timeslice, err := helpers.BytesArrToStringArr(itr.Value())
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
expiredAuthorityNames = append(expiredAuthorityNames, timeslice...)
|
||||
}
|
||||
|
||||
return expiredAuthorityNames
|
||||
}
|
||||
|
||||
// AuthorityExpiryQueueIterator returns all the authority expiry queue timeslices from time 0 until endTime.
|
||||
func (k Keeper) AuthorityExpiryQueueIterator(ctx sdk.Context, endTime time.Time) sdk.Iterator {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
rangeEndBytes := sdk.InclusiveEndBytes(getAuthorityExpiryQueueTimeKey(endTime))
|
||||
return store.Iterator(PrefixExpiryTimeToAuthoritiesIndex, rangeEndBytes)
|
||||
}
|
||||
|
||||
// TryTakeAuthorityRent tries to take rent from the authority bond.
|
||||
func (k Keeper) TryTakeAuthorityRent(ctx sdk.Context, name string, authority types.NameAuthority) {
|
||||
ctx.Logger().Info(fmt.Sprintf("Trying to take rent for authority: %s", name))
|
||||
|
||||
params := k.GetParams(ctx)
|
||||
rent := params.AuthorityRent
|
||||
sdkErr := k.bondKeeper.TransferCoinsToModuleAccount(ctx, authority.BondId, types.AuthorityRentModuleAccountName, sdk.NewCoins(rent))
|
||||
|
||||
if sdkErr != nil {
|
||||
// Insufficient funds, mark authority as expired.
|
||||
authority.Status = types.AuthorityExpired
|
||||
k.SetNameAuthority(ctx, name, &authority)
|
||||
k.DeleteAuthorityExpiryQueue(ctx, name, authority)
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Insufficient funds in owner account to pay authority rent, marking as expired: %s", name))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Delete old expiry queue entry, create new one.
|
||||
k.DeleteAuthorityExpiryQueue(ctx, name, authority)
|
||||
authority.ExpiryTime = ctx.BlockTime().Add(params.AuthorityRentDuration)
|
||||
k.InsertAuthorityExpiryQueue(ctx, name, authority.ExpiryTime)
|
||||
|
||||
// Save authority.
|
||||
authority.Status = types.AuthorityActive
|
||||
k.SetNameAuthority(ctx, name, &authority)
|
||||
k.AddBondToAuthorityIndexEntry(ctx, authority.BondId, name)
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Authority rent paid successfully: %s", name))
|
||||
}
|
||||
|
||||
// ListNameAuthorityRecords - get all name authority records.
|
||||
func (k Keeper) ListNameAuthorityRecords(ctx sdk.Context) map[string]types.NameAuthority {
|
||||
nameAuthorityRecords := make(map[string]types.NameAuthority)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
itr := sdk.KVStorePrefixIterator(store, PrefixNameAuthorityRecordIndex)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
bz := store.Get(itr.Key())
|
||||
if bz != nil {
|
||||
var record types.NameAuthority
|
||||
k.cdc.MustUnmarshal(bz, &record)
|
||||
nameAuthorityRecords[string(itr.Key()[len(PrefixNameAuthorityRecordIndex):])] = record
|
||||
}
|
||||
}
|
||||
|
||||
return nameAuthorityRecords
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// GetParams - Get all parameters as types.Params.
|
||||
func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
|
||||
k.paramSubspace.GetParamSet(ctx, ¶ms)
|
||||
return
|
||||
}
|
||||
|
||||
// SetParams - set the params.
|
||||
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
|
||||
k.paramSubspace.SetParamSet(ctx, ¶ms)
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
auctionkeeper "github.com/tharsis/ethermint/x/auction/keeper"
|
||||
auctiontypes "github.com/tharsis/ethermint/x/auction/types"
|
||||
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// RecordKeeper exposes the bare minimal read-only API for other modules.
|
||||
type RecordKeeper struct {
|
||||
auctionKeeper auctionkeeper.Keeper
|
||||
storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context
|
||||
cdc codec.BinaryCodec // The wire codec for binary encoding/decoding.
|
||||
}
|
||||
|
||||
func (k RecordKeeper) UsesAuction(ctx sdk.Context, auctionID string) bool {
|
||||
return k.GetAuctionToAuthorityMapping(ctx, auctionID) != ""
|
||||
}
|
||||
|
||||
func (k RecordKeeper) OnAuction(ctx sdk.Context, auctionId string) {
|
||||
updateBlockChangeSetForAuction(ctx, k, auctionId)
|
||||
}
|
||||
|
||||
func (k RecordKeeper) OnAuctionBid(ctx sdk.Context, auctionID string, bidderAddress string) {
|
||||
updateBlockChangeSetForAuctionBid(ctx, k, auctionID, bidderAddress)
|
||||
}
|
||||
|
||||
func (k RecordKeeper) OnAuctionWinnerSelected(ctx sdk.Context, auctionID string) {
|
||||
// Update authority status based on auction status/winner.
|
||||
name := k.GetAuctionToAuthorityMapping(ctx, auctionID)
|
||||
if name == "" {
|
||||
// We don't know about this auction, ignore.
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring auction notification, name mapping not found: %s", auctionID))
|
||||
return
|
||||
}
|
||||
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
if !HasNameAuthority(store, name) {
|
||||
// We don't know about this authority, ignore.
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring auction notification, authority not found: %s", auctionID))
|
||||
return
|
||||
}
|
||||
|
||||
authority := GetNameAuthority(store, k.cdc, name)
|
||||
auctionObj := k.auctionKeeper.GetAuction(ctx, auctionID)
|
||||
|
||||
if auctionObj.Status == auctiontypes.AuctionStatusCompleted {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
if auctionObj.WinnerAddress != "" {
|
||||
// Mark authority owner and change status to active.
|
||||
authority.OwnerAddress = auctionObj.WinnerAddress
|
||||
authority.Status = types.AuthorityActive
|
||||
|
||||
// Reset bond ID if required, as owner has changed.
|
||||
if authority.BondId != "" {
|
||||
RemoveBondToAuthorityIndexEntry(store, authority.BondId, name)
|
||||
authority.BondId = ""
|
||||
}
|
||||
|
||||
// Update height for updated/changed authority (owner).
|
||||
// Can be used to check if names are older than the authority itself (stale names).
|
||||
authority.Height = uint64(ctx.BlockHeight())
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("Winner selected, marking authority as active: %s", name))
|
||||
} else {
|
||||
// Mark as expired.
|
||||
authority.Status = types.AuthorityExpired
|
||||
|
||||
ctx.Logger().Info(fmt.Sprintf("No winner, marking authority as expired: %s", name))
|
||||
}
|
||||
|
||||
authority.AuctionId = ""
|
||||
SetNameAuthority(ctx, store, k.cdc, name, &authority)
|
||||
|
||||
// Forget about this auction now, we no longer need it.
|
||||
removeAuctionToAuthorityMapping(store, auctionID)
|
||||
} else {
|
||||
ctx.Logger().Info(fmt.Sprintf("Ignoring auction notification, status: %s", auctionObj.Status))
|
||||
}
|
||||
}
|
||||
|
||||
// Record keeper implements the bond usage keeper interface.
|
||||
var _ bondtypes.BondUsageKeeper = (*RecordKeeper)(nil)
|
||||
var _ auctiontypes.AuctionUsageKeeper = (*RecordKeeper)(nil)
|
||||
|
||||
// ModuleName returns the module name.
|
||||
func (k RecordKeeper) ModuleName() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
func (k RecordKeeper) GetAuctionToAuthorityMapping(ctx sdk.Context, auctionID string) string {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
|
||||
auctionToAuthorityIndexKey := GetAuctionToAuthorityIndexKey(auctionID)
|
||||
if store.Has(auctionToAuthorityIndexKey) {
|
||||
bz := store.Get(auctionToAuthorityIndexKey)
|
||||
return string(bz)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UsesBond returns true if the bond has associated records.
|
||||
func (k RecordKeeper) UsesBond(ctx sdk.Context, bondId string) bool {
|
||||
bondIDPrefix := append(PrefixBondIDToRecordsIndex, []byte(bondId)...)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, bondIDPrefix)
|
||||
defer itr.Close()
|
||||
return itr.Valid()
|
||||
}
|
||||
|
||||
// RemoveBondToRecordIndexEntry removes the Bond ID -> [Record] index entry.
|
||||
func (k Keeper) RemoveBondToRecordIndexEntry(ctx sdk.Context, bondID string, id string) {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
store.Delete(getBondIDToRecordsIndexKey(bondID, id))
|
||||
}
|
||||
|
||||
// NewRecordKeeper creates new instances of the nameservice RecordKeeper
|
||||
func NewRecordKeeper(auctionKeeper auctionkeeper.Keeper, storeKey sdk.StoreKey, cdc codec.BinaryCodec) RecordKeeper {
|
||||
return RecordKeeper{
|
||||
auctionKeeper: auctionKeeper,
|
||||
storeKey: storeKey,
|
||||
cdc: cdc,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryRecordsByBond - get all records for the given bond.
|
||||
func (k RecordKeeper) QueryRecordsByBond(ctx sdk.Context, bondID string) []types.Record {
|
||||
var records []types.Record
|
||||
|
||||
bondIDPrefix := append(PrefixBondIDToRecordsIndex, []byte(bondID)...)
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
itr := sdk.KVStorePrefixIterator(store, bondIDPrefix)
|
||||
defer itr.Close()
|
||||
for ; itr.Valid(); itr.Next() {
|
||||
cid := itr.Key()[len(bondIDPrefix):]
|
||||
bz := store.Get(append(PrefixCIDToRecordIndex, cid...))
|
||||
if bz != nil {
|
||||
var obj types.Record
|
||||
k.cdc.MustUnmarshal(bz, &obj)
|
||||
records = append(records, recordObjToRecord(store, k.cdc, obj))
|
||||
}
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
// ProcessRenewRecord renews a record.
|
||||
func (k Keeper) ProcessRenewRecord(ctx sdk.Context, msg types.MsgRenewRecord) error {
|
||||
if !k.HasRecord(ctx, msg.RecordId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Record not found.")
|
||||
}
|
||||
|
||||
// Check if renewal is required (i.e. expired record marked as deleted).
|
||||
record := k.GetRecord(ctx, msg.RecordId)
|
||||
expiryTime, err := time.Parse(time.RFC3339, record.ExpiryTime)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !record.Deleted || expiryTime.After(ctx.BlockTime()) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Renewal not required.")
|
||||
}
|
||||
|
||||
recordType := record.ToRecordType()
|
||||
err = k.processRecord(ctx, &recordType, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessAssociateBond associates a record with a bond.
|
||||
func (k Keeper) ProcessAssociateBond(ctx sdk.Context, msg types.MsgAssociateBond) error {
|
||||
|
||||
if !k.HasRecord(ctx, msg.RecordId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Record not found.")
|
||||
}
|
||||
|
||||
if !k.bondKeeper.HasBond(ctx, msg.BondId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
|
||||
// Check if already associated with a bond.
|
||||
record := k.GetRecord(ctx, msg.RecordId)
|
||||
if record.BondId != "" || len(record.BondId) != 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond already exists.")
|
||||
}
|
||||
|
||||
// Only the bond owner can associate a record with the bond.
|
||||
bond := k.bondKeeper.GetBond(ctx, msg.BondId)
|
||||
if msg.Signer != bond.Owner {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
record.BondId = msg.BondId
|
||||
k.PutRecord(ctx, record)
|
||||
k.AddBondToRecordIndexEntry(ctx, msg.BondId, msg.RecordId)
|
||||
|
||||
// Required so that renewal is triggered (with new bond ID) for expired records.
|
||||
if record.Deleted {
|
||||
k.InsertRecordExpiryQueue(ctx, record)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessDissociateBond dissociates a record from its bond.
|
||||
func (k Keeper) ProcessDissociateBond(ctx sdk.Context, msg types.MsgDissociateBond) error {
|
||||
if !k.HasRecord(ctx, msg.RecordId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Record not found.")
|
||||
}
|
||||
|
||||
// Check if associated with a bond.
|
||||
record := k.GetRecord(ctx, msg.RecordId)
|
||||
bondID := record.BondId
|
||||
if bondID == "" || len(bondID) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond not found.")
|
||||
}
|
||||
|
||||
// Only the bond owner can dissociate a record from the bond.
|
||||
bond := k.bondKeeper.GetBond(ctx, bondID)
|
||||
if msg.Signer != bond.Owner {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// Clear bond ID.
|
||||
record.BondId = ""
|
||||
k.PutRecord(ctx, record)
|
||||
k.RemoveBondToRecordIndexEntry(ctx, bondID, record.Id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessDissociateRecords dissociates all records associated with a given bond.
|
||||
func (k Keeper) ProcessDissociateRecords(ctx sdk.Context, msg types.MsgDissociateRecords) error {
|
||||
if !k.bondKeeper.HasBond(ctx, msg.BondId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Bond not found.")
|
||||
}
|
||||
|
||||
// Only the bond owner can dissociate all records from the bond.
|
||||
bond := k.bondKeeper.GetBond(ctx, msg.BondId)
|
||||
if msg.Signer != bond.Owner {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond owner mismatch.")
|
||||
}
|
||||
|
||||
// Dissociate all records from the bond.
|
||||
records := k.recordKeeper.QueryRecordsByBond(ctx, msg.BondId)
|
||||
for _, record := range records {
|
||||
// Clear bond ID.
|
||||
record.BondId = ""
|
||||
k.PutRecord(ctx, record)
|
||||
k.RemoveBondToRecordIndexEntry(ctx, msg.BondId, record.Id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProcessReAssociateRecords switches records from and old to new bond.
|
||||
func (k Keeper) ProcessReAssociateRecords(ctx sdk.Context, msg types.MsgReAssociateRecords) error {
|
||||
if !k.bondKeeper.HasBond(ctx, msg.OldBondId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Old bond not found.")
|
||||
}
|
||||
|
||||
if !k.bondKeeper.HasBond(ctx, msg.NewBondId) {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "New bond not found.")
|
||||
}
|
||||
|
||||
// Only the bond owner can re-associate all records.
|
||||
oldBond := k.bondKeeper.GetBond(ctx, msg.OldBondId)
|
||||
if msg.Signer != oldBond.Owner {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Old bond owner mismatch.")
|
||||
}
|
||||
|
||||
newBond := k.bondKeeper.GetBond(ctx, msg.NewBondId)
|
||||
if msg.Signer != newBond.Owner {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "New bond owner mismatch.")
|
||||
}
|
||||
|
||||
// Re-associate all records.
|
||||
records := k.recordKeeper.QueryRecordsByBond(ctx, msg.OldBondId)
|
||||
for _, record := range records {
|
||||
// Switch bond ID.
|
||||
record.BondId = msg.NewBondId
|
||||
k.PutRecord(ctx, record)
|
||||
|
||||
k.RemoveBondToRecordIndexEntry(ctx, msg.OldBondId, record.Id)
|
||||
k.AddBondToRecordIndexEntry(ctx, msg.NewBondId, record.Id)
|
||||
|
||||
// Required so that renewal is triggered (with new bond ID) for expired records.
|
||||
if record.Deleted {
|
||||
k.InsertRecordExpiryQueue(ctx, record)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/helpers"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
func GetBlockChangeSetIndexKey(height int64) []byte {
|
||||
return append(PrefixBlockChangesetIndex, helpers.Int64ToBytes(height)...)
|
||||
}
|
||||
|
||||
func getOrCreateBlockChangeset(store sdk.KVStore, codec codec.BinaryCodec, height int64) *types.BlockChangeSet {
|
||||
bz := store.Get(GetBlockChangeSetIndexKey(height))
|
||||
|
||||
if bz != nil {
|
||||
var changeSet types.BlockChangeSet
|
||||
err := codec.Unmarshal(bz, &changeSet)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &changeSet
|
||||
}
|
||||
|
||||
return &types.BlockChangeSet{
|
||||
Height: height,
|
||||
Records: []string{},
|
||||
Names: []string{},
|
||||
Auctions: []string{},
|
||||
AuctionBids: []*types.AuctionBidInfo{},
|
||||
}
|
||||
}
|
||||
|
||||
func updateBlockChangeSetForAuction(ctx sdk.Context, k RecordKeeper, id string) {
|
||||
changeSet := getOrCreateBlockChangeset(ctx.KVStore(k.storeKey), k.cdc, ctx.BlockHeight())
|
||||
|
||||
found := false
|
||||
for _, elem := range changeSet.Auctions {
|
||||
if id == elem {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
changeSet.Auctions = append(changeSet.Auctions, id)
|
||||
saveBlockChangeSet(ctx.KVStore(k.storeKey), k.cdc, changeSet)
|
||||
}
|
||||
}
|
||||
|
||||
func saveBlockChangeSet(store sdk.KVStore, codec codec.BinaryCodec, changeset *types.BlockChangeSet) {
|
||||
bz := codec.MustMarshal(changeset)
|
||||
store.Set(GetBlockChangeSetIndexKey(changeset.Height), bz)
|
||||
}
|
||||
|
||||
func (k Keeper) saveBlockChangeSet(ctx sdk.Context, changeSet *types.BlockChangeSet) {
|
||||
saveBlockChangeSet(ctx.KVStore(k.storeKey), k.cdc, changeSet)
|
||||
}
|
||||
|
||||
func (k Keeper) updateBlockChangeSetForRecord(ctx sdk.Context, id string) {
|
||||
changeSet := k.getOrCreateBlockChangeSet(ctx, ctx.BlockHeight())
|
||||
changeSet.Records = append(changeSet.Records, id)
|
||||
k.saveBlockChangeSet(ctx, changeSet)
|
||||
}
|
||||
|
||||
func (k Keeper) getOrCreateBlockChangeSet(ctx sdk.Context, height int64) *types.BlockChangeSet {
|
||||
store := ctx.KVStore(k.storeKey)
|
||||
bz := store.Get(GetBlockChangeSetIndexKey(height))
|
||||
|
||||
if bz != nil {
|
||||
var changeSet types.BlockChangeSet
|
||||
err := k.cdc.Unmarshal(bz, &changeSet)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &changeSet
|
||||
}
|
||||
|
||||
return &types.BlockChangeSet{
|
||||
Height: height,
|
||||
Records: []string{},
|
||||
Names: []string{},
|
||||
Auctions: []string{},
|
||||
AuctionBids: []*types.AuctionBidInfo{},
|
||||
}
|
||||
}
|
||||
|
||||
func updateBlockChangeSetForAuctionBid(ctx sdk.Context, k RecordKeeper, id, bidderAddress string) {
|
||||
changeSet := getOrCreateBlockChangeset(ctx.KVStore(k.storeKey), k.cdc, ctx.BlockHeight())
|
||||
changeSet.AuctionBids = append(changeSet.AuctionBids, &types.AuctionBidInfo{AuctionId: id, BidderAddress: bidderAddress})
|
||||
saveBlockChangeSet(ctx.KVStore(k.storeKey), k.cdc, changeSet)
|
||||
}
|
||||
|
||||
func updateBlockChangeSetForNameAuthority(ctx sdk.Context, codec codec.BinaryCodec, store sdk.KVStore, name string) {
|
||||
changeSet := getOrCreateBlockChangeset(store, codec, ctx.BlockHeight())
|
||||
changeSet.Authorities = append(changeSet.Authorities, name)
|
||||
saveBlockChangeSet(store, codec, changeSet)
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package nameservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
"github.com/spf13/cobra"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tharsis/ethermint/x/nameservice/client/cli"
|
||||
"github.com/tharsis/ethermint/x/nameservice/keeper"
|
||||
"github.com/tharsis/ethermint/x/nameservice/types"
|
||||
)
|
||||
|
||||
// type check to ensure the interface is properly implemented
|
||||
var (
|
||||
_ module.AppModule = AppModule{}
|
||||
_ module.AppModuleBasic = AppModuleBasic{}
|
||||
)
|
||||
|
||||
// AppModuleBasic _ app module Basics object
|
||||
type AppModuleBasic struct{}
|
||||
|
||||
func (a AppModuleBasic) Name() string {
|
||||
return types.ModuleName
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) RegisterLegacyAminoCodec(amino *codec.LegacyAmino) {
|
||||
types.RegisterLegacyAminoCodec(amino)
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) {
|
||||
types.RegisterInterfaces(registry)
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
|
||||
return cdc.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, message json.RawMessage) error {
|
||||
var data types.GenesisState
|
||||
if err := cdc.UnmarshalJSON(message, &data); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
|
||||
}
|
||||
|
||||
return types.ValidateGenesis(data)
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) RegisterRESTRoutes(context client.Context, router *mux.Router) {
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
|
||||
err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) GetTxCmd() *cobra.Command {
|
||||
return cli.NewTxCmd()
|
||||
}
|
||||
|
||||
func (a AppModuleBasic) GetQueryCmd() *cobra.Command {
|
||||
return cli.GetQueryCmd()
|
||||
}
|
||||
|
||||
type AppModule struct {
|
||||
AppModuleBasic
|
||||
keeper keeper.Keeper
|
||||
}
|
||||
|
||||
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, message json.RawMessage) []abci.ValidatorUpdate {
|
||||
var genesisState types.GenesisState
|
||||
|
||||
cdc.MustUnmarshalJSON(message, &genesisState)
|
||||
|
||||
return InitGenesis(ctx, am.keeper, genesisState)
|
||||
}
|
||||
|
||||
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
|
||||
gs := ExportGenesis(ctx, am.keeper)
|
||||
return cdc.MustMarshalJSON(&gs)
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterInvariants(registry sdk.InvariantRegistry) {
|
||||
keeper.RegisterInvariants(registry, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) Route() sdk.Route {
|
||||
return sdk.Route{}
|
||||
}
|
||||
|
||||
func (am AppModule) QuerierRoute() string {
|
||||
return types.QuerierRoute
|
||||
}
|
||||
|
||||
func (am AppModule) LegacyQuerierHandler(amino *codec.LegacyAmino) sdk.Querier {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||
|
||||
querier := keeper.Querier{Keeper: am.keeper}
|
||||
types.RegisterQueryServer(cfg.QueryServer(), querier)
|
||||
|
||||
msgServer := keeper.NewMsgServerImpl(am.keeper)
|
||||
types.RegisterMsgServer(cfg.MsgServer(), msgServer)
|
||||
}
|
||||
|
||||
func (am AppModule) ConsensusVersion() uint64 {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
|
||||
BeginBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
|
||||
return EndBlocker(ctx, am.keeper)
|
||||
}
|
||||
|
||||
// NewAppModule creates a new AppModule Object
|
||||
func NewAppModule(k keeper.Keeper) AppModule {
|
||||
return AppModule{
|
||||
AppModuleBasic: AppModuleBasic{},
|
||||
keeper: k,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||
)
|
||||
|
||||
// RegisterLegacyAminoCodec registers the necessary x/bond interfaces and concrete types
|
||||
// on the provided LegacyAmino codec. These types are used for Amino JSON serialization.
|
||||
func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) {
|
||||
cdc.RegisterConcrete(&MsgSetName{}, "nameservice/SetName", nil)
|
||||
cdc.RegisterConcrete(&MsgReserveAuthority{}, "nameservice/ReserveAuthority", nil)
|
||||
cdc.RegisterConcrete(&MsgDeleteNameAuthority{}, "nameservice/DeleteAuthority", nil)
|
||||
cdc.RegisterConcrete(&MsgSetAuthorityBond{}, "nameservice/SetAuthorityBond", nil)
|
||||
|
||||
cdc.RegisterConcrete(&MsgSetRecord{}, "nameservice/SetRecord", nil)
|
||||
cdc.RegisterConcrete(&MsgRenewRecord{}, "nameservice/RenewRecord", nil)
|
||||
cdc.RegisterConcrete(&MsgAssociateBond{}, "nameservice/AssociateBond", nil)
|
||||
cdc.RegisterConcrete(&MsgDissociateBond{}, "nameservice/DissociateBond", nil)
|
||||
cdc.RegisterConcrete(&MsgDissociateRecords{}, "nameservice/DissociateRecords", nil)
|
||||
cdc.RegisterConcrete(&MsgReAssociateRecords{}, "nameservice/ReassociateRecords", nil)
|
||||
}
|
||||
|
||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||
registry.RegisterImplementations((*sdk.Msg)(nil),
|
||||
&MsgSetName{},
|
||||
&MsgReserveAuthority{},
|
||||
&MsgDeleteNameAuthority{},
|
||||
&MsgSetAuthorityBond{},
|
||||
|
||||
&MsgSetRecord{},
|
||||
&MsgRenewRecord{},
|
||||
&MsgAssociateBond{},
|
||||
&MsgDissociateBond{},
|
||||
&MsgDissociateRecords{},
|
||||
&MsgReAssociateRecords{},
|
||||
)
|
||||
msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc)
|
||||
}
|
||||
|
||||
var (
|
||||
amino = codec.NewLegacyAmino()
|
||||
ModuleCdc = codec.NewAminoCodec(amino)
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterLegacyAminoCodec(amino)
|
||||
cryptocodec.RegisterCrypto(amino)
|
||||
amino.Seal()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
EventTypeSetRecord = "set"
|
||||
EventTypeDeleteName = "delete-name"
|
||||
EventTypeReserveNameAuthority = "reserve-authority"
|
||||
EventTypeAuthorityBond = "authority-bond"
|
||||
EventTypeRenewRecord = "renew-record"
|
||||
EventTypeAssociateBond = "associate-bond"
|
||||
EventTypeDissociateBond = "dissociate-bond"
|
||||
EventTypeDissociateRecords = "dissociate-record"
|
||||
EventTypeReAssociateRecords = "re-associate-records"
|
||||
|
||||
AttributeKeySigner = "signer"
|
||||
AttributeKeyOwner = "owner"
|
||||
AttributeKeyBondId = "bond-id"
|
||||
AttributeKeyPayload = "payload"
|
||||
AttributeKeyOldBondId = "old-bond-id"
|
||||
AttributeKeyNewBondId = "new-bond-id"
|
||||
AttributeKeyCID = "cid"
|
||||
AttributeKeyName = "name"
|
||||
AttributeKeyCRN = "crn"
|
||||
AttributeKeyRecordId = "record-id"
|
||||
AttributeValueCategory = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,27 @@
|
||||
package types
|
||||
|
||||
func NewGenesisState(params Params, records []Record, authorities []AuthorityEntry, names []NameEntry) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
Records: records,
|
||||
Authorities: authorities,
|
||||
Names: names,
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultGenesisState sets default evm genesis state with empty accounts and default params and
|
||||
// chain config values.
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{
|
||||
Params: DefaultParams(),
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateGenesis(data GenesisState) error {
|
||||
err := data.Params.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
+522
@@ -0,0 +1,522 @@
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: vulcanize/nameservice/v1beta1/genesis.proto
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
_ "github.com/gogo/protobuf/gogoproto"
|
||||
proto "github.com/gogo/protobuf/proto"
|
||||
io "io"
|
||||
math "math"
|
||||
math_bits "math/bits"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
// GenesisState defines the nameservice module's genesis state.
|
||||
type GenesisState struct {
|
||||
// params defines all the params of nameservice module.
|
||||
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
|
||||
// records
|
||||
Records []Record `protobuf:"bytes,2,rep,name=records,proto3" json:"records" json:"records" yaml:"records"`
|
||||
// authorities
|
||||
Authorities []AuthorityEntry `protobuf:"bytes,3,rep,name=authorities,proto3" json:"authorities" json:"authorities" yaml:"authorities"`
|
||||
// names
|
||||
Names []NameEntry `protobuf:"bytes,4,rep,name=names,proto3" json:"names" json:"names" yaml:"names"`
|
||||
}
|
||||
|
||||
func (m *GenesisState) Reset() { *m = GenesisState{} }
|
||||
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
|
||||
func (*GenesisState) ProtoMessage() {}
|
||||
func (*GenesisState) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_fe7037a2b22e67ef, []int{0}
|
||||
}
|
||||
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
|
||||
return m.Unmarshal(b)
|
||||
}
|
||||
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
if deterministic {
|
||||
return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic)
|
||||
} else {
|
||||
b = b[:cap(b)]
|
||||
n, err := m.MarshalToSizedBuffer(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b[:n], nil
|
||||
}
|
||||
}
|
||||
func (m *GenesisState) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GenesisState.Merge(m, src)
|
||||
}
|
||||
func (m *GenesisState) XXX_Size() int {
|
||||
return m.Size()
|
||||
}
|
||||
func (m *GenesisState) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GenesisState.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
|
||||
|
||||
func (m *GenesisState) GetParams() Params {
|
||||
if m != nil {
|
||||
return m.Params
|
||||
}
|
||||
return Params{}
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetRecords() []Record {
|
||||
if m != nil {
|
||||
return m.Records
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetAuthorities() []AuthorityEntry {
|
||||
if m != nil {
|
||||
return m.Authorities
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) GetNames() []NameEntry {
|
||||
if m != nil {
|
||||
return m.Names
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*GenesisState)(nil), "vulcanize.nameservice.v1beta1.GenesisState")
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterFile("vulcanize/nameservice/v1beta1/genesis.proto", fileDescriptor_fe7037a2b22e67ef)
|
||||
}
|
||||
|
||||
var fileDescriptor_fe7037a2b22e67ef = []byte{
|
||||
// 347 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0xd2, 0xb1, 0x4a, 0xfb, 0x40,
|
||||
0x1c, 0x07, 0xf0, 0xe4, 0xdf, 0xfe, 0x2b, 0xa4, 0x4e, 0xc1, 0x21, 0x16, 0x9a, 0xd6, 0x42, 0xa1,
|
||||
0x20, 0xcd, 0x59, 0xdd, 0xdc, 0x8c, 0x88, 0xe0, 0x20, 0x12, 0x37, 0xb7, 0x6b, 0xfc, 0x99, 0x9c,
|
||||
0x34, 0xb9, 0x72, 0xf7, 0x6b, 0x31, 0x0e, 0x3e, 0x83, 0x4f, 0xe0, 0xf3, 0x74, 0xec, 0xe8, 0x54,
|
||||
0xa4, 0x7d, 0x03, 0x9f, 0x40, 0x7a, 0x97, 0x68, 0x5c, 0x5a, 0xb7, 0x5c, 0xf8, 0x7e, 0xbf, 0x9f,
|
||||
0x40, 0xce, 0x3a, 0x9c, 0x4e, 0x46, 0x21, 0x4d, 0xd9, 0x33, 0x90, 0x94, 0x26, 0x20, 0x41, 0x4c,
|
||||
0x59, 0x08, 0x64, 0x3a, 0x18, 0x02, 0xd2, 0x01, 0x89, 0x20, 0x05, 0xc9, 0xa4, 0x37, 0x16, 0x1c,
|
||||
0xb9, 0xdd, 0xfc, 0x0e, 0x7b, 0xa5, 0xb0, 0x97, 0x87, 0x1b, 0x7b, 0x11, 0x8f, 0xb8, 0x4a, 0x92,
|
||||
0xf5, 0x93, 0x2e, 0x35, 0xc8, 0x66, 0xa1, 0x3c, 0xa4, 0x0a, 0x9d, 0xb7, 0x8a, 0xb5, 0x7b, 0xa9,
|
||||
0xdd, 0x5b, 0xa4, 0x08, 0xf6, 0xb9, 0x55, 0x1b, 0x53, 0x41, 0x13, 0xe9, 0x98, 0x6d, 0xb3, 0x57,
|
||||
0x3f, 0xee, 0x7a, 0x1b, 0xbf, 0xc3, 0xbb, 0x51, 0x61, 0xbf, 0x3a, 0x5b, 0xb4, 0x8c, 0x20, 0xaf,
|
||||
0xda, 0x0f, 0xd6, 0x8e, 0x80, 0x90, 0x8b, 0x7b, 0xe9, 0xfc, 0x6b, 0x57, 0xfe, 0xb0, 0x12, 0xa8,
|
||||
0xb4, 0xdf, 0x5d, 0xaf, 0x7c, 0x2e, 0x5a, 0xcd, 0x47, 0xc9, 0xd3, 0xd3, 0x4e, 0xbe, 0xd1, 0x69,
|
||||
0x67, 0x34, 0x19, 0xfd, 0x1c, 0x83, 0x62, 0xdc, 0x7e, 0xb1, 0xea, 0x74, 0x82, 0x31, 0x17, 0x0c,
|
||||
0x19, 0x48, 0xa7, 0xa2, 0xac, 0xfe, 0x16, 0xeb, 0x2c, 0x6f, 0x64, 0x17, 0x29, 0x8a, 0xcc, 0xef,
|
||||
0xe7, 0x66, 0x57, 0x9b, 0xa5, 0xbd, 0xc2, 0x2d, 0xbf, 0x0a, 0xca, 0xa0, 0x4d, 0xad, 0xff, 0x4a,
|
||||
0x70, 0xaa, 0x4a, 0xee, 0x6d, 0x91, 0xaf, 0x69, 0x02, 0x1a, 0x3d, 0xc8, 0xd1, 0x7d, 0x8d, 0xaa,
|
||||
0x70, 0xc1, 0xe9, 0x43, 0xa0, 0x97, 0xfd, 0xab, 0xd9, 0xd2, 0x35, 0xe7, 0x4b, 0xd7, 0xfc, 0x58,
|
||||
0xba, 0xe6, 0xeb, 0xca, 0x35, 0xe6, 0x2b, 0xd7, 0x78, 0x5f, 0xb9, 0xc6, 0xdd, 0x51, 0xc4, 0x30,
|
||||
0x9e, 0x0c, 0xbd, 0x90, 0x27, 0x04, 0x63, 0x2a, 0x24, 0x93, 0x04, 0x30, 0x06, 0x91, 0xb0, 0x14,
|
||||
0xc9, 0xd3, 0xaf, 0x0b, 0x80, 0xd9, 0x18, 0xe4, 0xb0, 0xa6, 0xfe, 0xf9, 0xc9, 0x57, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xbe, 0x6b, 0x6e, 0x5b, 0x88, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
func (m *GenesisState) Marshal() (dAtA []byte, err error) {
|
||||
size := m.Size()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) {
|
||||
size := m.Size()
|
||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.Names) > 0 {
|
||||
for iNdEx := len(m.Names) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Names[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
}
|
||||
}
|
||||
if len(m.Authorities) > 0 {
|
||||
for iNdEx := len(m.Authorities) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Authorities[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
}
|
||||
if len(m.Records) > 0 {
|
||||
for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Records[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
}
|
||||
{
|
||||
size, err := m.Params.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintGenesis(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
|
||||
offset -= sovGenesis(v)
|
||||
base := offset
|
||||
for v >= 1<<7 {
|
||||
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||
v >>= 7
|
||||
offset++
|
||||
}
|
||||
dAtA[offset] = uint8(v)
|
||||
return base
|
||||
}
|
||||
func (m *GenesisState) Size() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = m.Params.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
if len(m.Records) > 0 {
|
||||
for _, e := range m.Records {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.Authorities) > 0 {
|
||||
for _, e := range m.Authorities {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
if len(m.Names) > 0 {
|
||||
for _, e := range m.Names {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovGenesis(uint64(l))
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func sovGenesis(x uint64) (n int) {
|
||||
return (math_bits.Len64(x|1) + 6) / 7
|
||||
}
|
||||
func sozGenesis(x uint64) (n int) {
|
||||
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}
|
||||
func (m *GenesisState) Unmarshal(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: GenesisState: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Records", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Records = append(m.Records, Record{})
|
||||
if err := m.Records[len(m.Records)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Authorities", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Authorities = append(m.Authorities, AuthorityEntry{})
|
||||
if err := m.Authorities[len(m.Authorities)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Names", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Names = append(m.Names, NameEntry{})
|
||||
if err := m.Names[len(m.Names)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipGenesis(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthGenesis
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func skipGenesis(dAtA []byte) (n int, err error) {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
depth := 0
|
||||
for iNdEx < l {
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= (uint64(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
wireType := int(wire & 0x7)
|
||||
switch wireType {
|
||||
case 0:
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
iNdEx++
|
||||
if dAtA[iNdEx-1] < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 1:
|
||||
iNdEx += 8
|
||||
case 2:
|
||||
var length int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return 0, ErrIntOverflowGenesis
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
length |= (int(b) & 0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if length < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
iNdEx += length
|
||||
case 3:
|
||||
depth++
|
||||
case 4:
|
||||
if depth == 0 {
|
||||
return 0, ErrUnexpectedEndOfGroupGenesis
|
||||
}
|
||||
depth--
|
||||
case 5:
|
||||
iNdEx += 4
|
||||
default:
|
||||
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||
}
|
||||
if iNdEx < 0 {
|
||||
return 0, ErrInvalidLengthGenesis
|
||||
}
|
||||
if depth == 0 {
|
||||
return iNdEx, nil
|
||||
}
|
||||
}
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
|
||||
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
|
||||
)
|
||||
@@ -0,0 +1,21 @@
|
||||
package types
|
||||
|
||||
const (
|
||||
// ModuleName is the name of the staking module
|
||||
ModuleName = "nameservice"
|
||||
|
||||
// RecordRentModuleAccountName is the name of the module account that keeps track of record rents paid.
|
||||
RecordRentModuleAccountName = "record_rent"
|
||||
|
||||
// AuthorityRentModuleAccountName is the name of the module account that keeps track of authority rents paid.
|
||||
AuthorityRentModuleAccountName = "authority_rent"
|
||||
|
||||
// StoreKey is the string store representation
|
||||
StoreKey = ModuleName
|
||||
|
||||
// QuerierRoute is the querier route for the staking module
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// RouterKey is the msg router key for the staking module
|
||||
RouterKey = ModuleName
|
||||
)
|
||||
@@ -0,0 +1,189 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgSetName{}
|
||||
_ sdk.Msg = &MsgReserveAuthority{}
|
||||
_ sdk.Msg = &MsgSetAuthorityBond{}
|
||||
_ sdk.Msg = &MsgDeleteNameAuthority{}
|
||||
)
|
||||
|
||||
// NewMsgSetName is the constructor function for MsgSetName.
|
||||
func NewMsgSetName(crn string, cid string, signer sdk.AccAddress) MsgSetName {
|
||||
return MsgSetName{
|
||||
Crn: crn,
|
||||
Cid: cid,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgSetName) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgSetName) Type() string { return "set-name" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgSetName) ValidateBasic() error {
|
||||
|
||||
if msg.Crn == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "CRN is required.")
|
||||
}
|
||||
|
||||
if msg.Cid == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "CID is required.")
|
||||
}
|
||||
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgSetName
|
||||
func (msg MsgSetName) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgSetName) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgReserveAuthority is the constructor function for MsgReserveName.
|
||||
func NewMsgReserveAuthority(name string, signer sdk.AccAddress, owner sdk.AccAddress) MsgReserveAuthority {
|
||||
return MsgReserveAuthority{
|
||||
Name: name,
|
||||
Owner: owner.String(),
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgReserveAuthority) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgReserveAuthority) Type() string { return "reserve-authority" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgReserveAuthority) ValidateBasic() error {
|
||||
|
||||
if len(msg.Name) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "name is required.")
|
||||
}
|
||||
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgSetName
|
||||
func (msg MsgReserveAuthority) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgReserveAuthority) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgSetAuthorityBond is the constructor function for MsgSetAuthorityBond.
|
||||
func NewMsgSetAuthorityBond(name string, bondId string, signer sdk.AccAddress) MsgSetAuthorityBond {
|
||||
return MsgSetAuthorityBond{
|
||||
Name: name,
|
||||
Signer: signer.String(),
|
||||
BondId: bondId,
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgSetAuthorityBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgSetAuthorityBond) Type() string { return "authority-bond" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgSetAuthorityBond) ValidateBasic() error {
|
||||
if len(msg.Name) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "name is required.")
|
||||
}
|
||||
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
if len(msg.BondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "bond id is required.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgSetName
|
||||
func (msg MsgSetAuthorityBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgSetAuthorityBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgDeleteNameAuthority is the constructor function for MsgDeleteNameAuthority.
|
||||
func NewMsgDeleteNameAuthority(crn string, signer sdk.AccAddress) MsgDeleteNameAuthority {
|
||||
return MsgDeleteNameAuthority{
|
||||
Crn: crn,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgDeleteNameAuthority) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgDeleteNameAuthority) Type() string { return "delete-name" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgDeleteNameAuthority) ValidateBasic() error {
|
||||
if len(msg.Crn) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "crn is required.")
|
||||
}
|
||||
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
_, err := url.Parse(msg.Crn)
|
||||
if err != nil {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid crn.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgSetName
|
||||
func (msg MsgDeleteNameAuthority) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgDeleteNameAuthority) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
Generated
+3688
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Default parameter values.
|
||||
var (
|
||||
// DefaultRecordRent is the default record rent for 1 time period (see expiry time).
|
||||
DefaultRecordRent = sdk.NewInt(1000000)
|
||||
|
||||
// DefaultRecordExpiryTime is the default record expiry time (1 year).
|
||||
DefaultRecordExpiryTime = time.Hour * 24 * 365
|
||||
|
||||
DefaultAuthorityRent = sdk.NewInt(1000000)
|
||||
DefaultAuthorityExpiryTime = time.Hour * 24 * 365
|
||||
DefaultAuthorityGracePeriod = time.Hour * 24 * 2
|
||||
|
||||
DefaultAuthorityAuctionEnabled = false
|
||||
DefaultCommitsDuration = time.Hour * 24
|
||||
DefaultRevealsDuration = time.Hour * 24
|
||||
DefaultCommitFee = sdk.NewInt(1000000)
|
||||
DefaultRevealFee = sdk.NewInt(1000000)
|
||||
DefaultMinimumBid = sdk.NewInt(5000000)
|
||||
)
|
||||
|
||||
// Keys for parameter access
|
||||
var (
|
||||
KeyRecordRent = []byte("RecordRent")
|
||||
KeyRecordRentDuration = []byte("RecordRentDuration")
|
||||
|
||||
KeyAuthorityRent = []byte("AuthorityRent")
|
||||
KeyAuthorityRentDuration = []byte("AuthorityRentDuration")
|
||||
KeyAuthorityGracePeriod = []byte("AuthorityGracePeriod")
|
||||
|
||||
KeyAuthorityAuctionEnabled = []byte("AuthorityAuctionEnabled")
|
||||
KeyCommitsDuration = []byte("AuthorityAuctionCommitsDuration")
|
||||
KeyRevealsDuration = []byte("AuthorityAuctionRevealsDuration")
|
||||
KeyCommitFee = []byte("AuthorityAuctionCommitFee")
|
||||
KeyRevealFee = []byte("AuthorityAuctionRevealFee")
|
||||
KeyMinimumBid = []byte("AuthorityAuctionMinimumBid")
|
||||
)
|
||||
|
||||
var _ paramtypes.ParamSet = &Params{}
|
||||
|
||||
// ParamKeyTable ParamTable for staking module
|
||||
func ParamKeyTable() paramtypes.KeyTable {
|
||||
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
|
||||
}
|
||||
|
||||
// ParamSetPairs returns the parameter set pairs.
|
||||
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
|
||||
return paramtypes.ParamSetPairs{
|
||||
paramtypes.NewParamSetPair(KeyRecordRent, &p.RecordRent, validateRecordRent),
|
||||
paramtypes.NewParamSetPair(KeyRecordRentDuration, &p.RecordRentDuration, validateRecordRentDuration),
|
||||
|
||||
paramtypes.NewParamSetPair(KeyAuthorityRent, &p.AuthorityRent, validateAuthorityRent),
|
||||
paramtypes.NewParamSetPair(KeyAuthorityRentDuration, &p.AuthorityRentDuration, validateAuthorityRentDuration),
|
||||
paramtypes.NewParamSetPair(KeyAuthorityGracePeriod, &p.AuthorityGracePeriod, validateAuthorityGracePeriod),
|
||||
|
||||
paramtypes.NewParamSetPair(KeyAuthorityAuctionEnabled, &p.AuthorityAuctionEnabled, validateAuthorityAuctionEnabled),
|
||||
paramtypes.NewParamSetPair(KeyCommitsDuration, &p.AuthorityAuctionCommitsDuration, validateCommitsDuration),
|
||||
paramtypes.NewParamSetPair(KeyRevealsDuration, &p.AuthorityAuctionRevealsDuration, validateRevealsDuration),
|
||||
paramtypes.NewParamSetPair(KeyCommitFee, &p.AuthorityAuctionCommitFee, validateCommitFee),
|
||||
paramtypes.NewParamSetPair(KeyRevealFee, &p.AuthorityAuctionRevealFee, validateRevealFee),
|
||||
paramtypes.NewParamSetPair(KeyMinimumBid, &p.AuthorityAuctionMinimumBid, validateMinimumBid),
|
||||
}
|
||||
}
|
||||
|
||||
// NewParams creates a new Params instance
|
||||
func NewParams(recordRent sdk.Coin, recordRentDuration time.Duration,
|
||||
authorityRent sdk.Coin, authorityRentDuration time.Duration, authorityGracePeriod time.Duration,
|
||||
authorityAuctionEnabled bool, commitsDuration time.Duration, revealsDuration time.Duration,
|
||||
commitFee sdk.Coin, revealFee sdk.Coin, minimumBid sdk.Coin) Params {
|
||||
|
||||
return Params{
|
||||
RecordRent: recordRent,
|
||||
RecordRentDuration: recordRentDuration,
|
||||
|
||||
AuthorityRent: authorityRent,
|
||||
AuthorityRentDuration: authorityRentDuration,
|
||||
AuthorityGracePeriod: authorityGracePeriod,
|
||||
|
||||
AuthorityAuctionEnabled: authorityAuctionEnabled,
|
||||
AuthorityAuctionCommitsDuration: commitsDuration,
|
||||
AuthorityAuctionRevealsDuration: revealsDuration,
|
||||
AuthorityAuctionCommitFee: commitFee,
|
||||
AuthorityAuctionRevealFee: revealFee,
|
||||
AuthorityAuctionMinimumBid: minimumBid,
|
||||
}
|
||||
}
|
||||
|
||||
// Equal returns a boolean determining if two Params types are identical.
|
||||
func (p Params) Equal(p2 Params) bool {
|
||||
bz1 := ModuleCdc.MustMarshalLengthPrefixed(&p)
|
||||
bz2 := ModuleCdc.MustMarshalLengthPrefixed(&p2)
|
||||
return bytes.Equal(bz1, bz2)
|
||||
}
|
||||
|
||||
// DefaultParams returns a default set of parameters.
|
||||
func DefaultParams() Params {
|
||||
return NewParams(
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultRecordRent), DefaultRecordExpiryTime,
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultAuthorityRent),
|
||||
DefaultAuthorityExpiryTime, DefaultAuthorityGracePeriod, DefaultAuthorityAuctionEnabled, DefaultCommitsDuration,
|
||||
DefaultRevealsDuration,
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultCommitFee),
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultRevealFee),
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, DefaultMinimumBid),
|
||||
)
|
||||
}
|
||||
|
||||
func validateAmount(name string, i interface{}) error {
|
||||
v, ok := i.(sdk.Coin)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid parameter type: %T", i)
|
||||
}
|
||||
|
||||
if v.Amount.IsNegative() {
|
||||
return fmt.Errorf("%s can't be negative", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateDuration(name string, i interface{}) error {
|
||||
v, ok := i.(time.Duration)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s invalid parameter type: %T", name, i)
|
||||
}
|
||||
|
||||
if v <= 0 {
|
||||
return fmt.Errorf("%s must be a positive integer", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRecordRent(i interface{}) error {
|
||||
return validateAmount("RecordRent", i)
|
||||
}
|
||||
|
||||
func validateRecordRentDuration(i interface{}) error {
|
||||
return validateDuration("RecordRentDuration", i)
|
||||
}
|
||||
|
||||
func validateAuthorityRent(i interface{}) error {
|
||||
return validateAmount("AuthorityRent", i)
|
||||
}
|
||||
|
||||
func validateAuthorityRentDuration(i interface{}) error {
|
||||
return validateDuration("AuthorityRentDuration", i)
|
||||
}
|
||||
|
||||
func validateAuthorityGracePeriod(i interface{}) error {
|
||||
return validateDuration("AuthorityGracePeriod", i)
|
||||
}
|
||||
|
||||
func validateAuthorityAuctionEnabled(i interface{}) error {
|
||||
_, ok := i.(bool)
|
||||
if !ok {
|
||||
return fmt.Errorf("%s invalid parameter type: %T", "AuthorityAuctionEnabled", i)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateCommitsDuration(i interface{}) error {
|
||||
return validateDuration("AuthorityCommitsDuration", i)
|
||||
}
|
||||
|
||||
func validateRevealsDuration(i interface{}) error {
|
||||
return validateDuration("AuthorityRevealsDuration", i)
|
||||
}
|
||||
|
||||
func validateCommitFee(i interface{}) error {
|
||||
return validateAmount("AuthorityCommitFee", i)
|
||||
}
|
||||
|
||||
func validateRevealFee(i interface{}) error {
|
||||
return validateAmount("AuthorityRevealFee", i)
|
||||
}
|
||||
|
||||
func validateMinimumBid(i interface{}) error {
|
||||
return validateAmount("AuthorityMinimumBid", i)
|
||||
}
|
||||
|
||||
// Validate a set of params.
|
||||
func (p Params) Validate() error {
|
||||
if err := validateRecordRent(p.RecordRent); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateRecordRentDuration(p.RecordRentDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateAuthorityRent(p.AuthorityRent); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateAuthorityRentDuration(p.AuthorityRentDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateAuthorityGracePeriod(p.AuthorityGracePeriod); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateAuthorityAuctionEnabled(p.AuthorityAuctionEnabled); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateCommitsDuration(p.AuthorityAuctionCommitsDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateRevealsDuration(p.AuthorityAuctionRevealsDuration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateCommitFee(p.AuthorityAuctionCommitFee); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateRevealFee(p.AuthorityAuctionRevealFee); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateMinimumBid(p.AuthorityAuctionMinimumBid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Generated
+6272
File diff suppressed because it is too large
Load Diff
Generated
+1002
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
_ sdk.Msg = &MsgSetRecord{}
|
||||
_ sdk.Msg = &MsgRenewRecord{}
|
||||
_ sdk.Msg = &MsgAssociateBond{}
|
||||
_ sdk.Msg = &MsgDissociateBond{}
|
||||
_ sdk.Msg = &MsgDissociateRecords{}
|
||||
_ sdk.Msg = &MsgReAssociateRecords{}
|
||||
)
|
||||
|
||||
// NewMsgSetRecord is the constructor function for MsgSetRecord.
|
||||
func NewMsgSetRecord(payload Payload, bondID string, signer sdk.AccAddress) MsgSetRecord {
|
||||
return MsgSetRecord{
|
||||
Payload: payload,
|
||||
BondId: bondID,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgSetRecord) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgSetRecord) Type() string { return "set-record" }
|
||||
|
||||
func (msg MsgSetRecord) ValidateBasic() error {
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Signer)
|
||||
}
|
||||
owners := msg.Payload.Record.Owners
|
||||
for _, owner := range owners {
|
||||
if owner == "" {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "Record owner not set.")
|
||||
}
|
||||
}
|
||||
|
||||
if len(msg.BondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "Bond ID is required.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (msg MsgSetRecord) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for the msg MsgCreateBond
|
||||
func (msg MsgSetRecord) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// NewMsgRenewRecord is the constructor function for MsgRenewRecord.
|
||||
func NewMsgRenewRecord(recordId string, signer sdk.AccAddress) MsgRenewRecord {
|
||||
return MsgRenewRecord{
|
||||
RecordId: recordId,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgRenewRecord) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgRenewRecord) Type() string { return "renew-record" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgRenewRecord) ValidateBasic() error {
|
||||
if len(msg.RecordId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "record id is required.")
|
||||
}
|
||||
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for Msg
|
||||
func (msg MsgRenewRecord) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgRenewRecord) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgAssociateBond is the constructor function for MsgAssociateBond.
|
||||
func NewMsgAssociateBond(recordId, bondId string, signer sdk.AccAddress) MsgAssociateBond {
|
||||
return MsgAssociateBond{
|
||||
BondId: bondId,
|
||||
RecordId: recordId,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgAssociateBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgAssociateBond) Type() string { return "associate-bond" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgAssociateBond) ValidateBasic() error {
|
||||
if len(msg.RecordId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "record id is required.")
|
||||
}
|
||||
if len(msg.BondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bond id is required.")
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for Msg
|
||||
func (msg MsgAssociateBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgAssociateBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgDissociateBond is the constructor function for MsgDissociateBond.
|
||||
func NewMsgDissociateBond(recordId string, signer sdk.AccAddress) MsgDissociateBond {
|
||||
return MsgDissociateBond{
|
||||
RecordId: recordId,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgDissociateBond) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgDissociateBond) Type() string { return "dissociate-bond" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgDissociateBond) ValidateBasic() error {
|
||||
if len(msg.RecordId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "record id is required.")
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for Msg
|
||||
func (msg MsgDissociateBond) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgDissociateBond) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgDissociateRecords is the constructor function for MsgDissociateRecords.
|
||||
func NewMsgDissociateRecords(bondId string, signer sdk.AccAddress) MsgDissociateRecords {
|
||||
return MsgDissociateRecords{
|
||||
BondId: bondId,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgDissociateRecords) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgDissociateRecords) Type() string { return "dissociate-records" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgDissociateRecords) ValidateBasic() error {
|
||||
if len(msg.BondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "bond id is required.")
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for Msg
|
||||
func (msg MsgDissociateRecords) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgDissociateRecords) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
|
||||
// NewMsgReAssociateRecords is the constructor function for MsgReAssociateRecords.
|
||||
func NewMsgReAssociateRecords(oldBondId, newBondId string, signer sdk.AccAddress) MsgReAssociateRecords {
|
||||
return MsgReAssociateRecords{
|
||||
OldBondId: oldBondId,
|
||||
NewBondId: newBondId,
|
||||
Signer: signer.String(),
|
||||
}
|
||||
}
|
||||
|
||||
// Route Implements Msg.
|
||||
func (msg MsgReAssociateRecords) Route() string { return RouterKey }
|
||||
|
||||
// Type Implements Msg.
|
||||
func (msg MsgReAssociateRecords) Type() string { return "reassociate-records" }
|
||||
|
||||
// ValidateBasic Implements Msg.
|
||||
func (msg MsgReAssociateRecords) ValidateBasic() error {
|
||||
if len(msg.OldBondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "old-bond-id is required.")
|
||||
}
|
||||
if len(msg.NewBondId) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "new-bond-id is required.")
|
||||
}
|
||||
if len(msg.Signer) == 0 {
|
||||
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "invalid signer.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignBytes gets the sign bytes for Msg
|
||||
func (msg MsgReAssociateRecords) GetSignBytes() []byte {
|
||||
bz := ModuleCdc.MustMarshalJSON(&msg)
|
||||
return sdk.MustSortJSON(bz)
|
||||
}
|
||||
|
||||
// GetSigners Implements Msg.
|
||||
func (msg MsgReAssociateRecords) GetSigners() []sdk.AccAddress {
|
||||
accAddr, _ := sdk.AccAddressFromBech32(msg.Signer)
|
||||
return []sdk.AccAddress{accAddr}
|
||||
}
|
||||
Generated
+4643
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,131 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
|
||||
canonicalJson "github.com/gibson042/canonicaljson-go"
|
||||
"github.com/tharsis/ethermint/x/nameservice/helpers"
|
||||
)
|
||||
|
||||
const (
|
||||
AuthorityActive = "active"
|
||||
AuthorityExpired = "expired"
|
||||
AuthorityUnderAuction = "auction"
|
||||
)
|
||||
|
||||
// PayloadType represents a signed record payload that can be serialized from/to YAML.
|
||||
type PayloadType struct {
|
||||
Record map[string]interface{} `json:"record"`
|
||||
Signatures []Signature `json:"signatures"`
|
||||
}
|
||||
|
||||
// ToPayload converts PayloadType to Payload object.
|
||||
// Why? Because go-amino can't handle maps: https://github.com/tendermint/go-amino/issues/4.
|
||||
func (payloadObj *PayloadType) ToPayload() Payload {
|
||||
var payload = Payload{
|
||||
Record: &Record{
|
||||
Deleted: false,
|
||||
Owners: nil,
|
||||
Attributes: helpers.BytesToBase64(helpers.MarshalMapToJSONBytes(payloadObj.Record)),
|
||||
},
|
||||
Signatures: payloadObj.Signatures,
|
||||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
// ToReadablePayload converts Payload to PayloadType
|
||||
// It will unmarshal with record attributes
|
||||
func (payload Payload) ToReadablePayload() PayloadType {
|
||||
var payloadType PayloadType
|
||||
|
||||
payloadType.Record = helpers.UnMarshalMapFromJSONBytes(helpers.BytesFromBase64(payload.Record.Attributes))
|
||||
|
||||
payloadType.Signatures = payload.Signatures
|
||||
|
||||
return payloadType
|
||||
}
|
||||
|
||||
// Record to Record Type for human-readable attributes
|
||||
|
||||
func (r *Record) ToRecordType() RecordType {
|
||||
var resourceObj RecordType
|
||||
|
||||
resourceObj.Id = r.Id
|
||||
resourceObj.BondId = r.BondId
|
||||
resourceObj.CreateTime = r.CreateTime
|
||||
resourceObj.ExpiryTime = r.ExpiryTime
|
||||
resourceObj.Deleted = r.Deleted
|
||||
resourceObj.Owners = r.Owners
|
||||
resourceObj.Names = r.Names
|
||||
resourceObj.Attributes = helpers.UnMarshalMapFromJSONBytes(helpers.BytesFromBase64(r.Attributes))
|
||||
|
||||
return resourceObj
|
||||
}
|
||||
|
||||
// RecordType represents a WNS record.
|
||||
type RecordType struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Names []string `json:"names,omitempty"`
|
||||
BondId string `json:"bondId,omitempty"`
|
||||
CreateTime string `json:"createTime,omitempty"`
|
||||
ExpiryTime string `json:"expiryTime,omitempty"`
|
||||
Deleted bool `json:"deleted,omitempty"`
|
||||
Owners []string `json:"owners,omitempty"`
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// ToRecordObj converts Record to RecordObj.
|
||||
// Why? Because go-amino can't handle maps: https://github.com/tendermint/go-amino/issues/4.
|
||||
func (r *RecordType) ToRecordObj() Record {
|
||||
var resourceObj Record
|
||||
|
||||
resourceObj.Id = r.Id
|
||||
resourceObj.BondId = r.BondId
|
||||
resourceObj.CreateTime = r.CreateTime
|
||||
resourceObj.ExpiryTime = r.ExpiryTime
|
||||
resourceObj.Deleted = r.Deleted
|
||||
resourceObj.Owners = r.Owners
|
||||
resourceObj.Attributes = helpers.BytesToBase64(helpers.MarshalMapToJSONBytes(r.Attributes))
|
||||
|
||||
return resourceObj
|
||||
}
|
||||
|
||||
// CanonicalJSON returns the canonical JSON representation of the record.
|
||||
func (r *RecordType) CanonicalJSON() []byte {
|
||||
bytes, err := canonicalJson.Marshal(r.Attributes)
|
||||
if err != nil {
|
||||
panic("Record marshal error.")
|
||||
}
|
||||
|
||||
return bytes
|
||||
}
|
||||
|
||||
// GetSignBytes generates a record hash to be signed.
|
||||
func (r *RecordType) GetSignBytes() ([]byte, []byte) {
|
||||
// Double SHA256 hash.
|
||||
|
||||
// Input to the first round of hashing.
|
||||
bytes := r.CanonicalJSON()
|
||||
|
||||
// First round.
|
||||
first := sha256.New()
|
||||
first.Write(bytes)
|
||||
firstHash := first.Sum(nil)
|
||||
|
||||
// Second round of hashing takes as input the output of the first round.
|
||||
second := sha256.New()
|
||||
second.Write(firstHash)
|
||||
secondHash := second.Sum(nil)
|
||||
|
||||
return secondHash, bytes
|
||||
}
|
||||
|
||||
// GetCID gets the record CID.
|
||||
func (r *RecordType) GetCID() (string, error) {
|
||||
id, err := helpers.GetCid(r.CanonicalJSON())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
Reference in New Issue
Block a user