Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

chain:Implement faucet service for testnet #2058

Merged
merged 10 commits into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG_UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

### Chain

- (feat) [\#2058](https://github.com/bandprotocol/bandchain/pull/2058) Implement faucet service for testnet.
- (impv) [\#2057](https://github.com/bandprotocol/bandchain/pull/2057) Change wasm execute gas to 100000.
- (chore) [\#2053](https://github.com/bandprotocol/bandchain/pull/2053) Remove data sources and oracle scripts from repo.
- (chore) [\#2056](https://github.com/bandprotocol/bandchain/pull/2056) Remove IBCInfo from current v0.38 release.
Expand Down
2 changes: 1 addition & 1 deletion chain/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ COPY chain/ /chain

COPY chain/docker-config/run.sh .

RUN make install
RUN make install && make faucet

CMD bandd start --rpc.laddr tcp://0.0.0.0:26657
3 changes: 3 additions & 0 deletions chain/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ install: go.sum
go install -mod=readonly $(BUILD_FLAGS) ./cmd/bandcli
go install -mod=readonly $(BUILD_FLAGS) ./cmd/bandoracled2

faucet: go.sum
go install -mod=readonly $(BUILD_FLAGS) ./cmd/faucet

release: go.sum
env GOOS=linux GOARCH=amd64 \
go build -mod=readonly -o ./build/bandd_linux_amd64 $(BUILD_FLAGS) ./cmd/bandd
Expand Down
7 changes: 3 additions & 4 deletions chain/cmd/bandoracled2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ import (
)

const (
flagValidator = "validator"
flagLogLevel = "log-level"
flagExecutor = "executor"
flagChainRestServerURI = "chain-rest-server"
flagValidator = "validator"
flagLogLevel = "log-level"
flagExecutor = "executor"
)

// Config data structure for bandoracled daemon.
Expand Down
20 changes: 20 additions & 0 deletions chain/cmd/faucet/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func configCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "config [key] [value]",
Aliases: []string{"c"},
Short: "Set faucet configuration environment",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
viper.Set(args[0], args[1])
return viper.WriteConfig()
},
}
return cmd
}
14 changes: 14 additions & 0 deletions chain/cmd/faucet/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
rpcclient "github.com/tendermint/tendermint/rpc/client"
)

type Context struct {
client rpcclient.Client
gasPrices sdk.DecCoins
keys chan keys.Info
amount sdk.Coins
}
82 changes: 82 additions & 0 deletions chain/cmd/faucet/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"fmt"
"net/http"

"github.com/bandprotocol/bandchain/chain/app"
sdkctx "github.com/cosmos/cosmos-sdk/client/context"
ckeys "github.com/cosmos/cosmos-sdk/client/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/gin-gonic/gin"
)

type Request struct {
Address string `json:"address" binding:"required"`
}

type Response struct {
TxHash string `json:"txHash"`
}

var (
cdc = app.MakeCodec()
)

