Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #867 from Bytom/prod
Browse files Browse the repository at this point in the history
Prod
  • Loading branch information
Paladz authored Apr 28, 2018
2 parents 23e4539 + 77c7b4e commit 2c742b9
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 123 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,6 @@ benchmark:
functional-tests:
@go test -v -timeout=5m -tags=functional ./test

ci: test
ci: test functional-tests

.PHONY: all target release-all clean test benchmark
2 changes: 1 addition & 1 deletion account/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func (m *Manager) Create(ctx context.Context, xpubs []chainkd.XPub, quorum int,

accountID := Key(id)
storeBatch.Set(accountID, rawAccount)
storeBatch.Set(aliasKey(alias), []byte(id))
storeBatch.Set(aliasKey(normalizedAlias), []byte(id))
storeBatch.Write()

return account, nil
Expand Down
10 changes: 10 additions & 0 deletions account/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ func TestCreateAccountWithSpaceTrimed(t *testing.T) {
if account.Alias != strings.TrimSpace(alias) {
t.Fatal("created account alias should be lowercase")
}

nilAccount, err := m.FindByAlias(nil, alias)
if nilAccount != nil {
t.Fatal("expected nil")
}

target, err := m.FindByAlias(nil, strings.ToLower(strings.TrimSpace(alias)))
if target == nil {
t.Fatal("expected Account, but got nil")
}
}

func TestCreateAccount(t *testing.T) {
Expand Down
11 changes: 7 additions & 4 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ func (a *API) buildHandler() {
m.Handle("/", alwaysError(errors.New("not Found")))
m.Handle("/error", jsonHandler(a.walletError))

m.Handle("/net-info", jsonHandler(a.getNetInfo))

m.Handle("/create-access-token", jsonHandler(a.createAccessToken))
m.Handle("/list-access-tokens", jsonHandler(a.listAccessTokens))
m.Handle("/delete-access-token", jsonHandler(a.deleteAccessToken))
Expand All @@ -225,12 +223,17 @@ func (a *API) buildHandler() {
m.Handle("/get-block-header", jsonHandler(a.getBlockHeader))
m.Handle("/get-block", jsonHandler(a.getBlock))
m.Handle("/get-block-count", jsonHandler(a.getBlockCount))
m.Handle("/get-difficulty", jsonHandler(a.getDifficulty))
m.Handle("/get-hash-rate", jsonHandler(a.getHashRate))

m.Handle("/is-mining", jsonHandler(a.isMining))
m.Handle("/gas-rate", jsonHandler(a.gasRate))
m.Handle("/set-mining", jsonHandler(a.setMining))

m.Handle("/get-work", jsonHandler(a.getWork))
m.Handle("/submit-work", jsonHandler(a.submitWork))
m.Handle("/set-mining", jsonHandler(a.setMining))

m.Handle("/gas-rate", jsonHandler(a.gasRate))
m.Handle("/net-info", jsonHandler(a.getNetInfo))

handler := latencyHandler(m, walletEnable)
handler = maxBytesHandler(handler) // TODO(tessr): consider moving this to non-core specific mux
Expand Down
85 changes: 85 additions & 0 deletions api/block_retrieve.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package api

import (
"math/big"

"github.com/bytom/blockchain/query"
"github.com/bytom/consensus/difficulty"
chainjson "github.com/bytom/encoding/json"
Expand Down Expand Up @@ -143,3 +145,86 @@ func (a *API) getBlockHeader(ins BlockReq) Response {
}
return NewSuccessResponse(resp)
}

// GetDifficultyResp is resp struct for getDifficulty API
type GetDifficultyResp struct {
BlockHash *bc.Hash `json:"hash"`
BlockHeight uint64 `json:"height"`
Bits uint64 `json:"bits"`
Difficulty string `json:"difficulty"`
}

func (a *API) getDifficulty(ins *BlockReq) Response {
var err error
block := &types.Block{}

if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
b32 := [32]byte{}
copy(b32[:], ins.BlockHash)
hash := bc.NewHash(b32)
block, err = a.chain.GetBlockByHash(&hash)
} else if ins.BlockHeight > 0 {
block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
} else {
hash := a.chain.BestBlockHash()
block, err = a.chain.GetBlockByHash(hash)
}

if err != nil {
return NewErrorResponse(err)
}

blockHash := block.Hash()
resp := &GetDifficultyResp{
BlockHash: &blockHash,
BlockHeight: block.Height,
Bits: block.Bits,
Difficulty: difficulty.CalcWork(block.Bits).String(),
}
return NewSuccessResponse(resp)
}

// getHashRateResp is resp struct for getHashRate API
type getHashRateResp struct {
BlockHash *bc.Hash `json:"hash"`
BlockHeight uint64 `json:"height"`
HashRate uint64 `json:"hash_rate"`
}

func (a *API) getHashRate(ins BlockReq) Response {
var err error
block := &types.Block{}

if len(ins.BlockHash) == 32 && ins.BlockHash != nil {
b32 := [32]byte{}
copy(b32[:], ins.BlockHash)
hash := bc.NewHash(b32)
block, err = a.chain.GetBlockByHash(&hash)
} else if ins.BlockHeight > 0 {
block, err = a.chain.GetBlockByHeight(ins.BlockHeight)
} else {
hash := a.chain.BestBlockHash()
block, err = a.chain.GetBlockByHash(hash)
}

if err != nil {
return NewErrorResponse(err)
}

preBlock, err := a.chain.GetBlockByHash(&block.PreviousBlockHash)
if err != nil {
return NewErrorResponse(err)
}

diffTime := block.Timestamp - preBlock.Timestamp
hashCount := difficulty.CalcWork(block.Bits)
hashRate := new(big.Int).Div(hashCount, big.NewInt(int64(diffTime)))

blockHash := block.Hash()
resp := &getHashRateResp{
BlockHash: &blockHash,
BlockHeight: block.Height,
HashRate: hashRate.Uint64(),
}
return NewSuccessResponse(resp)
}
73 changes: 72 additions & 1 deletion cmd/bytomcli/commands/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ import (
"github.com/bytom/util"
)

func init() {
getDifficultyCmd.PersistentFlags().StringVar(&blockHash, "hash", "", "hash of block")
getDifficultyCmd.PersistentFlags().IntVar(&blockHeight, "height", 0, "height of block")

getHashRateCmd.PersistentFlags().StringVar(&blockHash, "hash", "", "hash of block")
getHashRateCmd.PersistentFlags().IntVar(&blockHeight, "height", 0, "height of block")
}

var (
blockHash = ""
blockHeight = 0
)

var getBlockHashCmd = &cobra.Command{
Use: "get-block-hash",
Short: "Get the hash of most recent block",
Expand Down Expand Up @@ -139,7 +152,65 @@ var getBlockHeaderCmd = &cobra.Command{
BlockHash chainjson.HexBytes `json:"block_hash"`
}{BlockHeight: height, BlockHash: hash}

data, exitCode := util.ClientCall("/get-block-header", &req)
data, exitCode := util.ClientCall("/get-block-header", req)
if exitCode != util.Success {
os.Exit(exitCode)
}
printJSON(data)
},
}

var getDifficultyCmd = &cobra.Command{
Use: "get-difficulty",
Short: "Get the difficulty of most recent block",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var hash chainjson.HexBytes
var err error

if blockHash != "" {
hash, err = hex.DecodeString(blockHash)
if err != nil {
jww.ERROR.Println(err)
os.Exit(util.ErrLocalExe)
}
}

req := &struct {
BlockHeight uint64 `json:"block_height"`
BlockHash chainjson.HexBytes `json:"block_hash"`
}{BlockHeight: uint64(blockHeight), BlockHash: hash}

data, exitCode := util.ClientCall("/get-difficulty", req)
if exitCode != util.Success {
os.Exit(exitCode)
}
printJSON(data)
},
}

var getHashRateCmd = &cobra.Command{
Use: "get-hash-rate",
Short: "Get the nonce of most recent block",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
var hash chainjson.HexBytes
var err error

if blockHash != "" {
hash, err = hex.DecodeString(blockHash)
if err != nil {
jww.ERROR.Println(err)
os.Exit(util.ErrLocalExe)
}
}

req := &struct {
BlockHeight uint64 `json:"block_height"`
BlockHash chainjson.HexBytes `json:"block_hash"`
}{BlockHeight: uint64(blockHeight), BlockHash: hash}

data, exitCode := util.ClientCall("/get-hash-rate", req)
if exitCode != util.Success {
os.Exit(exitCode)
}
Expand Down
100 changes: 91 additions & 9 deletions cmd/bytomcli/commands/bytomcli.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,37 @@ import (
"github.com/bytom/util"
)

// bytomcli usage template
var usageTemplate = `Usage:{{if .Runnable}}
{{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}
{{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
Examples:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
Available Commands:
{{range .Commands}}{{if (and .IsAvailableCommand (.Name | WalletDisable))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}
available with wallet enable:
{{range .Commands}}{{if (and .IsAvailableCommand (.Name | WalletEnable))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Flags:
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
Global Flags:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} [command] --help" for more information about a command.{{end}}
`

// commandError is an error used to signal different error situations in command handling.
type commandError struct {
s string
Expand Down Expand Up @@ -56,6 +87,7 @@ var BytomcliCmd = &cobra.Command{
Short: "Bytomcli is a commond line client for bytom core (a.k.a. bytomd)",
Run: func(cmd *cobra.Command, args []string) {
if len(args) < 1 {
cmd.SetUsageTemplate(usageTemplate)
cmd.Usage()
}
},
Expand All @@ -65,6 +97,7 @@ var BytomcliCmd = &cobra.Command{
func Execute() {

AddCommands()
AddTemplateFunc()

if _, err := BytomcliCmd.ExecuteC(); err != nil {
os.Exit(util.ErrLocalExe)
Expand Down Expand Up @@ -108,26 +141,75 @@ func AddCommands() {
BytomcliCmd.AddCommand(getBlockHashCmd)
BytomcliCmd.AddCommand(getBlockCmd)
BytomcliCmd.AddCommand(getBlockHeaderCmd)
BytomcliCmd.AddCommand(getDifficultyCmd)
BytomcliCmd.AddCommand(getHashRateCmd)

BytomcliCmd.AddCommand(createKeyCmd)
BytomcliCmd.AddCommand(deleteKeyCmd)
BytomcliCmd.AddCommand(listKeysCmd)
BytomcliCmd.AddCommand(resetKeyPwdCmd)

BytomcliCmd.AddCommand(isMiningCmd)

BytomcliCmd.AddCommand(netInfoCmd)
BytomcliCmd.AddCommand(netListeningCmd)
BytomcliCmd.AddCommand(peerCountCmd)
BytomcliCmd.AddCommand(netSyncingCmd)

BytomcliCmd.AddCommand(gasRateCmd)

BytomcliCmd.AddCommand(createTransactionFeedCmd)
BytomcliCmd.AddCommand(listTransactionFeedsCmd)
BytomcliCmd.AddCommand(deleteTransactionFeedCmd)
BytomcliCmd.AddCommand(getTransactionFeedCmd)
BytomcliCmd.AddCommand(updateTransactionFeedCmd)

BytomcliCmd.AddCommand(isMiningCmd)
BytomcliCmd.AddCommand(setMiningCmd)

BytomcliCmd.AddCommand(netInfoCmd)
BytomcliCmd.AddCommand(gasRateCmd)

BytomcliCmd.AddCommand(versionCmd)
}

// AddTemplateFunc adds usage template to the root command BytomcliCmd.
func AddTemplateFunc() {
walletEnableCmd := []string{
createAccountCmd.Name(),
listAccountsCmd.Name(),
deleteAccountCmd.Name(),
createAccountReceiverCmd.Name(),
listAddressesCmd.Name(),
validateAddressCmd.Name(),

createAssetCmd.Name(),
getAssetCmd.Name(),
listAssetsCmd.Name(),
updateAssetAliasCmd.Name(),

createKeyCmd.Name(),
deleteKeyCmd.Name(),
listKeysCmd.Name(),
resetKeyPwdCmd.Name(),

buildTransactionCmd.Name(),
signTransactionCmd.Name(),
submitTransactionCmd.Name(),
estimateTransactionGasCmd.Name(),

getTransactionCmd.Name(),
listTransactionsCmd.Name(),
listUnspentOutputsCmd.Name(),
listBalancesCmd.Name(),
}

cobra.AddTemplateFunc("WalletEnable", func(cmdName string) bool {
for _, name := range walletEnableCmd {
if name == cmdName {
return true
}
}
return false
})

cobra.AddTemplateFunc("WalletDisable", func(cmdName string) bool {
for _, name := range walletEnableCmd {
if name == cmdName {
return false
}
}
return true
})
}
Loading

0 comments on commit 2c742b9

Please sign in to comment.