func handleRequest(gc *gin.Context, c *Context) {
key := <-c.keys
defer func() {
c.keys <- key
}()

var req Request
if err := gc.ShouldBindJSON(&req); err != nil {
gc.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
to, err := sdk.AccAddressFromBech32(req.Address)
if err != nil {
gc.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
msg := bank.NewMsgSend(key.GetAddress(), to, c.amount)
if err := msg.ValidateBasic(); err != nil {
gc.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

cliCtx := sdkctx.CLIContext{Client: c.client}
acc, err := auth.NewAccountRetriever(cliCtx).GetAccount(key.GetAddress())
if err != nil {
gc.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

txBldr := auth.NewTxBuilder(
auth.DefaultTxEncoder(cdc), acc.GetAccountNumber(), acc.GetSequence(),
200000, 1, false, cfg.ChainID, "", sdk.NewCoins(), c.gasPrices,
)
out, err := txBldr.WithKeybase(keybase).BuildAndSign(key.GetName(), ckeys.DefaultKeyPass, []sdk.Msg{msg})
if err != nil {
gc.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

res, err := cliCtx.BroadcastTxCommit(out)
if err != nil {
gc.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if res.Code != 0 {
gc.JSON(http.StatusInternalServerError, gin.H{
"error": fmt.Sprintf(":exploding_head: Tx returned nonzero code %d with log %s, tx hash: %s",
res.Code, res.RawLog, res.TxHash,
)})
return
}
gc.JSON(200, Response{
TxHash: res.TxHash,
})
}
165 changes: 165 additions & 0 deletions chain/cmd/faucet/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package main

import (
"bufio"
"fmt"

"github.com/cosmos/cosmos-sdk/client/input"
ckeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/go-bip39"
"github.com/spf13/cobra"
)

const (
flagAccount = "account"
flagIndex = "index"
flagCoinType = "coin-type"
flagRecover = "recover"
)

func keysCmd(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Aliases: []string{"k"},
Short: "Manage key held by the oracle process",
}
cmd.AddCommand(keysAddCmd(c))
cmd.AddCommand(keysDeleteCmd(c))
cmd.AddCommand(keysListCmd(c))
cmd.AddCommand(keysShowCmd(c))
return cmd
}

func keysAddCmd(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "add [name]",
Aliases: []string{"a"},
Short: "Add a new key to the keychain",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var mnemonic string
recover, err := cmd.Flags().GetBool(flagRecover)
if err != nil {
return err
}
if recover {
inBuf := bufio.NewReader(cmd.InOrStdin())
var err error
mnemonic, err = input.GetString("Enter your bip39 mnemonic", inBuf)
if err != nil {
return err
}
} else {
seed, err := bip39.NewEntropy(256)
if err != nil {
return err
}
mnemonic, err = bip39.NewMnemonic(seed)
if err != nil {
return err
}
fmt.Printf("Mnemonic: %s\n", mnemonic)
}

if err != nil {
return err
}
account, err := cmd.Flags().GetUint32(flagAccount)
if err != nil {
return err
}
index, err := cmd.Flags().GetUint32(flagIndex)
if err != nil {
return err
}
hdPath := keys.CreateHDPath(account, index)
info, err := keybase.CreateAccount(args[0], mnemonic, "", ckeys.DefaultKeyPass, hdPath.String(), keys.Secp256k1)
if err != nil {
return err
}
fmt.Printf("Address: %s\n", info.GetAddress().String())
return nil
},
}
cmd.Flags().Bool(flagRecover, false, "Provide seed phrase to recover existing key instead of creating")
cmd.Flags().Uint32(flagAccount, 0, "Account number for HD derivation")
cmd.Flags().Uint32(flagIndex, 0, "Address index number for HD derivation")
return cmd
}

func keysDeleteCmd(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "delete [name]",
Aliases: []string{"d"},
Short: "Delete a key from the keychain",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]

_, err := keybase.Get(name)
if err != nil {
return err
}

inBuf := bufio.NewReader(cmd.InOrStdin())
confirmInput, err := input.GetString("Key will be deleted. Continue?[y/N]", inBuf)
if err != nil {
return err
}

if confirmInput != "y" {
fmt.Println("Cancel")
return nil
}

if err := keybase.Delete(name, "", true); err != nil {
return err
}

fmt.Printf("Deleted key: %s\n", name)
return nil
},
}
return cmd
}

func keysListCmd(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Aliases: []string{"l"},
Short: "List all the keys in the keychain",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
keys, err := keybase.List()
if err != nil {
return err
}
for _, key := range keys {
fmt.Printf("%s => %s\n", key.GetName(), key.GetAddress().String())
}
return nil
},
}
return cmd
}

func keysShowCmd(c *Context) *cobra.Command {
cmd := &cobra.Command{
Use: "show [name]",
Aliases: []string{"s"},
Short: "Show address from name in the keychain",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]

key, err := keybase.Get(name)
if err != nil {
return err
}
fmt.Println(key.GetAddress().String())
return nil
},
}
return cmd
}
Loading