Commit 2c249090 authored by 张振华's avatar 张振华

Merge branch 'master' into guess

parents 335380b0 e26a5b79
...@@ -33,6 +33,8 @@ const ( ...@@ -33,6 +33,8 @@ const (
delAct int64 = 2 //reference blockstore.go, del para block action delAct int64 = 2 //reference blockstore.go, del para block action
paraCrossTxCount = 2 //current only support 2 txs for cross paraCrossTxCount = 2 //current only support 2 txs for cross
minBlockNum = 6 //min block number startHeight before lastHeight in mainchain
) )
var ( var (
...@@ -40,7 +42,6 @@ var ( ...@@ -40,7 +42,6 @@ var (
grpcSite = "localhost:8802" grpcSite = "localhost:8802"
genesisBlockTime int64 = 1514533390 genesisBlockTime int64 = 1514533390
startHeight int64 //parachain sync from startHeight in mainchain startHeight int64 //parachain sync from startHeight in mainchain
searchSeq int64 //start sequence to search startHeight in mainchain
blockSec int64 = 5 //write block interval, second blockSec int64 = 5 //write block interval, second
emptyBlockInterval int64 = 4 //write empty block every interval blocks in mainchain emptyBlockInterval int64 = 4 //write empty block every interval blocks in mainchain
zeroHash [32]byte zeroHash [32]byte
...@@ -75,7 +76,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -75,7 +76,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
} }
if cfg.StartHeight > 0 { if cfg.StartHeight > 0 {
startHeight = cfg.StartHeight startHeight = cfg.StartHeight
searchSeq = calcSearchseq(cfg.StartHeight)
} }
if cfg.WriteBlockSeconds > 0 { if cfg.WriteBlockSeconds > 0 {
blockSec = cfg.WriteBlockSeconds blockSec = cfg.WriteBlockSeconds
...@@ -139,13 +139,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -139,13 +139,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
return para return para
} }
func calcSearchseq(height int64) int64 {
if height < 1000 {
return 0
}
return height - 1000
}
//para 不检查任何的交易 //para 不检查任何的交易
func (client *client) CheckBlock(parent *types.Block, current *types.BlockDetail) error { func (client *client) CheckBlock(parent *types.Block, current *types.BlockDetail) error {
err := checkMinerTx(current) err := checkMinerTx(current)
...@@ -179,10 +172,7 @@ func (client *client) InitBlock() { ...@@ -179,10 +172,7 @@ func (client *client) InitBlock() {
} }
if block == nil { if block == nil {
startSeq := int64(0) startSeq := client.GetStartSeq(startHeight)
if searchSeq > 0 {
startSeq = client.GetSeqByHeightOnMain(startHeight, searchSeq)
}
// 创世区块 // 创世区块
newblock := &types.Block{} newblock := &types.Block{}
newblock.Height = 0 newblock.Height = 0
...@@ -191,37 +181,47 @@ func (client *client) InitBlock() { ...@@ -191,37 +181,47 @@ func (client *client) InitBlock() {
tx := client.CreateGenesisTx() tx := client.CreateGenesisTx()
newblock.Txs = tx newblock.Txs = tx
newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs) newblock.TxHash = merkle.CalcMerkleRoot(newblock.Txs)
client.WriteBlock(zeroHash[:], newblock, startSeq-int64(1)) client.WriteBlock(zeroHash[:], newblock, startSeq-1)
} else { } else {
client.SetCurrentBlock(block) client.SetCurrentBlock(block)
} }
} }
func (client *client) GetSeqByHeightOnMain(height int64, originSeq int64) int64 { // GetStartSeq get startSeq in mainchain
lastSeq, err := client.GetLastSeqOnMainChain() func (client *client) GetStartSeq(height int64) int64 {
plog.Info("Searching for the sequence", "heightOnMain", height, "searchSeq", searchSeq, "lastSeq", lastSeq) if height == 0 {
return 0
}
lastHeight, err := client.GetLastHeightOnMainChain()
if err != nil { if err != nil {
panic(err) panic(err)
} }
hint := time.NewTicker(10 * time.Second) if lastHeight < height {
defer hint.Stop() panic(fmt.Sprintf("lastHeight(%d) less than startHeight(%d) in mainchain", lastHeight, height))
for originSeq <= lastSeq { }
hint := time.NewTicker(5 * time.Second)
for lastHeight < height+minBlockNum {
select { select {
case <-hint.C: case <-hint.C:
plog.Info("Still Searching......", "searchAtSeq", originSeq, "lastSeq", lastSeq) plog.Info("Waiting lastHeight increase......", "lastHeight", lastHeight, "startHeight", height)
default: default:
blockDetail, seqTy, err := client.GetBlockOnMainBySeq(originSeq) lastHeight, err = client.GetLastHeightOnMainChain()
if err != nil { if err != nil {
panic(err) panic(err)
} }
if blockDetail.Block.Height == height && seqTy == addAct { time.Sleep(time.Second)
plog.Info("the target sequence in mainchain", "heightOnMain", height, "targetSeq", originSeq)
return originSeq
} }
originSeq++
} }
hint.Stop()
plog.Info(fmt.Sprintf("lastHeight more than %d blocks after startHeight", minBlockNum), "lastHeight", lastHeight, "startHeight", height)
seq, err := client.GetSeqByHeightOnMainChain(height)
if err != nil {
panic(err)
} }
panic("Main chain has not reached the height currently") plog.Info("the start sequence in mainchain", "startHeight", height, "startSeq", seq)
return seq
} }
func (client *client) CreateGenesisTx() (ret []*types.Transaction) { func (client *client) CreateGenesisTx() (ret []*types.Transaction) {
...@@ -357,6 +357,15 @@ func (client *client) getLastBlockInfo() (int64, *types.Block, []byte, int64, er ...@@ -357,6 +357,15 @@ func (client *client) getLastBlockInfo() (int64, *types.Block, []byte, int64, er
} }
func (client *client) GetLastHeightOnMainChain() (int64, error) {
header, err := client.grpcClient.GetLastHeader(context.Background(), &types.ReqNil{})
if err != nil {
plog.Error("GetLastHeightOnMainChain", "Error", err.Error())
return -1, err
}
return header.Height, nil
}
func (client *client) GetLastSeqOnMainChain() (int64, error) { func (client *client) GetLastSeqOnMainChain() (int64, error) {
seq, err := client.grpcClient.GetLastBlockSequence(context.Background(), &types.ReqNil{}) seq, err := client.grpcClient.GetLastBlockSequence(context.Background(), &types.ReqNil{})
if err != nil { if err != nil {
...@@ -367,6 +376,24 @@ func (client *client) GetLastSeqOnMainChain() (int64, error) { ...@@ -367,6 +376,24 @@ func (client *client) GetLastSeqOnMainChain() (int64, error) {
return seq.Data, nil return seq.Data, nil
} }
func (client *client) GetSeqByHeightOnMainChain(height int64) (int64, error) {
hash, err := client.GetHashByHeightOnMainChain(height)
if err != nil {
return -1, err
}
seq, err := client.GetSeqByHashOnMainChain(hash)
return seq, err
}
func (client *client) GetHashByHeightOnMainChain(height int64) ([]byte, error) {
reply, err := client.grpcClient.GetBlockHash(context.Background(), &types.ReqInt{Height: height})
if err != nil {
plog.Error("GetHashByHeightOnMainChain", "Error", err.Error())
return nil, err
}
return reply.Hash, nil
}
func (client *client) GetSeqByHashOnMainChain(hash []byte) (int64, error) { func (client *client) GetSeqByHashOnMainChain(hash []byte) (int64, error) {
seq, err := client.grpcClient.GetSequenceByHash(context.Background(), &types.ReqHash{Hash: hash}) seq, err := client.grpcClient.GetSequenceByHash(context.Background(), &types.ReqHash{Hash: hash})
if err != nil { if err != nil {
...@@ -465,7 +492,6 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type ...@@ -465,7 +492,6 @@ func (client *client) RequestTx(currSeq int64, preMainBlockHash []byte) ([]*type
//lastSeq = currSeq-1, main node not update //lastSeq = currSeq-1, main node not update
if lastSeq+1 == currSeq { if lastSeq+1 == currSeq {
plog.Debug("Waiting new sequence from main chain") plog.Debug("Waiting new sequence from main chain")
time.Sleep(time.Second * time.Duration(blockSec*2))
return nil, nil, -1, paracross.ErrParaWaitingNewSeq return nil, nil, -1, paracross.ErrParaWaitingNewSeq
} }
...@@ -596,15 +622,16 @@ func (client *client) CreateBlock() { ...@@ -596,15 +622,16 @@ func (client *client) CreateBlock() {
txs, blockOnMain, seqTy, err := client.RequestTx(currSeq, lastSeqMainHash) txs, blockOnMain, seqTy, err := client.RequestTx(currSeq, lastSeqMainHash)
if err != nil { if err != nil {
incSeqFlag = false
if err == paracross.ErrParaCurHashNotMatch { if err == paracross.ErrParaCurHashNotMatch {
newSeq, newSeqMainHash, err := client.switchHashMatchedBlock(currSeq) newSeq, newSeqMainHash, err := client.switchHashMatchedBlock(currSeq)
if err == nil { if err == nil {
currSeq = newSeq currSeq = newSeq
lastSeqMainHash = newSeqMainHash lastSeqMainHash = newSeqMainHash
continue
} }
} }
incSeqFlag = false time.Sleep(time.Second * time.Duration(blockSec))
time.Sleep(time.Second)
continue continue
} }
......
...@@ -92,6 +92,9 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu ...@@ -92,6 +92,9 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
ret := &types.Reply{IsOk: true, Msg: data} ret := &types.Reply{IsOk: true, Msg: data}
s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe() s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe()
s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe() s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe()
s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: cfg.Consensus.StartHeight + minBlockNum}, nil).Maybe()
s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe()
s.grpcCli.On("GetSequenceByHash", mock.Anything, mock.Anything).Return(&types.Int64{Data: cfg.Consensus.StartHeight}, nil).Maybe()
s.para.grpcClient = s.grpcCli s.para.grpcClient = s.grpcCli
s.para.SetQueueClient(q.Client()) s.para.SetQueueClient(q.Client())
......
...@@ -58,7 +58,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) ...@@ -58,7 +58,7 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
s.store = store.New(cfg.Store, sub.Store) s.store = store.New(cfg.Store, sub.Store)
s.store.SetQueueClient(q.Client()) s.store.SetQueueClient(q.Client())
cfg.Consensus.StartHeight = 0 //cfg.Consensus.StartHeight = 0
cfg.Consensus.EmptyBlockInterval = 1 cfg.Consensus.EmptyBlockInterval = 1
s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client) s.para = New(cfg.Consensus, sub.Consensus["para"]).(*client)
s.grpcCli = &typesmocks.Chain33Client{} s.grpcCli = &typesmocks.Chain33Client{}
...@@ -103,6 +103,8 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule) ...@@ -103,6 +103,8 @@ func (s *suiteParaClient) initEnv(cfg *types.Config, sub *types.ConfigSubModule)
ret := &types.Reply{IsOk: true, Msg: data} ret := &types.Reply{IsOk: true, Msg: data}
s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe() s.grpcCli.On("QueryChain", mock.Anything, mock.Anything).Return(ret, nil).Maybe()
s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe() s.grpcCli.On("SendTransaction", mock.Anything, mock.Anything).Return(reply, nil).Maybe()
s.grpcCli.On("GetLastHeader", mock.Anything, mock.Anything).Return(&types.Header{Height: cfg.Consensus.StartHeight + minBlockNum}, nil).Maybe()
s.grpcCli.On("GetBlockHash", mock.Anything, mock.Anything).Return(&types.ReplyHash{Hash: []byte("1")}, nil).Maybe()
s.para.grpcClient = s.grpcCli s.para.grpcClient = s.grpcCli
s.para.SetQueueClient(q.Client()) s.para.SetQueueClient(q.Client())
......
...@@ -49,5 +49,4 @@ cli send jsvm call -a "{\"hello\": \"world\"}" -f hello -n test -k 14KEKbYtKKQm ...@@ -49,5 +49,4 @@ cli send jsvm call -a "{\"hello\": \"world\"}" -f hello -n test -k 14KEKbYtKKQm
第四步:query test合约hello函数 第四步:query test合约hello函数
cli jsvm query -a "{\"hello\": \"world\"}" -f hello -n test cli jsvm query -a "{\"hello\": \"world\"}" -f hello -n test
*/ */
...@@ -27,3 +27,18 @@ func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 { ...@@ -27,3 +27,18 @@ func (action *Action) GetMainHeightByTxHash(txHash []byte) int64 {
return -1 return -1
} }
// GetMainBlockHashByHeight get Hash
func (action *Action) GetMainBlockHashByHeight(height int64) ([]byte, error) {
for i := 0; i < retryNum; i++ {
req := &types.ReqInt{Height: height}
replyHash, err := action.grpcClient.GetBlockHash(context.Background(), req)
if err != nil {
time.Sleep(time.Second)
} else {
return replyHash.Hash, nil
}
}
return nil, types.ErrBlockNotFound
}
...@@ -127,6 +127,7 @@ type Action struct { ...@@ -127,6 +127,7 @@ type Action struct {
conn *grpc.ClientConn conn *grpc.ClientConn
grpcClient types.Chain33Client grpcClient types.Chain33Client
index int index int
lottery *Lottery
} }
// NewLotteryAction generate New Action // NewLotteryAction generate New Action
...@@ -135,10 +136,9 @@ func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action { ...@@ -135,10 +136,9 @@ func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action {
fromaddr := tx.From() fromaddr := tx.From()
msgRecvOp := grpc.WithMaxMsgSize(grpcRecSize) msgRecvOp := grpc.WithMaxMsgSize(grpcRecSize)
if types.IsPara() && cfg.ParaRemoteGrpcClient == "" { paraRemoteGrpcClient := types.Conf("config.consensus").GStr("ParaRemoteGrpcClient")
panic("ParaRemoteGrpcClient error")
} conn, err := grpc.Dial(paraRemoteGrpcClient, grpc.WithInsecure(), msgRecvOp)
conn, err := grpc.Dial(cfg.ParaRemoteGrpcClient, grpc.WithInsecure(), msgRecvOp)
if err != nil { if err != nil {
panic(err) panic(err)
...@@ -146,7 +146,7 @@ func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action { ...@@ -146,7 +146,7 @@ func NewLotteryAction(l *Lottery, tx *types.Transaction, index int) *Action {
grpcClient := types.NewChain33Client(conn) grpcClient := types.NewChain33Client(conn)
return &Action{l.GetCoinsAccount(), l.GetStateDB(), hash, fromaddr, l.GetBlockTime(), return &Action{l.GetCoinsAccount(), l.GetStateDB(), hash, fromaddr, l.GetBlockTime(),
l.GetHeight(), dapp.ExecAddress(string(tx.Execer)), l.GetDifficulty(), l.GetAPI(), conn, grpcClient, index} l.GetHeight(), dapp.ExecAddress(string(tx.Execer)), l.GetDifficulty(), l.GetAPI(), conn, grpcClient, index, l}
} }
// GetLottCommonRecipt generate logs for lottery common action // GetLottCommonRecipt generate logs for lottery common action
...@@ -569,7 +569,6 @@ func (action *Action) LotteryClose(draw *pty.LotteryClose) (*types.Receipt, erro ...@@ -569,7 +569,6 @@ func (action *Action) LotteryClose(draw *pty.LotteryClose) (*types.Receipt, erro
func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 { func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 {
var num int64 var num int64
var msg types.Message var msg types.Message
var err error
var hash []byte var hash []byte
if isSolo { if isSolo {
//used for internal verification //used for internal verification
...@@ -579,7 +578,12 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 { ...@@ -579,7 +578,12 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 {
//在主链上,当前高度查询不到,如果要保证区块个数,高度传入action.height-1 //在主链上,当前高度查询不到,如果要保证区块个数,高度传入action.height-1
llog.Debug("findLuckyNum on randnum module") llog.Debug("findLuckyNum on randnum module")
if !types.IsPara() { if !types.IsPara() {
req := &types.ReqRandHash{ExecName: "ticket", Height: action.height - 1, BlockNum: blockNum} blockHash, err := action.api.GetBlockHash(&types.ReqInt{Height: action.height - 1})
if err != nil {
return -1
}
req := &types.ReqRandHash{ExecName: "ticket", Hash: blockHash.Hash, BlockNum: blockNum}
msg, err = action.api.Query("ticket", "RandNumHash", req) msg, err = action.api.Query("ticket", "RandNumHash", req)
if err != nil { if err != nil {
return -1 return -1
...@@ -587,12 +591,20 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 { ...@@ -587,12 +591,20 @@ func (action *Action) findLuckyNum(isSolo bool, lott *LotteryDB) int64 {
reply := msg.(*types.ReplyHash) reply := msg.(*types.ReplyHash)
hash = reply.Hash hash = reply.Hash
} else { } else {
mainHeight := action.GetMainHeightByTxHash(action.txhash) txs := action.lottery.GetTxs()
if mainHeight < 0 { if len(txs) < action.index+1 {
llog.Error("findLuckyNum", "mainHeight", mainHeight) llog.Error("findLuckyNum", "len(txs)", len(txs), "index", action.index)
return -1 return -1
} }
req := &types.ReqRandHash{ExecName: "ticket", Height: mainHeight, BlockNum: blockNum}
msg, err := action.api.Query("paracross", "GetMainBlockHash", txs[0])
if err != nil {
return -1
}
queryReply := msg.(*types.ReplyHash)
mainBlockHash := queryReply.Hash
req := &types.ReqRandHash{ExecName: "ticket", Hash: mainBlockHash, BlockNum: blockNum}
reply, err := action.grpcClient.QueryRandNum(context.Background(), req) reply, err := action.grpcClient.QueryRandNum(context.Background(), req)
if err != nil { if err != nil {
return -1 return -1
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"strings" "strings"
"github.com/33cn/chain33/rpc/jsonclient" "github.com/33cn/chain33/rpc/jsonclient"
"github.com/33cn/chain33/system/dapp/commands"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types" pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
...@@ -162,19 +163,12 @@ func addCreateTransferFlags(cmd *cobra.Command) { ...@@ -162,19 +163,12 @@ func addCreateTransferFlags(cmd *cobra.Command) {
cmd.Flags().StringP("note", "n", "", "transaction note info") cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("title", "", "", "the title of para chain, like `p.user.guodun.`")
cmd.MarkFlagRequired("title")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token") cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token")
cmd.MarkFlagRequired("symbol")
} }
func createTransfer(cmd *cobra.Command, args []string) { func createTransfer(cmd *cobra.Command, args []string) {
txHex, err := createTransferTx(cmd, false) commands.CreateAssetTransfer(cmd, args, pt.ParaX)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(txHex)
} }
//CreateRawTransferToExecCmd create raw transfer to exec tx //CreateRawTransferToExecCmd create raw transfer to exec tx
...@@ -189,27 +183,20 @@ func CreateRawTransferToExecCmd() *cobra.Command { ...@@ -189,27 +183,20 @@ func CreateRawTransferToExecCmd() *cobra.Command {
} }
func addCreateTransferToExecFlags(cmd *cobra.Command) { func addCreateTransferToExecFlags(cmd *cobra.Command) {
cmd.Flags().StringP("to", "t", "", "receiver exec name")
cmd.MarkFlagRequired("to")
cmd.Flags().Float64P("amount", "a", 0, "transaction amount") cmd.Flags().Float64P("amount", "a", 0, "transaction amount")
cmd.MarkFlagRequired("amount") cmd.MarkFlagRequired("amount")
cmd.Flags().StringP("note", "n", "", "transaction note info") cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("title", "", "", "the title of para chain, like `p.user.guodun.`") cmd.Flags().StringP("symbol", "s", "coins.bty", "default for bty, symbol for token")
cmd.MarkFlagRequired("title") cmd.MarkFlagRequired("symbol")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token") cmd.Flags().StringP("exec", "e", "", "asset deposit exec")
cmd.MarkFlagRequired("exec")
} }
func createTransferToExec(cmd *cobra.Command, args []string) { func createTransferToExec(cmd *cobra.Command, args []string) {
txHex, err := createTransferTx(cmd, false) commands.CreateAssetSendToExec(cmd, args, pt.ParaX)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(txHex)
} }
//CreateRawWithdrawCmd create raw withdraw tx //CreateRawWithdrawCmd create raw withdraw tx
...@@ -229,59 +216,15 @@ func addCreateWithdrawFlags(cmd *cobra.Command) { ...@@ -229,59 +216,15 @@ func addCreateWithdrawFlags(cmd *cobra.Command) {
cmd.Flags().StringP("note", "n", "", "transaction note info") cmd.Flags().StringP("note", "n", "", "transaction note info")
cmd.Flags().StringP("title", "", "", "the title of para chain, like `p.user.guodun.`")
cmd.MarkFlagRequired("title")
cmd.Flags().StringP("from", "t", "", "exec name")
cmd.MarkFlagRequired("from")
cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token") cmd.Flags().StringP("symbol", "s", "", "default for bty, symbol for token")
} cmd.MarkFlagRequired("symbol")
func createWithdraw(cmd *cobra.Command, args []string) { cmd.Flags().StringP("exec", "e", "", "asset deposit exec")
txHex, err := createTransferTx(cmd, true) cmd.MarkFlagRequired("exec")
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
fmt.Println(txHex)
} }
func createTransferTx(cmd *cobra.Command, isWithdraw bool) (string, error) { func createWithdraw(cmd *cobra.Command, args []string) {
amount, _ := cmd.Flags().GetFloat64("amount") commands.CreateAssetWithdraw(cmd, args, pt.ParaX)
if amount < 0 {
return "", types.ErrAmount
}
amountInt64 := int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4
toAddr, _ := cmd.Flags().GetString("to")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
title, _ := cmd.Flags().GetString("title")
if !strings.HasPrefix(title, "user.p") {
fmt.Fprintln(os.Stderr, "title is not right, title format like `user.p.guodun.`")
return "", types.ErrInvalidParam
}
execName := title + pt.ParaX
param := types.CreateTx{
To: toAddr,
Amount: amountInt64,
Fee: 0,
Note: []byte(note),
IsWithdraw: isWithdraw,
IsToken: false,
TokenSymbol: symbol,
ExecName: execName,
}
tx, err := pt.CreateRawTransferTx(&param)
if err != nil {
return "", err
}
txHex := types.Encode(tx)
return hex.EncodeToString(txHex), nil
} }
// IsSyncCmd query parachain is sync // IsSyncCmd query parachain is sync
......
...@@ -40,6 +40,38 @@ func (p *Paracross) Query_GetAssetTxResult(in *types.ReqHash) (types.Message, er ...@@ -40,6 +40,38 @@ func (p *Paracross) Query_GetAssetTxResult(in *types.ReqHash) (types.Message, er
return p.paracrossGetAssetTxResult(in.Hash) return p.paracrossGetAssetTxResult(in.Hash)
} }
// Query_GetMainBlockHash query get mainblockHash by tx
func (p *Paracross) Query_GetMainBlockHash(in *types.Transaction) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
return p.paracrossGetMainBlockHash(in)
}
func (p *Paracross) paracrossGetMainBlockHash(tx *types.Transaction) (types.Message, error) {
var paraAction pt.ParacrossAction
err := types.Decode(tx.GetPayload(), &paraAction)
if err != nil {
return nil, err
}
if paraAction.GetTy() != pt.ParacrossActionMiner {
return nil, types.ErrCoinBaseTxType
}
if paraAction.GetMiner() == nil {
return nil, pt.ErrParaEmptyMinerTx
}
paraNodeStatus := paraAction.GetMiner().GetStatus()
if paraNodeStatus == nil {
return nil, types.ErrCoinBaseTxType
}
mainHashFromNode := paraNodeStatus.MainBlockHash
return &types.ReplyHash{Hash: mainHashFromNode}, nil
}
func (p *Paracross) paracrossGetHeight(title string) (types.Message, error) { func (p *Paracross) paracrossGetHeight(title string) (types.Message, error) {
ret, err := getTitle(p.GetStateDB(), calcTitleKey(title)) ret, err := getTitle(p.GetStateDB(), calcTitleKey(title))
if err != nil { if err != nil {
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
package types package types
import ( import (
fmt "fmt" "encoding/json"
"fmt"
"github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/log/log15" "github.com/33cn/chain33/common/log/log15"
...@@ -187,34 +188,28 @@ func CreateRawMinerTx(status *ParacrossNodeStatus) (*types.Transaction, error) { ...@@ -187,34 +188,28 @@ func CreateRawMinerTx(status *ParacrossNodeStatus) (*types.Transaction, error) {
} }
// CreateRawTransferTx create paracross asset transfer tx with transfer and withdraw // CreateRawTransferTx create paracross asset transfer tx with transfer and withdraw
func CreateRawTransferTx(param *types.CreateTx) (*types.Transaction, error) { func (p ParacrossType) CreateRawTransferTx(action string, param json.RawMessage) (*types.Transaction, error) {
if !types.IsParaExecName(param.GetExecName()) { tlog.Error("ParacrossType CreateTx failed", "action", action, "msg", string(param))
tlog.Error("CreateRawTransferTx", "exec", param.GetExecName()) tx, err := p.ExecTypeBase.CreateTx(action, param)
return nil, types.ErrInvalidParam if err != nil {
} tlog.Error("ParacrossType CreateTx failed", "err", err, "action", action, "msg", string(param))
return nil, err
transfer := &ParacrossAction{}
if !param.IsWithdraw {
v := &ParacrossAction_Transfer{Transfer: &types.AssetsTransfer{
Amount: param.Amount, Note: param.GetNote(), To: param.GetTo(), Cointoken: param.TokenSymbol}}
transfer.Value = v
transfer.Ty = ParacrossActionTransfer
} else {
v := &ParacrossAction_Withdraw{Withdraw: &types.AssetsWithdraw{
Amount: param.Amount, Note: param.GetNote(), To: param.GetTo(), Cointoken: param.TokenSymbol}}
transfer.Value = v
transfer.Ty = ParacrossActionWithdraw
}
tx := &types.Transaction{
Execer: []byte(param.GetExecName()),
Payload: types.Encode(transfer),
To: address.ExecAddress(param.GetExecName()),
Fee: param.Fee,
} }
var err error if !types.IsPara() {
tx, err = types.FormatTx(param.GetExecName(), tx) var transfer ParacrossAction
err = types.Decode(tx.Payload, &transfer)
if err != nil { if err != nil {
tlog.Error("ParacrossType CreateTx failed", "decode payload err", err, "action", action, "msg", string(param))
return nil, err return nil, err
} }
if action == "Transfer" {
tx.To = transfer.GetTransfer().To
} else if action == "Withdraw" {
tx.To = transfer.GetWithdraw().To
} else if action == "TransferToExec" {
tx.To = transfer.GetTransferToExec().To
}
}
return tx, nil return tx, nil
} }
...@@ -98,15 +98,16 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types. ...@@ -98,15 +98,16 @@ func (p ParacrossType) CreateTx(action string, message json.RawMessage) (*types.
} }
return CreateRawAssetTransferTx(&param) return CreateRawAssetTransferTx(&param)
} else if action == "ParacrossTransfer" || action == "ParacrossWithdraw" || action == "ParacrossTransferToExec" { } else if action == "ParacrossTransfer" || action == "Transfer" ||
action == "ParacrossWithdraw" || action == "Withdraw" ||
action == "ParacrossTransferToExec" || action == "TransferToExec" {
var param types.CreateTx var param types.CreateTx
err := json.Unmarshal(message, &param) err := json.Unmarshal(message, &param)
if err != nil { if err != nil {
glog.Error("CreateTx", "Error", err) glog.Error("CreateTx", "Error", err)
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
return CreateRawTransferTx(&param) return p.CreateRawTransferTx(action, message)
} }
return nil, types.ErrNotSupport return nil, types.ErrNotSupport
......
...@@ -28,6 +28,7 @@ func PokerBullCmd() *cobra.Command { ...@@ -28,6 +28,7 @@ func PokerBullCmd() *cobra.Command {
PokerBullContinueRawTxCmd(), PokerBullContinueRawTxCmd(),
PokerBullQuitRawTxCmd(), PokerBullQuitRawTxCmd(),
PokerBullQueryResultRawTxCmd(), PokerBullQueryResultRawTxCmd(),
PokerBullPlayRawTxCmd(),
) )
return cmd return cmd
...@@ -45,7 +46,7 @@ func PokerBullStartRawTxCmd() *cobra.Command { ...@@ -45,7 +46,7 @@ func PokerBullStartRawTxCmd() *cobra.Command {
} }
func addPokerbullStartFlags(cmd *cobra.Command) { func addPokerbullStartFlags(cmd *cobra.Command) {
cmd.Flags().Uint64P("value", "a", 0, "value") cmd.Flags().Uint64P("value", "v", 0, "value")
cmd.MarkFlagRequired("value") cmd.MarkFlagRequired("value")
cmd.Flags().Uint32P("playerCount", "p", 0, "player count") cmd.Flags().Uint32P("playerCount", "p", 0, "player count")
...@@ -121,7 +122,7 @@ func pokerbullQuit(cmd *cobra.Command, args []string) { ...@@ -121,7 +122,7 @@ func pokerbullQuit(cmd *cobra.Command, args []string) {
params := &rpctypes.CreateTxIn{ params := &rpctypes.CreateTxIn{
Execer: types.ExecName(pkt.PokerBullX), Execer: types.ExecName(pkt.PokerBullX),
ActionName: pkt.CreatequitTx, ActionName: pkt.CreateQuitTx,
Payload: []byte(fmt.Sprintf("{\"gameId\":\"%s\"}", gameID)), Payload: []byte(fmt.Sprintf("{\"gameId\":\"%s\"}", gameID)),
} }
...@@ -130,6 +131,54 @@ func pokerbullQuit(cmd *cobra.Command, args []string) { ...@@ -130,6 +131,54 @@ func pokerbullQuit(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal() ctx.RunWithoutMarshal()
} }
// PokerBullPlayRawTxCmd 生成已匹配玩家游戏命令行
func PokerBullPlayRawTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "play",
Short: "Play game",
Run: pokerbullPlay,
}
addPokerbullPlayFlags(cmd)
return cmd
}
func addPokerbullPlayFlags(cmd *cobra.Command) {
cmd.Flags().StringP("gameID", "g", "", "game ID")
cmd.MarkFlagRequired("gameID")
cmd.Flags().Uint32P("round", "r", 0, "round")
cmd.MarkFlagRequired("round")
cmd.Flags().Uint64P("value", "v", 0, "value")
cmd.MarkFlagRequired("value")
cmd.Flags().StringArrayP("address", "a", nil, "address")
cmd.MarkFlagRequired("address")
}
func pokerbullPlay(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
gameID, _ := cmd.Flags().GetString("gameID")
round, _ := cmd.Flags().GetUint32("round")
value, _ := cmd.Flags().GetUint64("value")
address, _ := cmd.Flags().GetStringArray("address")
payload := &pkt.PBGamePlay{
GameId: gameID,
Value: int64(value) * types.Coin,
Round: int32(round),
}
payload.Address = make([]string, len(address))
copy(payload.Address, address)
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(pkt.PokerBullX),
ActionName: pkt.CreatePlayTx,
Payload: types.MustPBToJSON(payload),
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, &res)
ctx.RunWithoutMarshal()
}
// PokerBullQueryResultRawTxCmd 查询命令行 // PokerBullQueryResultRawTxCmd 查询命令行
func PokerBullQueryResultRawTxCmd() *cobra.Command { func PokerBullQueryResultRawTxCmd() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
......
...@@ -26,3 +26,9 @@ func (c *PokerBull) Exec_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, in ...@@ -26,3 +26,9 @@ func (c *PokerBull) Exec_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, in
action := NewAction(c, tx, index) action := NewAction(c, tx, index)
return action.GameQuit(payload) return action.GameQuit(payload)
} }
// Exec_Play 已匹配玩家直接开始游戏
func (c *PokerBull) Exec_Play(payload *pkt.PBGamePlay, tx *types.Transaction, index int) (*types.Receipt, error) {
action := NewAction(c, tx, index)
return action.GamePlay(payload)
}
...@@ -57,7 +57,7 @@ func (c *PokerBull) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, er ...@@ -57,7 +57,7 @@ func (c *PokerBull) execLocal(receipt *types.ReceiptData) (*types.LocalDBSet, er
dbSet := &types.LocalDBSet{} dbSet := &types.LocalDBSet{}
for i := 0; i < len(receipt.Logs); i++ { for i := 0; i < len(receipt.Logs); i++ {
item := receipt.Logs[i] item := receipt.Logs[i]
if item.Ty == pkt.TyLogPBGameStart || item.Ty == pkt.TyLogPBGameContinue || item.Ty == pkt.TyLogPBGameQuit { if item.Ty == pkt.TyLogPBGameStart || item.Ty == pkt.TyLogPBGameContinue || item.Ty == pkt.TyLogPBGameQuit || item.Ty == pkt.TyLogPBGamePlay {
var Gamelog pkt.ReceiptPBGame var Gamelog pkt.ReceiptPBGame
err := types.Decode(item.Log, &Gamelog) err := types.Decode(item.Log, &Gamelog)
if err != nil { if err != nil {
...@@ -84,3 +84,8 @@ func (c *PokerBull) ExecLocal_Continue(payload *pkt.PBGameContinue, tx *types.Tr ...@@ -84,3 +84,8 @@ func (c *PokerBull) ExecLocal_Continue(payload *pkt.PBGameContinue, tx *types.Tr
func (c *PokerBull) ExecLocal_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (c *PokerBull) ExecLocal_Quit(payload *pkt.PBGameQuit, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return c.execLocal(receiptData) return c.execLocal(receiptData)
} }
// ExecLocal_Play 已匹配游戏交易local执行
func (c *PokerBull) ExecLocal_Play(payload *pkt.PBGamePlay, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return c.execLocal(receiptData)
}
...@@ -5,11 +5,13 @@ ...@@ -5,11 +5,13 @@
package executor package executor
import ( import (
"errors"
"fmt" "fmt"
"sort" "sort"
"strconv" "strconv"
"strings"
"time"
"github.com/33cn/chain33/account" "github.com/33cn/chain33/account"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db" dbm "github.com/33cn/chain33/common/db"
...@@ -183,6 +185,8 @@ func (action *Action) GetReceiptLog(game *pkt.PokerBull) *types.ReceiptLog { ...@@ -183,6 +185,8 @@ func (action *Action) GetReceiptLog(game *pkt.PokerBull) *types.ReceiptLog {
log.Ty = pkt.TyLogPBGameContinue log.Ty = pkt.TyLogPBGameContinue
} else if game.Status == pkt.PBGameActionQuit { } else if game.Status == pkt.PBGameActionQuit {
log.Ty = pkt.TyLogPBGameQuit log.Ty = pkt.TyLogPBGameQuit
} else if game.Status == pkt.PBGameActionPlay {
log.Ty = pkt.TyLogPBGamePlay
} }
r.GameId = game.GameId r.GameId = game.GameId
...@@ -327,11 +331,11 @@ func (action *Action) settleDealerAccount(lastAddress string, game *pkt.PokerBul ...@@ -327,11 +331,11 @@ func (action *Action) settleDealerAccount(lastAddress string, game *pkt.PokerBul
result := action.calculateDealer(game) result := action.calculateDealer(game)
for _, hand := range result.Hands { for _, hand := range result.Hands {
// 最后一名玩家没有冻结 // 最后一名玩家没有冻结
if hand.Address != lastAddress { if lastAddress != "" && hand.Address != lastAddress {
receipt, err := action.coinsAccount.ExecActive(hand.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax) receipt, err := action.coinsAccount.ExecActive(hand.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax)
if err != nil { if err != nil {
logger.Error("GameSettleDealer.ExecActive", "addr", hand.Address, "execaddr", action.execaddr, "amount", game.GetValue(), logger.Error("GameSettleDealer.ExecActive", "GameID", game.GetGameId(), "addr", hand.Address,
"err", err) "execaddr", action.execaddr, "amount", game.GetValue(), "err", err)
return nil, nil, err return nil, nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -346,16 +350,16 @@ func (action *Action) settleDealerAccount(lastAddress string, game *pkt.PokerBul ...@@ -346,16 +350,16 @@ func (action *Action) settleDealerAccount(lastAddress string, game *pkt.PokerBul
receipt, err = action.coinsAccount.ExecTransfer(result.Dealer, hand.Address, action.execaddr, game.GetValue()*int64(hand.Leverage)) receipt, err = action.coinsAccount.ExecTransfer(result.Dealer, hand.Address, action.execaddr, game.GetValue()*int64(hand.Leverage))
if err != nil { if err != nil {
action.coinsAccount.ExecFrozen(hand.Address, action.execaddr, game.GetValue()) // rollback action.coinsAccount.ExecFrozen(hand.Address, action.execaddr, game.GetValue()) // rollback
logger.Error("GameSettleDealer.ExecTransfer", "addr", hand.Address, "execaddr", action.execaddr, logger.Error("GameSettleDealer.ExecTransfer", "GameID", game.GetGameId(), "addr", hand.Address,
"amount", game.GetValue()*int64(hand.Leverage), "err", err) "execaddr", action.execaddr, "amount", game.GetValue()*int64(hand.Leverage), "err", err)
return nil, nil, err return nil, nil, err
} }
} else { } else {
receipt, err = action.coinsAccount.ExecTransfer(hand.Address, result.Dealer, action.execaddr, game.GetValue()*int64(result.DealerLeverage)) receipt, err = action.coinsAccount.ExecTransfer(hand.Address, result.Dealer, action.execaddr, game.GetValue()*int64(result.DealerLeverage))
if err != nil { if err != nil {
action.coinsAccount.ExecFrozen(hand.Address, action.execaddr, game.GetValue()) // rollback action.coinsAccount.ExecFrozen(hand.Address, action.execaddr, game.GetValue()) // rollback
logger.Error("GameSettleDealer.ExecTransfer", "addr", hand.Address, "execaddr", action.execaddr, logger.Error("GameSettleDealer.ExecTransfer", "GameID", game.GetGameId(), "addr", hand.Address,
"amount", game.GetValue()*int64(result.DealerLeverage), "err", err) "execaddr", action.execaddr, "amount", game.GetValue()*int64(result.DealerLeverage), "err", err)
return nil, nil, err return nil, nil, err
} }
} }
...@@ -375,11 +379,11 @@ func (action *Action) settleDefaultAccount(lastAddress string, game *pkt.PokerBu ...@@ -375,11 +379,11 @@ func (action *Action) settleDefaultAccount(lastAddress string, game *pkt.PokerBu
for _, player := range game.Players { for _, player := range game.Players {
// 最后一名玩家没有冻结 // 最后一名玩家没有冻结
if player.Address != lastAddress { if lastAddress != "" && player.Address != lastAddress {
receipt, err := action.coinsAccount.ExecActive(player.GetAddress(), action.execaddr, game.GetValue()*PokerbullLeverageMax) receipt, err := action.coinsAccount.ExecActive(player.GetAddress(), action.execaddr, game.GetValue()*PokerbullLeverageMax)
if err != nil { if err != nil {
logger.Error("GameSettleDefault.ExecActive", "addr", player.GetAddress(), "execaddr", action.execaddr, logger.Error("GameSettleDefault.ExecActive", "GameID", game.GetGameId(), "addr", player.GetAddress(),
"amount", game.GetValue()*PokerbullLeverageMax, "err", err) "execaddr", action.execaddr, "amount", game.GetValue()*PokerbullLeverageMax, "err", err)
return nil, nil, err return nil, nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -391,8 +395,8 @@ func (action *Action) settleDefaultAccount(lastAddress string, game *pkt.PokerBu ...@@ -391,8 +395,8 @@ func (action *Action) settleDefaultAccount(lastAddress string, game *pkt.PokerBu
receipt, err := action.coinsAccount.ExecTransfer(player.Address, result.Winner, action.execaddr, game.GetValue() /**int64(result.Leverage)*/) //TODO Dealer:暂时不支持倍数 receipt, err := action.coinsAccount.ExecTransfer(player.Address, result.Winner, action.execaddr, game.GetValue() /**int64(result.Leverage)*/) //TODO Dealer:暂时不支持倍数
if err != nil { if err != nil {
action.coinsAccount.ExecFrozen(result.Winner, action.execaddr, game.GetValue()) // rollback action.coinsAccount.ExecFrozen(result.Winner, action.execaddr, game.GetValue()) // rollback
logger.Error("GameSettleDefault.ExecTransfer", "addr", result.Winner, "execaddr", action.execaddr, logger.Error("GameSettleDefault.ExecTransfer", "GameID", game.GetGameId(), "addr", result.Winner,
"amount", game.GetValue() /**int64(result.Leverage)*/, "err", err) //TODO Dealer:暂时不支持倍数 "execaddr", action.execaddr, "amount", game.GetValue() /**int64(result.Leverage)*/, "err", err) //TODO Dealer:暂时不支持倍数
return nil, nil, err return nil, nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -438,8 +442,8 @@ func (action *Action) settleAccount(lastAddress string, game *pkt.PokerBull) ([] ...@@ -438,8 +442,8 @@ func (action *Action) settleAccount(lastAddress string, game *pkt.PokerBull) ([]
} }
func (action *Action) genTxRnd(txhash []byte) (int64, error) { func (action *Action) genTxRnd(txhash []byte) (int64, error) {
randbyte := make([]byte, 7) randbyte := make([]byte, 6)
for i := 0; i < 7; i++ { for i := 0; i < 6; i++ {
randbyte[i] = txhash[i] randbyte[i] = txhash[i]
} }
...@@ -452,15 +456,35 @@ func (action *Action) genTxRnd(txhash []byte) (int64, error) { ...@@ -452,15 +456,35 @@ func (action *Action) genTxRnd(txhash []byte) (int64, error) {
return randint, nil return randint, nil
} }
func (action *Action) checkDupPlayerAddress(id string, pbPlayers []*pkt.PBPlayer) error { func (action *Action) genTxRnds(txhash []byte, playnum int32) ([]int64, error) {
rands := make([]int64, playnum)
for i := 0; i < int(playnum); i++ {
randbyte := make([]byte, 6)
for j := 0; j < 6; j++ {
randbyte[j] = txhash[i*6+j]
}
randstr := common.ToHex(randbyte)
randint, err := strconv.ParseInt(randstr, 0, 64)
if err != nil {
return nil, err
}
rands[i] = randint
}
return rands, nil
}
func (action *Action) checkPlayerAddressExist(pbPlayers []*pkt.PBPlayer) bool {
for _, player := range pbPlayers { for _, player := range pbPlayers {
if action.fromaddr == player.Address { if action.fromaddr == player.Address {
logger.Error("Poker bull game start", "addr", action.fromaddr, "execaddr", action.execaddr, "Already in a game", id) return true
return errors.New("Address is already in a game")
} }
} }
return nil return false
} }
// 新建一局游戏 // 新建一局游戏
...@@ -475,8 +499,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker ...@@ -475,8 +499,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker
//TODO 庄家检查闲家数量倍数的资金 //TODO 庄家检查闲家数量倍数的资金
if pkt.DefaultStyle == pkt.PlayStyleDealer { if pkt.DefaultStyle == pkt.PlayStyleDealer {
if !action.CheckExecAccountBalance(action.fromaddr, start.GetValue()*PokerbullLeverageMax*int64(start.PlayerNum-1), 0) { if !action.CheckExecAccountBalance(action.fromaddr, start.GetValue()*PokerbullLeverageMax*int64(start.PlayerNum-1), 0) {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, "id", logger.Error("GameStart", "GameID", gameID, "addr", action.fromaddr, "execaddr", action.execaddr, "err", types.ErrNoBalance)
gameID, "err", types.ErrNoBalance)
return nil, types.ErrNoBalance return nil, types.ErrNoBalance
} }
} }
...@@ -484,7 +507,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker ...@@ -484,7 +507,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker
game = &pkt.PokerBull{ game = &pkt.PokerBull{
GameId: gameID, GameId: gameID,
Status: pkt.PBGameActionStart, Status: pkt.PBGameActionStart,
StartTime: action.blocktime, StartTime: time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05"),
StartTxHash: gameID, StartTxHash: gameID,
Value: start.GetValue(), Value: start.GetValue(),
Poker: NewPoker(), Poker: NewPoker(),
...@@ -497,7 +520,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker ...@@ -497,7 +520,7 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker
} }
Shuffle(game.Poker, action.blocktime) //洗牌 Shuffle(game.Poker, action.blocktime) //洗牌
logger.Debug(fmt.Sprintf("Start a new game %s for player %s", game.GameId, action.fromaddr)) logger.Info(fmt.Sprintf("Create a new game %s for player %s", game.GameId, action.fromaddr))
return game, nil return game, nil
} }
...@@ -505,27 +528,37 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker ...@@ -505,27 +528,37 @@ func (action *Action) newGame(gameID string, start *pkt.PBGameStart) (*pkt.Poker
// 筛选合适的牌局 // 筛选合适的牌局
func (action *Action) selectGameFromIds(ids []string, value int64) *pkt.PokerBull { func (action *Action) selectGameFromIds(ids []string, value int64) *pkt.PokerBull {
var gameRet *pkt.PokerBull var gameRet *pkt.PokerBull
for _, id := range ids { for num := len(ids) - 1; num > -1; num-- {
id := ids[num]
game, err := action.readGame(id) game, err := action.readGame(id)
if err != nil { if err != nil {
logger.Error("Poker bull game start", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed", id, "err", err) logger.Error("Poker bull game start", "GameID", id, "addr", action.fromaddr, "execaddr", action.execaddr,
"get game failed", "err", err)
continue
}
// 玩家已经满了,不需要再匹配(防止多交易在同一区块没有刷新localdb的场景)
if int32(len(game.Players)) == game.PlayerNum {
continue continue
} }
//不能自己和自己玩 //不能自己和自己玩
if action.checkDupPlayerAddress(id, game.Players) != nil { if action.checkPlayerAddressExist(game.Players) {
logger.Info(fmt.Sprintf("Player %s already exist in game %s", action.fromaddr, id))
continue continue
} }
//选择合适赌注的游戏 //选择合适赌注的游戏
if value == 0 && game.GetValue() != pkt.MinPlayValue { if value == 0 && game.GetValue() != pkt.MinPlayValue {
if !action.CheckExecAccountBalance(action.fromaddr, game.GetValue(), 0) { if !action.CheckExecAccountBalance(action.fromaddr, game.GetValue(), 0) {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, "id", id, "err", types.ErrNoBalance) logger.Error("GameStart", "GameID", id, "addr", action.fromaddr, "execaddr", action.execaddr,
"err", types.ErrNoBalance)
continue continue
} }
} }
gameRet = game gameRet = game
logger.Info(fmt.Sprintf("Match a new game %s for player %s", id, action.fromaddr))
break break
} }
return gameRet return gameRet
...@@ -554,7 +587,7 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error) ...@@ -554,7 +587,7 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error)
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
logger.Debug(fmt.Sprintf("Pokerbull game start for %s", action.fromaddr)) logger.Info(fmt.Sprintf("Pokerbull game match for %s", action.fromaddr))
if start.PlayerNum > pkt.MaxPlayerNum { if start.PlayerNum > pkt.MaxPlayerNum {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr,
"err", fmt.Sprintf("The maximum player number is %d", pkt.MaxPlayerNum)) "err", fmt.Sprintf("The maximum player number is %d", pkt.MaxPlayerNum))
...@@ -563,7 +596,7 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error) ...@@ -563,7 +596,7 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error)
gameID := common.ToHex(action.txhash) gameID := common.ToHex(action.txhash)
if !action.CheckExecAccountBalance(action.fromaddr, start.GetValue()*PokerbullLeverageMax, 0) { if !action.CheckExecAccountBalance(action.fromaddr, start.GetValue()*PokerbullLeverageMax, 0) {
logger.Error("GameStart", "addr", action.fromaddr, "execaddr", action.execaddr, "id", gameID, "err", types.ErrNoBalance) logger.Error("GameStart", "GameID", gameID, "addr", action.fromaddr, "execaddr", action.execaddr, "err", types.ErrNoBalance)
return nil, types.ErrNoBalance return nil, types.ErrNoBalance
} }
...@@ -593,7 +626,6 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error) ...@@ -593,7 +626,6 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error)
return nil, err return nil, err
} }
} }
logger.Debug(fmt.Sprintf("Match a new game %s for player %s", game.GameId, game.GameId))
} }
//发牌随机数取txhash //发牌随机数取txhash
...@@ -607,11 +639,12 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error) ...@@ -607,11 +639,12 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error)
Address: action.fromaddr, Address: action.fromaddr,
TxHash: txrng, TxHash: txrng,
Ready: false, Ready: false,
MatchTime: time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05"),
}) })
// 如果人数达标,则发牌计算斗牛结果 // 如果人数达标,则发牌计算斗牛结果
if len(game.Players) == int(game.PlayerNum) { if len(game.Players) == int(game.PlayerNum) {
logger.Debug(fmt.Sprintf("Game start: %s", game.GameId)) logger.Info(fmt.Sprintf("Game starting: %s round: %d", game.GameId, game.Round))
logsH, kvH, err := action.settleAccount(action.fromaddr, game) logsH, kvH, err := action.settleAccount(action.fromaddr, game)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -625,10 +658,11 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error) ...@@ -625,10 +658,11 @@ func (action *Action) GameStart(start *pkt.PBGameStart) (*types.Receipt, error)
game.PreStatus = pkt.PBGameActionStart game.PreStatus = pkt.PBGameActionStart
game.IsWaiting = false game.IsWaiting = false
} else { } else {
logger.Debug(fmt.Sprintf("Game waiting: %s", game.GameId)) logger.Info(fmt.Sprintf("Game waiting: %s round: %d", game.GameId, game.Round))
receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, start.GetValue()*PokerbullLeverageMax) //冻结子账户资金, 最后一位玩家不需要冻结 receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, start.GetValue()*PokerbullLeverageMax) //冻结子账户资金, 最后一位玩家不需要冻结
if err != nil { if err != nil {
logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", start.GetValue(), "err", err.Error()) logger.Error("GameCreate.ExecFrozen", "GameID", gameID, "addr", action.fromaddr, "execaddr", action.execaddr,
"amount", start.GetValue(), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -667,17 +701,17 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei ...@@ -667,17 +701,17 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei
game, err := action.readGame(pbcontinue.GetGameId()) game, err := action.readGame(pbcontinue.GetGameId())
if err != nil { if err != nil {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed, gameID", logger.Error("GameContinue", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr, "execaddr",
pbcontinue.GetGameId(), "err", err) action.execaddr, "get game failed", "err", err)
return nil, err return nil, err
} }
if game.Status != pkt.PBGameActionContinue { if game.Status != pkt.PBGameActionContinue {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "Status error, gameID", logger.Error("GameContinue", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr, "execaddr",
pbcontinue.GetGameId()) action.execaddr, "Status error")
return nil, err return nil, err
} }
logger.Debug(fmt.Sprintf("Pokerbull game %s continue for %s", game.GameId, action.fromaddr)) logger.Info(fmt.Sprintf("Continue pokerbull game %s from %s", game.GameId, action.fromaddr))
// 检查余额,庄家检查闲家数量倍数的资金 // 检查余额,庄家检查闲家数量倍数的资金
checkValue := game.GetValue() * PokerbullLeverageMax checkValue := game.GetValue() * PokerbullLeverageMax
...@@ -685,21 +719,21 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei ...@@ -685,21 +719,21 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei
checkValue = checkValue * int64(game.PlayerNum-1) checkValue = checkValue * int64(game.PlayerNum-1)
} }
if !action.CheckExecAccountBalance(action.fromaddr, checkValue, 0) { if !action.CheckExecAccountBalance(action.fromaddr, checkValue, 0) {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "id", logger.Error("GameContinue", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr, "execaddr",
pbcontinue.GetGameId(), "err", types.ErrNoBalance) action.execaddr, "err", types.ErrNoBalance)
return nil, types.ErrNoBalance return nil, types.ErrNoBalance
} }
// 寻找对应玩家 // 寻找对应玩家
pbplayer := getPlayerFromAddress(game.Players, action.fromaddr) pbplayer := getPlayerFromAddress(game.Players, action.fromaddr)
if pbplayer == nil { if pbplayer == nil {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "get game player failed", logger.Error("GameContinue", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr, "execaddr",
pbcontinue.GetGameId(), "err", types.ErrNotFound) action.execaddr, "get game player failed", "err", types.ErrNotFound)
return nil, types.ErrNotFound return nil, types.ErrNotFound
} }
if pbplayer.Ready { if pbplayer.Ready {
logger.Error("GameContinue", "addr", action.fromaddr, "execaddr", action.execaddr, "player has been ready", logger.Error("GameContinue", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr, "execaddr",
pbcontinue.GetGameId(), "player", pbplayer.Address) action.execaddr, "player has been ready")
return nil, fmt.Errorf("player %s has been ready", pbplayer.Address) return nil, fmt.Errorf("player %s has been ready", pbplayer.Address)
} }
...@@ -710,9 +744,10 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei ...@@ -710,9 +744,10 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei
} }
pbplayer.TxHash = txrng pbplayer.TxHash = txrng
pbplayer.Ready = true pbplayer.Ready = true
pbplayer.MatchTime = time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05")
if getReadyPlayerNum(game.Players) == int(game.PlayerNum) { if getReadyPlayerNum(game.Players) == int(game.PlayerNum) {
logger.Debug(fmt.Sprintf("Game start: %s", game.GameId)) logger.Info(fmt.Sprintf("Game starting: %s round: %d", game.GameId, game.Round))
logsH, kvH, err := action.settleAccount(action.fromaddr, game) logsH, kvH, err := action.settleAccount(action.fromaddr, game)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -724,14 +759,15 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei ...@@ -724,14 +759,15 @@ func (action *Action) GameContinue(pbcontinue *pkt.PBGameContinue) (*types.Recei
game.IsWaiting = false game.IsWaiting = false
game.PreStatus = pkt.PBGameActionContinue game.PreStatus = pkt.PBGameActionContinue
} else { } else {
logger.Debug(fmt.Sprintf("Game waiting: %s", game.GameId)) logger.Info(fmt.Sprintf("Game waiting: %s round: %d", game.GameId, game.Round))
// 回合数加一次 // 回合数加一次
if !game.IsWaiting { if !game.IsWaiting {
game.Round++ game.Round++
} }
receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, game.GetValue()*PokerbullLeverageMax) //冻结子账户资金,最后一位玩家不需要冻结 receipt, err := action.coinsAccount.ExecFrozen(action.fromaddr, action.execaddr, game.GetValue()*PokerbullLeverageMax) //冻结子账户资金,最后一位玩家不需要冻结
if err != nil { if err != nil {
logger.Error("GameCreate.ExecFrozen", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", game.GetValue(), "err", err.Error()) logger.Error("GameCreate.ExecFrozen", "GameID", pbcontinue.GetGameId(), "addr", action.fromaddr,
"execaddr", action.execaddr, "amount", game.GetValue(), "err", err.Error())
return nil, err return nil, err
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -751,21 +787,35 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) { ...@@ -751,21 +787,35 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) {
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
var kv []*types.KeyValue var kv []*types.KeyValue
logger.Info(fmt.Sprintf("Quit pokerbull game %s", pbend.GameId))
game, err := action.readGame(pbend.GetGameId()) game, err := action.readGame(pbend.GetGameId())
if err != nil { if err != nil {
logger.Error("GameEnd", "addr", action.fromaddr, "execaddr", action.execaddr, "get game failed", logger.Error("GameEnd", "GameID", pbend.GetGameId(), "addr", action.fromaddr, "execaddr",
pbend.GetGameId(), "err", err) action.execaddr, "get game failed", "err", err)
return nil, err return nil, err
} }
if game.Status == pkt.PBGameActionQuit {
logger.Error("Quit pokerbull game", "GameID", pbend.GetGameId(), "value", game.Value, "err", "already game over")
return nil, fmt.Errorf("already game over")
}
if !action.checkPlayerAddressExist(game.Players) {
if action.fromaddr != pkt.PlatformSignAddress {
logger.Error("GameEnd", "GameID", pbend.GetGameId(), "addr", action.fromaddr, "execaddr",
action.execaddr, "err", "permission denied")
return nil, fmt.Errorf("permission denied")
}
}
// 如果游戏没有开始,激活冻结账户 // 如果游戏没有开始,激活冻结账户
if game.IsWaiting { if game.IsWaiting {
if game.Status == pkt.PBGameActionStart { if game.Status == pkt.PBGameActionStart {
for _, player := range game.Players { for _, player := range game.Players {
receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax) receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax)
if err != nil { if err != nil {
logger.Error("GameSettleDealer.ExecActive", "addr", player.Address, "execaddr", action.execaddr, "amount", game.GetValue(), logger.Error("GameSettleDealer.ExecActive", "GameID", pbend.GetGameId(), "addr", player.Address,
"err", err) "execaddr", action.execaddr, "amount", game.GetValue(), "err", err)
continue continue
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -779,8 +829,8 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) { ...@@ -779,8 +829,8 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) {
receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax) receipt, err := action.coinsAccount.ExecActive(player.Address, action.execaddr, game.GetValue()*PokerbullLeverageMax)
if err != nil { if err != nil {
logger.Error("GameSettleDealer.ExecActive", "addr", player.Address, "execaddr", action.execaddr, "amount", game.GetValue(), logger.Error("GameSettleDealer.ExecActive", "GameID", pbend.GetGameId(), "addr", player.Address,
"err", err) "execaddr", action.execaddr, "amount", game.GetValue(), "err", err)
continue continue
} }
logs = append(logs, receipt.Logs...) logs = append(logs, receipt.Logs...)
...@@ -793,12 +843,129 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) { ...@@ -793,12 +843,129 @@ func (action *Action) GameQuit(pbend *pkt.PBGameQuit) (*types.Receipt, error) {
game.Status = pkt.PBGameActionQuit game.Status = pkt.PBGameActionQuit
game.PrevIndex = game.Index game.PrevIndex = game.Index
game.Index = action.getIndex(game) game.Index = action.getIndex(game)
game.QuitTime = action.blocktime game.QuitTime = time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05")
game.QuitTxHash = common.ToHex(action.txhash)
receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
}
// GamePlay 已匹配玩家直接游戏
func (action *Action) GamePlay(pbplay *pkt.PBGamePlay) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
logger.Info(fmt.Sprintf("Play pokerbull game %s, player:%s", pbplay.GameId, strings.Join(pbplay.Address, ",")))
// 校验签名地址
if action.fromaddr != pkt.PlatformSignAddress {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", "permission denied")
return nil, fmt.Errorf("game signing address not support")
}
// 检查玩家人数
if len(pbplay.Address) < pkt.MinPlayerNum || len(pbplay.Address) > pkt.MaxPlayerNum {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", "invalid player number")
return nil, fmt.Errorf("Invalid player number")
}
// 检查玩家地址余额
for _, addr := range pbplay.Address {
if !action.CheckExecAccountBalance(addr, pbplay.GetValue()*PokerbullLeverageMax, 0) {
logger.Error("GamePlay", "addr", addr, "execaddr", action.execaddr, "id", pbplay.GetGameId(), "err", types.ErrNoBalance)
return nil, types.ErrNoBalance
}
}
// 游戏存在则校验游戏状态,不存在则创建游戏
game, _ := action.readGame(pbplay.GetGameId())
if game != nil {
if game.Status == pkt.PBGameActionQuit {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", "already game over")
return nil, fmt.Errorf("already game over")
}
if game.Round+1 != pbplay.Round {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", "game round error")
return nil, fmt.Errorf("game round error")
}
if game.Value != pbplay.Value {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", "game value error")
return nil, fmt.Errorf("game value error")
}
// 获取发牌随机数
rands, err := action.genTxRnds(action.txhash, game.PlayerNum)
if err != nil {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", err)
return nil, err
}
// 更新玩家信息
for i, player := range game.Players {
player.TxHash = rands[i]
player.MatchTime = time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05")
}
game.Round++
game.Status = pkt.PBGameActionContinue // 更新游戏状态
game.PreStatus = pkt.PBGameActionContinue
} else {
gameNew, err := action.newGame(pbplay.GameId, &pkt.PBGameStart{Value: pbplay.Value, PlayerNum: int32(len(pbplay.Address))})
if err != nil {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", err)
return nil, err
}
game = gameNew
// 获取发牌随机数
rands, err := action.genTxRnds(action.txhash, game.PlayerNum)
if err != nil {
logger.Error("Pokerbull game play", "GameID", pbplay.GetGameId(), "round", pbplay.Round, "value",
pbplay.Value, "players", strings.Join(pbplay.Address, ","), "err", err)
return nil, err
}
// 创建玩家信息
for i, addr := range pbplay.Address {
player := &pkt.PBPlayer{
Address: addr,
TxHash: rands[i],
MatchTime: time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05"),
}
game.Players = append(game.Players, player)
}
game.Status = pkt.PBGameActionQuit // 更新游戏状态
game.PreStatus = pkt.PBGameActionStart
game.QuitTime = time.Unix(action.blocktime, 0).Format("2006-01-02 15:04:05")
game.QuitTxHash = common.ToHex(action.txhash) game.QuitTxHash = common.ToHex(action.txhash)
}
logger.Info(fmt.Sprintf("Game starting: %s round: %d", game.GameId, game.Round))
logsH, kvH, err := action.settleAccount("", game)
if err != nil {
return nil, err
}
logs = append(logs, logsH...)
kv = append(kv, kvH...)
game.PrevIndex = game.Index
game.Index = action.getIndex(game)
game.IsWaiting = false
receiptLog := action.GetReceiptLog(game) receiptLog := action.GetReceiptLog(game)
logs = append(logs, receiptLog) logs = append(logs, receiptLog)
kv = append(kv, action.saveGame(game)...) kv = append(kv, action.saveGame(game)...)
return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil return &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}, nil
} }
......
...@@ -6,7 +6,7 @@ package types; ...@@ -6,7 +6,7 @@ package types;
message PokerBull { message PokerBull {
string gameId = 1; //默认是由创建这局游戏的txHash作为gameId string gameId = 1; //默认是由创建这局游戏的txHash作为gameId
int32 status = 2; // Start 1 -> Continue 2 -> Quit 3 int32 status = 2; // Start 1 -> Continue 2 -> Quit 3
int64 startTime = 3; //开始时间 string startTime = 3; //开始时间
string startTxHash = 4; //游戏启动交易hash string startTxHash = 4; //游戏启动交易hash
int64 value = 5; //赌注 int64 value = 5; //赌注
PBPoker poker = 6; //扑克牌 PBPoker poker = 6; //扑克牌
...@@ -15,7 +15,7 @@ message PokerBull { ...@@ -15,7 +15,7 @@ message PokerBull {
repeated PBResult results = 9; //游戏结果集 repeated PBResult results = 9; //游戏结果集
int64 index = 10; //索引 int64 index = 10; //索引
int64 prevIndex = 11; //上级索引 int64 prevIndex = 11; //上级索引
int64 quitTime = 12; //游戏结束时间 string quitTime = 12; //游戏结束时间
string quitTxHash = 13; //游戏结束交易hash string quitTxHash = 13; //游戏结束交易hash
string dealerAddr = 14; //下局庄家地址 string dealerAddr = 14; //下局庄家地址
bool isWaiting = 15; //游戏是否处于等待状态 bool isWaiting = 15; //游戏是否处于等待状态
...@@ -30,6 +30,7 @@ message PBHand { ...@@ -30,6 +30,7 @@ message PBHand {
string address = 3; //玩家地址 string address = 3; //玩家地址
bool isWin = 4; //是否赢庄家 bool isWin = 4; //是否赢庄家
int32 leverage = 5; //赌注倍数 int32 leverage = 5; //赌注倍数
string roundTime = 6; //本回合开始时间
} }
//玩家 //玩家
...@@ -37,7 +38,8 @@ message PBPlayer { ...@@ -37,7 +38,8 @@ message PBPlayer {
repeated PBHand hands = 1; //历史发牌和斗牛结果 repeated PBHand hands = 1; //历史发牌和斗牛结果
string address = 2; //玩家地址 string address = 2; //玩家地址
int64 txHash = 3; //发牌随机数因子txhash的整数格式 int64 txHash = 3; //发牌随机数因子txhash的整数格式
bool ready = 4; // continue状态下,是否ready bool ready = 4; //continue状态下,是否ready
string matchTime = 5; //玩家匹配时间
} }
//本局游戏结果 //本局游戏结果
...@@ -62,6 +64,7 @@ message PBGameAction { ...@@ -62,6 +64,7 @@ message PBGameAction {
PBGameContinue continue = 2; PBGameContinue continue = 2;
PBGameQuit quit = 3; PBGameQuit quit = 3;
PBGameQuery query = 4; PBGameQuery query = 4;
PBGamePlay play = 5;
} }
int32 ty = 10; int32 ty = 10;
} }
...@@ -87,6 +90,14 @@ message PBGameQuery { ...@@ -87,6 +90,14 @@ message PBGameQuery {
string gameId = 1; string gameId = 1;
} }
//已匹配玩家直接游戏
message PBGamePlay {
string gameId = 1; //游戏id
int32 round = 2; //当前游戏回合数
int64 value = 3; //当前游戏赌注
repeated string address = 4; //玩家地址
}
//根据状态和游戏人数查找 //根据状态和游戏人数查找
message QueryPBGameListByStatusAndPlayerNum { message QueryPBGameListByStatusAndPlayerNum {
int32 status = 1; int32 status = 1;
......
...@@ -97,7 +97,7 @@ func testQuitRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error { ...@@ -97,7 +97,7 @@ func testQuitRawTxCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
payload := &pty.PBGameQuit{GameId: "123"} payload := &pty.PBGameQuit{GameId: "123"}
params := &rpctypes.CreateTxIn{ params := &rpctypes.CreateTxIn{
Execer: types.ExecName(pty.PokerBullX), Execer: types.ExecName(pty.PokerBullX),
ActionName: pty.CreatequitTx, ActionName: pty.CreateQuitTx,
Payload: types.MustPBToJSON(payload), Payload: types.MustPBToJSON(payload),
} }
var res string var res string
......
...@@ -12,6 +12,7 @@ const ( ...@@ -12,6 +12,7 @@ const (
PBGameActionContinue PBGameActionContinue
PBGameActionQuit PBGameActionQuit
PBGameActionQuery PBGameActionQuery
PBGameActionPlay
) )
const ( const (
...@@ -30,6 +31,8 @@ const ( ...@@ -30,6 +31,8 @@ const (
TyLogPBGameQuit = 723 TyLogPBGameQuit = 723
// TyLogPBGameQuery log for query PBgame // TyLogPBGameQuery log for query PBgame
TyLogPBGameQuery = 724 TyLogPBGameQuery = 724
// TyLogPBGamePlay log for play PBgame
TyLogPBGamePlay = 725
) )
//包的名字可以通过配置文件来配置 //包的名字可以通过配置文件来配置
...@@ -56,8 +59,10 @@ const ( ...@@ -56,8 +59,10 @@ const (
CreateStartTx = "Start" CreateStartTx = "Start"
// CreateContinueTx 创建继续交易 // CreateContinueTx 创建继续交易
CreateContinueTx = "Continue" CreateContinueTx = "Continue"
// CreatequitTx 创建退出交易 // CreateQuitTx 创建退出交易
CreatequitTx = "Quit" CreateQuitTx = "Quit"
// CreatePlayTx 创建已匹配玩家交易
CreatePlayTx = "Play"
) )
const ( const (
...@@ -67,6 +72,8 @@ const ( ...@@ -67,6 +72,8 @@ const (
DefaultCount = int32(20) DefaultCount = int32(20)
// MaxPlayerNum 最大玩家数 // MaxPlayerNum 最大玩家数
MaxPlayerNum = 5 MaxPlayerNum = 5
// MinPlayerNum 最小玩家数
MinPlayerNum = 2
// MinPlayValue 最小赌注 // MinPlayValue 最小赌注
MinPlayValue = 10 * types.Coin MinPlayValue = 10 * types.Coin
// DefaultStyle 默认游戏类型 // DefaultStyle 默认游戏类型
...@@ -80,5 +87,7 @@ const ( ...@@ -80,5 +87,7 @@ const (
// DeveloperFee 开发者佣金 // DeveloperFee 开发者佣金
DeveloperFee = int64(0.005 * float64(types.Coin)) DeveloperFee = int64(0.005 * float64(types.Coin))
// WinnerReturn 赢家回报率 // WinnerReturn 赢家回报率
WinnerReturn = types.Coin - DeveloperFee WinnerReturn = types.Coin - DeveloperFee - PlatformFee
// PlatformSignAddress 平台签名地址
PlatformSignAddress = "1Geb4ppNiAwMKKyrJgcis3JA57FkqsXvdR"
) )
...@@ -25,7 +25,7 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package ...@@ -25,7 +25,7 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type PokerBull struct { type PokerBull struct {
GameId string `protobuf:"bytes,1,opt,name=gameId,proto3" json:"gameId,omitempty"` GameId string `protobuf:"bytes,1,opt,name=gameId,proto3" json:"gameId,omitempty"`
Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"` Status int32 `protobuf:"varint,2,opt,name=status,proto3" json:"status,omitempty"`
StartTime int64 `protobuf:"varint,3,opt,name=startTime,proto3" json:"startTime,omitempty"` StartTime string `protobuf:"bytes,3,opt,name=startTime,proto3" json:"startTime,omitempty"`
StartTxHash string `protobuf:"bytes,4,opt,name=startTxHash,proto3" json:"startTxHash,omitempty"` StartTxHash string `protobuf:"bytes,4,opt,name=startTxHash,proto3" json:"startTxHash,omitempty"`
Value int64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` Value int64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"`
Poker *PBPoker `protobuf:"bytes,6,opt,name=poker,proto3" json:"poker,omitempty"` Poker *PBPoker `protobuf:"bytes,6,opt,name=poker,proto3" json:"poker,omitempty"`
...@@ -34,7 +34,7 @@ type PokerBull struct { ...@@ -34,7 +34,7 @@ type PokerBull struct {
Results []*PBResult `protobuf:"bytes,9,rep,name=results,proto3" json:"results,omitempty"` Results []*PBResult `protobuf:"bytes,9,rep,name=results,proto3" json:"results,omitempty"`
Index int64 `protobuf:"varint,10,opt,name=index,proto3" json:"index,omitempty"` Index int64 `protobuf:"varint,10,opt,name=index,proto3" json:"index,omitempty"`
PrevIndex int64 `protobuf:"varint,11,opt,name=prevIndex,proto3" json:"prevIndex,omitempty"` PrevIndex int64 `protobuf:"varint,11,opt,name=prevIndex,proto3" json:"prevIndex,omitempty"`
QuitTime int64 `protobuf:"varint,12,opt,name=quitTime,proto3" json:"quitTime,omitempty"` QuitTime string `protobuf:"bytes,12,opt,name=quitTime,proto3" json:"quitTime,omitempty"`
QuitTxHash string `protobuf:"bytes,13,opt,name=quitTxHash,proto3" json:"quitTxHash,omitempty"` QuitTxHash string `protobuf:"bytes,13,opt,name=quitTxHash,proto3" json:"quitTxHash,omitempty"`
DealerAddr string `protobuf:"bytes,14,opt,name=dealerAddr,proto3" json:"dealerAddr,omitempty"` DealerAddr string `protobuf:"bytes,14,opt,name=dealerAddr,proto3" json:"dealerAddr,omitempty"`
IsWaiting bool `protobuf:"varint,15,opt,name=isWaiting,proto3" json:"isWaiting,omitempty"` IsWaiting bool `protobuf:"varint,15,opt,name=isWaiting,proto3" json:"isWaiting,omitempty"`
...@@ -84,11 +84,11 @@ func (m *PokerBull) GetStatus() int32 { ...@@ -84,11 +84,11 @@ func (m *PokerBull) GetStatus() int32 {
return 0 return 0
} }
func (m *PokerBull) GetStartTime() int64 { func (m *PokerBull) GetStartTime() string {
if m != nil { if m != nil {
return m.StartTime return m.StartTime
} }
return 0 return ""
} }
func (m *PokerBull) GetStartTxHash() string { func (m *PokerBull) GetStartTxHash() string {
...@@ -147,11 +147,11 @@ func (m *PokerBull) GetPrevIndex() int64 { ...@@ -147,11 +147,11 @@ func (m *PokerBull) GetPrevIndex() int64 {
return 0 return 0
} }
func (m *PokerBull) GetQuitTime() int64 { func (m *PokerBull) GetQuitTime() string {
if m != nil { if m != nil {
return m.QuitTime return m.QuitTime
} }
return 0 return ""
} }
func (m *PokerBull) GetQuitTxHash() string { func (m *PokerBull) GetQuitTxHash() string {
...@@ -196,6 +196,7 @@ type PBHand struct { ...@@ -196,6 +196,7 @@ type PBHand struct {
Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"`
IsWin bool `protobuf:"varint,4,opt,name=isWin,proto3" json:"isWin,omitempty"` IsWin bool `protobuf:"varint,4,opt,name=isWin,proto3" json:"isWin,omitempty"`
Leverage int32 `protobuf:"varint,5,opt,name=leverage,proto3" json:"leverage,omitempty"` Leverage int32 `protobuf:"varint,5,opt,name=leverage,proto3" json:"leverage,omitempty"`
RoundTime string `protobuf:"bytes,6,opt,name=roundTime,proto3" json:"roundTime,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -261,12 +262,20 @@ func (m *PBHand) GetLeverage() int32 { ...@@ -261,12 +262,20 @@ func (m *PBHand) GetLeverage() int32 {
return 0 return 0
} }
func (m *PBHand) GetRoundTime() string {
if m != nil {
return m.RoundTime
}
return ""
}
//玩家 //玩家
type PBPlayer struct { type PBPlayer struct {
Hands []*PBHand `protobuf:"bytes,1,rep,name=hands,proto3" json:"hands,omitempty"` Hands []*PBHand `protobuf:"bytes,1,rep,name=hands,proto3" json:"hands,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
TxHash int64 `protobuf:"varint,3,opt,name=txHash,proto3" json:"txHash,omitempty"` TxHash int64 `protobuf:"varint,3,opt,name=txHash,proto3" json:"txHash,omitempty"`
Ready bool `protobuf:"varint,4,opt,name=ready,proto3" json:"ready,omitempty"` Ready bool `protobuf:"varint,4,opt,name=ready,proto3" json:"ready,omitempty"`
MatchTime string `protobuf:"bytes,5,opt,name=matchTime,proto3" json:"matchTime,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -325,6 +334,13 @@ func (m *PBPlayer) GetReady() bool { ...@@ -325,6 +334,13 @@ func (m *PBPlayer) GetReady() bool {
return false return false
} }
func (m *PBPlayer) GetMatchTime() string {
if m != nil {
return m.MatchTime
}
return ""
}
//本局游戏结果 //本局游戏结果
type PBResult struct { type PBResult struct {
Hands []*PBHand `protobuf:"bytes,1,rep,name=hands,proto3" json:"hands,omitempty"` Hands []*PBHand `protobuf:"bytes,1,rep,name=hands,proto3" json:"hands,omitempty"`
...@@ -452,6 +468,7 @@ type PBGameAction struct { ...@@ -452,6 +468,7 @@ type PBGameAction struct {
// *PBGameAction_Continue // *PBGameAction_Continue
// *PBGameAction_Quit // *PBGameAction_Quit
// *PBGameAction_Query // *PBGameAction_Query
// *PBGameAction_Play
Value isPBGameAction_Value `protobuf_oneof:"value"` Value isPBGameAction_Value `protobuf_oneof:"value"`
Ty int32 `protobuf:"varint,10,opt,name=ty,proto3" json:"ty,omitempty"` Ty int32 `protobuf:"varint,10,opt,name=ty,proto3" json:"ty,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -504,6 +521,10 @@ type PBGameAction_Query struct { ...@@ -504,6 +521,10 @@ type PBGameAction_Query struct {
Query *PBGameQuery `protobuf:"bytes,4,opt,name=query,proto3,oneof"` Query *PBGameQuery `protobuf:"bytes,4,opt,name=query,proto3,oneof"`
} }
type PBGameAction_Play struct {
Play *PBGamePlay `protobuf:"bytes,5,opt,name=play,proto3,oneof"`
}
func (*PBGameAction_Start) isPBGameAction_Value() {} func (*PBGameAction_Start) isPBGameAction_Value() {}
func (*PBGameAction_Continue) isPBGameAction_Value() {} func (*PBGameAction_Continue) isPBGameAction_Value() {}
...@@ -512,6 +533,8 @@ func (*PBGameAction_Quit) isPBGameAction_Value() {} ...@@ -512,6 +533,8 @@ func (*PBGameAction_Quit) isPBGameAction_Value() {}
func (*PBGameAction_Query) isPBGameAction_Value() {} func (*PBGameAction_Query) isPBGameAction_Value() {}
func (*PBGameAction_Play) isPBGameAction_Value() {}
func (m *PBGameAction) GetValue() isPBGameAction_Value { func (m *PBGameAction) GetValue() isPBGameAction_Value {
if m != nil { if m != nil {
return m.Value return m.Value
...@@ -547,6 +570,13 @@ func (m *PBGameAction) GetQuery() *PBGameQuery { ...@@ -547,6 +570,13 @@ func (m *PBGameAction) GetQuery() *PBGameQuery {
return nil return nil
} }
func (m *PBGameAction) GetPlay() *PBGamePlay {
if x, ok := m.GetValue().(*PBGameAction_Play); ok {
return x.Play
}
return nil
}
func (m *PBGameAction) GetTy() int32 { func (m *PBGameAction) GetTy() int32 {
if m != nil { if m != nil {
return m.Ty return m.Ty
...@@ -561,6 +591,7 @@ func (*PBGameAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) ...@@ -561,6 +591,7 @@ func (*PBGameAction) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer)
(*PBGameAction_Continue)(nil), (*PBGameAction_Continue)(nil),
(*PBGameAction_Quit)(nil), (*PBGameAction_Quit)(nil),
(*PBGameAction_Query)(nil), (*PBGameAction_Query)(nil),
(*PBGameAction_Play)(nil),
} }
} }
...@@ -588,6 +619,11 @@ func _PBGameAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { ...@@ -588,6 +619,11 @@ func _PBGameAction_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
if err := b.EncodeMessage(x.Query); err != nil { if err := b.EncodeMessage(x.Query); err != nil {
return err return err
} }
case *PBGameAction_Play:
b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Play); err != nil {
return err
}
case nil: case nil:
default: default:
return fmt.Errorf("PBGameAction.Value has unexpected type %T", x) return fmt.Errorf("PBGameAction.Value has unexpected type %T", x)
...@@ -630,6 +666,14 @@ func _PBGameAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B ...@@ -630,6 +666,14 @@ func _PBGameAction_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.B
err := b.DecodeMessage(msg) err := b.DecodeMessage(msg)
m.Value = &PBGameAction_Query{msg} m.Value = &PBGameAction_Query{msg}
return true, err return true, err
case 5: // value.play
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(PBGamePlay)
err := b.DecodeMessage(msg)
m.Value = &PBGameAction_Play{msg}
return true, err
default: default:
return false, nil return false, nil
} }
...@@ -659,6 +703,11 @@ func _PBGameAction_OneofSizer(msg proto.Message) (n int) { ...@@ -659,6 +703,11 @@ func _PBGameAction_OneofSizer(msg proto.Message) (n int) {
n += 1 // tag and wire n += 1 // tag and wire
n += proto.SizeVarint(uint64(s)) n += proto.SizeVarint(uint64(s))
n += s n += s
case *PBGameAction_Play:
s := proto.Size(x.Play)
n += 1 // tag and wire
n += proto.SizeVarint(uint64(s))
n += s
case nil: case nil:
default: default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
...@@ -834,6 +883,70 @@ func (m *PBGameQuery) GetGameId() string { ...@@ -834,6 +883,70 @@ func (m *PBGameQuery) GetGameId() string {
return "" return ""
} }
//已匹配玩家直接游戏
type PBGamePlay struct {
GameId string `protobuf:"bytes,1,opt,name=gameId,proto3" json:"gameId,omitempty"`
Round int32 `protobuf:"varint,2,opt,name=round,proto3" json:"round,omitempty"`
Value int64 `protobuf:"varint,3,opt,name=value,proto3" json:"value,omitempty"`
Address []string `protobuf:"bytes,4,rep,name=address,proto3" json:"address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBGamePlay) Reset() { *m = PBGamePlay{} }
func (m *PBGamePlay) String() string { return proto.CompactTextString(m) }
func (*PBGamePlay) ProtoMessage() {}
func (*PBGamePlay) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{10}
}
func (m *PBGamePlay) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBGamePlay.Unmarshal(m, b)
}
func (m *PBGamePlay) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBGamePlay.Marshal(b, m, deterministic)
}
func (m *PBGamePlay) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBGamePlay.Merge(m, src)
}
func (m *PBGamePlay) XXX_Size() int {
return xxx_messageInfo_PBGamePlay.Size(m)
}
func (m *PBGamePlay) XXX_DiscardUnknown() {
xxx_messageInfo_PBGamePlay.DiscardUnknown(m)
}
var xxx_messageInfo_PBGamePlay proto.InternalMessageInfo
func (m *PBGamePlay) GetGameId() string {
if m != nil {
return m.GameId
}
return ""
}
func (m *PBGamePlay) GetRound() int32 {
if m != nil {
return m.Round
}
return 0
}
func (m *PBGamePlay) GetValue() int64 {
if m != nil {
return m.Value
}
return 0
}
func (m *PBGamePlay) GetAddress() []string {
if m != nil {
return m.Address
}
return nil
}
//根据状态和游戏人数查找 //根据状态和游戏人数查找
type QueryPBGameListByStatusAndPlayerNum struct { type QueryPBGameListByStatusAndPlayerNum struct {
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"` Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
...@@ -848,7 +961,7 @@ func (m *QueryPBGameListByStatusAndPlayerNum) Reset() { *m = QueryPBGame ...@@ -848,7 +961,7 @@ func (m *QueryPBGameListByStatusAndPlayerNum) Reset() { *m = QueryPBGame
func (m *QueryPBGameListByStatusAndPlayerNum) String() string { return proto.CompactTextString(m) } func (m *QueryPBGameListByStatusAndPlayerNum) String() string { return proto.CompactTextString(m) }
func (*QueryPBGameListByStatusAndPlayerNum) ProtoMessage() {} func (*QueryPBGameListByStatusAndPlayerNum) ProtoMessage() {}
func (*QueryPBGameListByStatusAndPlayerNum) Descriptor() ([]byte, []int) { func (*QueryPBGameListByStatusAndPlayerNum) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{10} return fileDescriptor_8d22e4ee2313e311, []int{11}
} }
func (m *QueryPBGameListByStatusAndPlayerNum) XXX_Unmarshal(b []byte) error { func (m *QueryPBGameListByStatusAndPlayerNum) XXX_Unmarshal(b []byte) error {
...@@ -904,7 +1017,7 @@ func (m *PBGameRecord) Reset() { *m = PBGameRecord{} } ...@@ -904,7 +1017,7 @@ func (m *PBGameRecord) Reset() { *m = PBGameRecord{} }
func (m *PBGameRecord) String() string { return proto.CompactTextString(m) } func (m *PBGameRecord) String() string { return proto.CompactTextString(m) }
func (*PBGameRecord) ProtoMessage() {} func (*PBGameRecord) ProtoMessage() {}
func (*PBGameRecord) Descriptor() ([]byte, []int) { func (*PBGameRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{11} return fileDescriptor_8d22e4ee2313e311, []int{12}
} }
func (m *PBGameRecord) XXX_Unmarshal(b []byte) error { func (m *PBGameRecord) XXX_Unmarshal(b []byte) error {
...@@ -958,7 +1071,7 @@ func (m *PBGameIndexRecord) Reset() { *m = PBGameIndexRecord{} } ...@@ -958,7 +1071,7 @@ func (m *PBGameIndexRecord) Reset() { *m = PBGameIndexRecord{} }
func (m *PBGameIndexRecord) String() string { return proto.CompactTextString(m) } func (m *PBGameIndexRecord) String() string { return proto.CompactTextString(m) }
func (*PBGameIndexRecord) ProtoMessage() {} func (*PBGameIndexRecord) ProtoMessage() {}
func (*PBGameIndexRecord) Descriptor() ([]byte, []int) { func (*PBGameIndexRecord) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{12} return fileDescriptor_8d22e4ee2313e311, []int{13}
} }
func (m *PBGameIndexRecord) XXX_Unmarshal(b []byte) error { func (m *PBGameIndexRecord) XXX_Unmarshal(b []byte) error {
...@@ -1004,7 +1117,7 @@ func (m *PBGameRecords) Reset() { *m = PBGameRecords{} } ...@@ -1004,7 +1117,7 @@ func (m *PBGameRecords) Reset() { *m = PBGameRecords{} }
func (m *PBGameRecords) String() string { return proto.CompactTextString(m) } func (m *PBGameRecords) String() string { return proto.CompactTextString(m) }
func (*PBGameRecords) ProtoMessage() {} func (*PBGameRecords) ProtoMessage() {}
func (*PBGameRecords) Descriptor() ([]byte, []int) { func (*PBGameRecords) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{13} return fileDescriptor_8d22e4ee2313e311, []int{14}
} }
func (m *PBGameRecords) XXX_Unmarshal(b []byte) error { func (m *PBGameRecords) XXX_Unmarshal(b []byte) error {
...@@ -1043,7 +1156,7 @@ func (m *PBGameIndexRecords) Reset() { *m = PBGameIndexRecords{} } ...@@ -1043,7 +1156,7 @@ func (m *PBGameIndexRecords) Reset() { *m = PBGameIndexRecords{} }
func (m *PBGameIndexRecords) String() string { return proto.CompactTextString(m) } func (m *PBGameIndexRecords) String() string { return proto.CompactTextString(m) }
func (*PBGameIndexRecords) ProtoMessage() {} func (*PBGameIndexRecords) ProtoMessage() {}
func (*PBGameIndexRecords) Descriptor() ([]byte, []int) { func (*PBGameIndexRecords) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{14} return fileDescriptor_8d22e4ee2313e311, []int{15}
} }
func (m *PBGameIndexRecords) XXX_Unmarshal(b []byte) error { func (m *PBGameIndexRecords) XXX_Unmarshal(b []byte) error {
...@@ -1085,7 +1198,7 @@ func (m *QueryPBGameInfo) Reset() { *m = QueryPBGameInfo{} } ...@@ -1085,7 +1198,7 @@ func (m *QueryPBGameInfo) Reset() { *m = QueryPBGameInfo{} }
func (m *QueryPBGameInfo) String() string { return proto.CompactTextString(m) } func (m *QueryPBGameInfo) String() string { return proto.CompactTextString(m) }
func (*QueryPBGameInfo) ProtoMessage() {} func (*QueryPBGameInfo) ProtoMessage() {}
func (*QueryPBGameInfo) Descriptor() ([]byte, []int) { func (*QueryPBGameInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{15} return fileDescriptor_8d22e4ee2313e311, []int{16}
} }
func (m *QueryPBGameInfo) XXX_Unmarshal(b []byte) error { func (m *QueryPBGameInfo) XXX_Unmarshal(b []byte) error {
...@@ -1145,7 +1258,7 @@ func (m *ReplyPBGame) Reset() { *m = ReplyPBGame{} } ...@@ -1145,7 +1258,7 @@ func (m *ReplyPBGame) Reset() { *m = ReplyPBGame{} }
func (m *ReplyPBGame) String() string { return proto.CompactTextString(m) } func (m *ReplyPBGame) String() string { return proto.CompactTextString(m) }
func (*ReplyPBGame) ProtoMessage() {} func (*ReplyPBGame) ProtoMessage() {}
func (*ReplyPBGame) Descriptor() ([]byte, []int) { func (*ReplyPBGame) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{16} return fileDescriptor_8d22e4ee2313e311, []int{17}
} }
func (m *ReplyPBGame) XXX_Unmarshal(b []byte) error { func (m *ReplyPBGame) XXX_Unmarshal(b []byte) error {
...@@ -1184,7 +1297,7 @@ func (m *QueryPBGameInfos) Reset() { *m = QueryPBGameInfos{} } ...@@ -1184,7 +1297,7 @@ func (m *QueryPBGameInfos) Reset() { *m = QueryPBGameInfos{} }
func (m *QueryPBGameInfos) String() string { return proto.CompactTextString(m) } func (m *QueryPBGameInfos) String() string { return proto.CompactTextString(m) }
func (*QueryPBGameInfos) ProtoMessage() {} func (*QueryPBGameInfos) ProtoMessage() {}
func (*QueryPBGameInfos) Descriptor() ([]byte, []int) { func (*QueryPBGameInfos) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{17} return fileDescriptor_8d22e4ee2313e311, []int{18}
} }
func (m *QueryPBGameInfos) XXX_Unmarshal(b []byte) error { func (m *QueryPBGameInfos) XXX_Unmarshal(b []byte) error {
...@@ -1223,7 +1336,7 @@ func (m *ReplyPBGameList) Reset() { *m = ReplyPBGameList{} } ...@@ -1223,7 +1336,7 @@ func (m *ReplyPBGameList) Reset() { *m = ReplyPBGameList{} }
func (m *ReplyPBGameList) String() string { return proto.CompactTextString(m) } func (m *ReplyPBGameList) String() string { return proto.CompactTextString(m) }
func (*ReplyPBGameList) ProtoMessage() {} func (*ReplyPBGameList) ProtoMessage() {}
func (*ReplyPBGameList) Descriptor() ([]byte, []int) { func (*ReplyPBGameList) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{18} return fileDescriptor_8d22e4ee2313e311, []int{19}
} }
func (m *ReplyPBGameList) XXX_Unmarshal(b []byte) error { func (m *ReplyPBGameList) XXX_Unmarshal(b []byte) error {
...@@ -1264,7 +1377,7 @@ func (m *QueryPBGameByRound) Reset() { *m = QueryPBGameByRound{} } ...@@ -1264,7 +1377,7 @@ func (m *QueryPBGameByRound) Reset() { *m = QueryPBGameByRound{} }
func (m *QueryPBGameByRound) String() string { return proto.CompactTextString(m) } func (m *QueryPBGameByRound) String() string { return proto.CompactTextString(m) }
func (*QueryPBGameByRound) ProtoMessage() {} func (*QueryPBGameByRound) ProtoMessage() {}
func (*QueryPBGameByRound) Descriptor() ([]byte, []int) { func (*QueryPBGameByRound) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{19} return fileDescriptor_8d22e4ee2313e311, []int{20}
} }
func (m *QueryPBGameByRound) XXX_Unmarshal(b []byte) error { func (m *QueryPBGameByRound) XXX_Unmarshal(b []byte) error {
...@@ -1317,7 +1430,7 @@ func (m *ReplyPBGameByRound) Reset() { *m = ReplyPBGameByRound{} } ...@@ -1317,7 +1430,7 @@ func (m *ReplyPBGameByRound) Reset() { *m = ReplyPBGameByRound{} }
func (m *ReplyPBGameByRound) String() string { return proto.CompactTextString(m) } func (m *ReplyPBGameByRound) String() string { return proto.CompactTextString(m) }
func (*ReplyPBGameByRound) ProtoMessage() {} func (*ReplyPBGameByRound) ProtoMessage() {}
func (*ReplyPBGameByRound) Descriptor() ([]byte, []int) { func (*ReplyPBGameByRound) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{20} return fileDescriptor_8d22e4ee2313e311, []int{21}
} }
func (m *ReplyPBGameByRound) XXX_Unmarshal(b []byte) error { func (m *ReplyPBGameByRound) XXX_Unmarshal(b []byte) error {
...@@ -1408,7 +1521,7 @@ func (m *ReceiptPBGame) Reset() { *m = ReceiptPBGame{} } ...@@ -1408,7 +1521,7 @@ func (m *ReceiptPBGame) Reset() { *m = ReceiptPBGame{} }
func (m *ReceiptPBGame) String() string { return proto.CompactTextString(m) } func (m *ReceiptPBGame) String() string { return proto.CompactTextString(m) }
func (*ReceiptPBGame) ProtoMessage() {} func (*ReceiptPBGame) ProtoMessage() {}
func (*ReceiptPBGame) Descriptor() ([]byte, []int) { func (*ReceiptPBGame) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{21} return fileDescriptor_8d22e4ee2313e311, []int{22}
} }
func (m *ReceiptPBGame) XXX_Unmarshal(b []byte) error { func (m *ReceiptPBGame) XXX_Unmarshal(b []byte) error {
...@@ -1519,7 +1632,7 @@ func (m *PBStartTxReq) Reset() { *m = PBStartTxReq{} } ...@@ -1519,7 +1632,7 @@ func (m *PBStartTxReq) Reset() { *m = PBStartTxReq{} }
func (m *PBStartTxReq) String() string { return proto.CompactTextString(m) } func (m *PBStartTxReq) String() string { return proto.CompactTextString(m) }
func (*PBStartTxReq) ProtoMessage() {} func (*PBStartTxReq) ProtoMessage() {}
func (*PBStartTxReq) Descriptor() ([]byte, []int) { func (*PBStartTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{22} return fileDescriptor_8d22e4ee2313e311, []int{23}
} }
func (m *PBStartTxReq) XXX_Unmarshal(b []byte) error { func (m *PBStartTxReq) XXX_Unmarshal(b []byte) error {
...@@ -1573,7 +1686,7 @@ func (m *PBContinueTxReq) Reset() { *m = PBContinueTxReq{} } ...@@ -1573,7 +1686,7 @@ func (m *PBContinueTxReq) Reset() { *m = PBContinueTxReq{} }
func (m *PBContinueTxReq) String() string { return proto.CompactTextString(m) } func (m *PBContinueTxReq) String() string { return proto.CompactTextString(m) }
func (*PBContinueTxReq) ProtoMessage() {} func (*PBContinueTxReq) ProtoMessage() {}
func (*PBContinueTxReq) Descriptor() ([]byte, []int) { func (*PBContinueTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{23} return fileDescriptor_8d22e4ee2313e311, []int{24}
} }
func (m *PBContinueTxReq) XXX_Unmarshal(b []byte) error { func (m *PBContinueTxReq) XXX_Unmarshal(b []byte) error {
...@@ -1620,7 +1733,7 @@ func (m *PBQuitTxReq) Reset() { *m = PBQuitTxReq{} } ...@@ -1620,7 +1733,7 @@ func (m *PBQuitTxReq) Reset() { *m = PBQuitTxReq{} }
func (m *PBQuitTxReq) String() string { return proto.CompactTextString(m) } func (m *PBQuitTxReq) String() string { return proto.CompactTextString(m) }
func (*PBQuitTxReq) ProtoMessage() {} func (*PBQuitTxReq) ProtoMessage() {}
func (*PBQuitTxReq) Descriptor() ([]byte, []int) { func (*PBQuitTxReq) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{24} return fileDescriptor_8d22e4ee2313e311, []int{25}
} }
func (m *PBQuitTxReq) XXX_Unmarshal(b []byte) error { func (m *PBQuitTxReq) XXX_Unmarshal(b []byte) error {
...@@ -1667,7 +1780,7 @@ func (m *PBQueryReq) Reset() { *m = PBQueryReq{} } ...@@ -1667,7 +1780,7 @@ func (m *PBQueryReq) Reset() { *m = PBQueryReq{} }
func (m *PBQueryReq) String() string { return proto.CompactTextString(m) } func (m *PBQueryReq) String() string { return proto.CompactTextString(m) }
func (*PBQueryReq) ProtoMessage() {} func (*PBQueryReq) ProtoMessage() {}
func (*PBQueryReq) Descriptor() ([]byte, []int) { func (*PBQueryReq) Descriptor() ([]byte, []int) {
return fileDescriptor_8d22e4ee2313e311, []int{25} return fileDescriptor_8d22e4ee2313e311, []int{26}
} }
func (m *PBQueryReq) XXX_Unmarshal(b []byte) error { func (m *PBQueryReq) XXX_Unmarshal(b []byte) error {
...@@ -1713,6 +1826,7 @@ func init() { ...@@ -1713,6 +1826,7 @@ func init() {
proto.RegisterType((*PBGameContinue)(nil), "types.PBGameContinue") proto.RegisterType((*PBGameContinue)(nil), "types.PBGameContinue")
proto.RegisterType((*PBGameQuit)(nil), "types.PBGameQuit") proto.RegisterType((*PBGameQuit)(nil), "types.PBGameQuit")
proto.RegisterType((*PBGameQuery)(nil), "types.PBGameQuery") proto.RegisterType((*PBGameQuery)(nil), "types.PBGameQuery")
proto.RegisterType((*PBGamePlay)(nil), "types.PBGamePlay")
proto.RegisterType((*QueryPBGameListByStatusAndPlayerNum)(nil), "types.QueryPBGameListByStatusAndPlayerNum") proto.RegisterType((*QueryPBGameListByStatusAndPlayerNum)(nil), "types.QueryPBGameListByStatusAndPlayerNum")
proto.RegisterType((*PBGameRecord)(nil), "types.PBGameRecord") proto.RegisterType((*PBGameRecord)(nil), "types.PBGameRecord")
proto.RegisterType((*PBGameIndexRecord)(nil), "types.PBGameIndexRecord") proto.RegisterType((*PBGameIndexRecord)(nil), "types.PBGameIndexRecord")
...@@ -1734,69 +1848,73 @@ func init() { ...@@ -1734,69 +1848,73 @@ func init() {
func init() { proto.RegisterFile("pokerbull.proto", fileDescriptor_8d22e4ee2313e311) } func init() { proto.RegisterFile("pokerbull.proto", fileDescriptor_8d22e4ee2313e311) }
var fileDescriptor_8d22e4ee2313e311 = []byte{ var fileDescriptor_8d22e4ee2313e311 = []byte{
// 1021 bytes of a gzipped FileDescriptorProto // 1081 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4b, 0x6f, 0x23, 0x45, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0x4f, 0x6f, 0xe3, 0x44,
0x10, 0xde, 0xb1, 0x3d, 0x7e, 0xd4, 0x6c, 0xec, 0xa4, 0x81, 0xa8, 0x85, 0x10, 0xb2, 0x66, 0xc3, 0x14, 0x5f, 0xdb, 0xb1, 0x93, 0x3c, 0x6f, 0x9b, 0x76, 0x80, 0x6a, 0x84, 0x10, 0x8a, 0xbc, 0x65,
0xae, 0x41, 0x90, 0x83, 0x23, 0x81, 0x56, 0x48, 0x48, 0x36, 0x07, 0x1c, 0x69, 0x85, 0x9c, 0xce, 0x37, 0x20, 0xe8, 0x21, 0x95, 0x40, 0x2b, 0x24, 0xa4, 0x86, 0x03, 0xa9, 0xb4, 0x42, 0xe9, 0x74,
0x4a, 0x7b, 0x9e, 0xf5, 0xf4, 0x66, 0x47, 0x3b, 0x19, 0x3b, 0xf3, 0xc8, 0xc6, 0x57, 0xee, 0xfc, 0xa5, 0x3d, 0x7b, 0xe3, 0xd9, 0xd6, 0xac, 0xe3, 0xa4, 0xfe, 0x53, 0x36, 0x5f, 0x80, 0x1b, 0x47,
0x0a, 0x0e, 0xfc, 0x2a, 0x6e, 0xfc, 0x10, 0xd4, 0x55, 0xdd, 0x33, 0x3d, 0x13, 0x9b, 0x10, 0x6e, 0xee, 0x48, 0x1c, 0xf8, 0x62, 0x7c, 0x10, 0x34, 0x6f, 0x66, 0xec, 0xb1, 0x1b, 0xab, 0x84, 0x9b,
0x5d, 0x8f, 0xae, 0xae, 0x57, 0x7f, 0x55, 0x30, 0xda, 0xac, 0x3f, 0xc8, 0xf4, 0x6d, 0x11, 0xc7, 0xdf, 0x9f, 0x79, 0xf3, 0x7b, 0x6f, 0xde, 0xfc, 0xde, 0x18, 0x46, 0x9b, 0xf5, 0x7b, 0x9e, 0xbd,
0xa7, 0x9b, 0x74, 0x9d, 0xaf, 0x99, 0x9b, 0x6f, 0x37, 0x32, 0xf3, 0x7f, 0xef, 0xc0, 0x60, 0xa9, 0x2d, 0x93, 0xe4, 0x6c, 0x93, 0xad, 0x8b, 0x35, 0x71, 0x8b, 0xed, 0x86, 0xe7, 0xc1, 0xef, 0x3d,
0x44, 0xf3, 0x22, 0x8e, 0xd9, 0x31, 0x74, 0xaf, 0x82, 0x6b, 0x79, 0x1e, 0x72, 0x67, 0xec, 0x4c, 0x18, 0x2e, 0x84, 0x69, 0x56, 0x26, 0x09, 0x39, 0x01, 0xef, 0x26, 0x5c, 0xf1, 0xcb, 0x88, 0x5a,
0x06, 0x42, 0x53, 0x8a, 0x9f, 0xe5, 0x41, 0x5e, 0x64, 0xbc, 0x35, 0x76, 0x26, 0xae, 0xd0, 0x14, 0x63, 0x6b, 0x32, 0x64, 0x4a, 0x12, 0xfa, 0xbc, 0x08, 0x8b, 0x32, 0xa7, 0xf6, 0xd8, 0x9a, 0xb8,
0xfb, 0x02, 0x06, 0x59, 0x1e, 0xa4, 0xf9, 0xeb, 0xe8, 0x5a, 0xf2, 0xf6, 0xd8, 0x99, 0xb4, 0x45, 0x4c, 0x49, 0xe4, 0x33, 0x18, 0xe6, 0x45, 0x98, 0x15, 0xaf, 0xe3, 0x15, 0xa7, 0x0e, 0x2e, 0xa9,
0xc5, 0x60, 0x63, 0xf0, 0x88, 0xb8, 0x5b, 0x04, 0xd9, 0x7b, 0xde, 0x41, 0x93, 0x36, 0x8b, 0x7d, 0x15, 0x64, 0x0c, 0xbe, 0x14, 0x3e, 0xcc, 0xc3, 0xfc, 0x96, 0xf6, 0xd0, 0x6e, 0xaa, 0xc8, 0xc7,
0x0a, 0xee, 0x6d, 0x10, 0x17, 0x92, 0xbb, 0x78, 0x97, 0x08, 0x76, 0x02, 0x2e, 0x7a, 0xcb, 0xbb, 0xe0, 0xde, 0x87, 0x49, 0xc9, 0xa9, 0x3b, 0xb6, 0x26, 0x0e, 0x93, 0x02, 0x39, 0x05, 0x17, 0xd1,
0x63, 0x67, 0xe2, 0x4d, 0x87, 0xa7, 0xe8, 0xea, 0xe9, 0x72, 0x8e, 0x8e, 0x0a, 0x12, 0xb2, 0xaf, 0x52, 0x6f, 0x6c, 0x4d, 0xfc, 0xe9, 0xe1, 0x19, 0x42, 0x3d, 0x5b, 0xcc, 0x10, 0x28, 0x93, 0x46,
0xa1, 0xb7, 0x89, 0x83, 0xad, 0x4c, 0x33, 0xde, 0x1b, 0xb7, 0x27, 0xde, 0x74, 0x54, 0xe9, 0x21, 0xf2, 0x25, 0xf4, 0x37, 0x49, 0xb8, 0xe5, 0x59, 0x4e, 0xfb, 0x63, 0x67, 0xe2, 0x4f, 0x47, 0xb5,
0x5f, 0x18, 0xb9, 0x72, 0x93, 0x8e, 0xbf, 0x16, 0xd7, 0xbc, 0x8f, 0x11, 0x54, 0x0c, 0x65, 0x28, 0x1f, 0xea, 0x99, 0xb6, 0x0b, 0x98, 0xf2, 0xf3, 0xe7, 0x72, 0x45, 0x07, 0x98, 0x41, 0xad, 0x10,
0x95, 0x59, 0x11, 0xe7, 0x19, 0x1f, 0x34, 0x0c, 0x09, 0xe4, 0x0b, 0x23, 0x57, 0xfe, 0x46, 0x49, 0x81, 0x32, 0x9e, 0x97, 0x49, 0x91, 0xd3, 0x61, 0x2b, 0x10, 0x43, 0x3d, 0xd3, 0x76, 0x81, 0x37,
0x28, 0xef, 0x38, 0x90, 0xbf, 0x48, 0xa0, 0xf9, 0x54, 0xde, 0x9e, 0xa3, 0xc4, 0xa3, 0x2c, 0x94, 0x4e, 0x23, 0xfe, 0x81, 0x82, 0xc4, 0x8b, 0x02, 0x86, 0xcf, 0xf8, 0xfd, 0x25, 0x5a, 0x7c, 0xb4,
0x0c, 0xf6, 0x39, 0xf4, 0x6f, 0x8a, 0x88, 0x52, 0xf4, 0x14, 0x85, 0x25, 0xcd, 0xbe, 0x04, 0xc0, 0xd4, 0x0a, 0xf2, 0x29, 0x0c, 0xee, 0xca, 0x58, 0x96, 0xe8, 0x29, 0x96, 0xa0, 0x92, 0xc9, 0xe7,
0x33, 0x25, 0xe8, 0x00, 0x13, 0x64, 0x71, 0x94, 0x3c, 0x94, 0x41, 0x2c, 0xd3, 0x59, 0x18, 0xa6, 0x00, 0xf8, 0x2d, 0x0b, 0x74, 0x80, 0x56, 0x43, 0x23, 0xec, 0x11, 0x0f, 0x13, 0x9e, 0x5d, 0x44,
0x7c, 0x48, 0xf2, 0x8a, 0xa3, 0x5e, 0x8e, 0xb2, 0x37, 0x41, 0x94, 0x47, 0xc9, 0x15, 0x1f, 0x8d, 0x51, 0x46, 0x0f, 0xa5, 0xbd, 0xd6, 0x88, 0x9d, 0xe3, 0xfc, 0x4d, 0x18, 0x17, 0x71, 0x7a, 0x43,
0x9d, 0x49, 0x5f, 0x54, 0x0c, 0xed, 0xd7, 0x25, 0x15, 0xee, 0x50, 0x87, 0x6d, 0x18, 0x2a, 0x96, 0x47, 0x63, 0x6b, 0x32, 0x60, 0xb5, 0x42, 0xe1, 0xba, 0x96, 0x07, 0x77, 0xa4, 0xd2, 0xd6, 0x0a,
0x74, 0x5d, 0x24, 0x21, 0x3f, 0x42, 0x09, 0x11, 0xfe, 0x6f, 0x0e, 0x74, 0x97, 0xf3, 0x45, 0x90, 0x91, 0x4b, 0xb6, 0x2e, 0xd3, 0x88, 0x1e, 0xa3, 0x45, 0x0a, 0xc1, 0x9f, 0x16, 0x78, 0x8b, 0xd9,
0x84, 0x4a, 0x61, 0x15, 0xa4, 0x61, 0xc6, 0x9d, 0x71, 0x5b, 0x29, 0x20, 0xa1, 0x5a, 0x81, 0xb2, 0x3c, 0x4c, 0x23, 0xe1, 0xb0, 0x0c, 0xb3, 0x28, 0xa7, 0xd6, 0xd8, 0x11, 0x0e, 0x28, 0x88, 0x56,
0x61, 0x5a, 0x81, 0x28, 0xc6, 0xa1, 0x17, 0x84, 0x61, 0x2a, 0xb3, 0x0c, 0x1b, 0x61, 0x20, 0x0c, 0x90, 0xd5, 0xd0, 0xad, 0x20, 0x25, 0x42, 0xa1, 0x1f, 0x46, 0x51, 0xc6, 0xf3, 0x5c, 0x35, 0x82,
0x89, 0x49, 0xcb, 0xde, 0x44, 0x09, 0x36, 0x40, 0x5f, 0x10, 0xa1, 0xd2, 0x12, 0xcb, 0x5b, 0x99, 0x16, 0xb1, 0x68, 0xf9, 0x9b, 0x38, 0xc5, 0x06, 0x18, 0x30, 0x29, 0x88, 0xb2, 0x24, 0xfc, 0x9e,
0x06, 0x57, 0x54, 0x7d, 0x57, 0x94, 0xb4, 0xff, 0x11, 0xfa, 0xa6, 0x88, 0xec, 0x19, 0xb8, 0xef, 0x67, 0xe1, 0x8d, 0x3c, 0x7d, 0x97, 0x55, 0xb2, 0x00, 0x8e, 0x68, 0xb0, 0x66, 0x9e, 0x6c, 0xab,
0x83, 0x44, 0x7b, 0xe1, 0x4d, 0x0f, 0xca, 0xda, 0x28, 0x1f, 0x05, 0xc9, 0xec, 0xc7, 0x5b, 0xf5, 0x4a, 0x11, 0xfc, 0x61, 0xc1, 0x40, 0x9f, 0x31, 0x79, 0x06, 0xee, 0x6d, 0x98, 0x2a, 0x90, 0xfe,
0xc7, 0x8f, 0xa1, 0x9b, 0x53, 0x76, 0xa9, 0x3d, 0x35, 0x85, 0xd1, 0xcb, 0x20, 0xdc, 0x1a, 0xa7, 0xf4, 0xa0, 0x3a, 0x3a, 0x91, 0x02, 0x93, 0x36, 0x13, 0x9b, 0xdd, 0xc4, 0x76, 0x02, 0x5e, 0x21,
0x90, 0xf0, 0xff, 0x70, 0xd4, 0xcb, 0x54, 0xf5, 0xff, 0xf6, 0xf2, 0x31, 0x74, 0x3f, 0x46, 0x49, 0x8b, 0xef, 0xe0, 0xb9, 0x29, 0x09, 0x8b, 0xc3, 0xc3, 0x68, 0xab, 0x31, 0xa3, 0x20, 0x70, 0xad,
0x22, 0x53, 0xfd, 0xb0, 0xa6, 0x6a, 0xe1, 0xb5, 0xeb, 0xe1, 0xa9, 0x3b, 0x54, 0x43, 0xfd, 0x25, 0xc2, 0x62, 0x79, 0x8b, 0xb8, 0x5c, 0x89, 0xab, 0x52, 0x04, 0x7f, 0x21, 0x2e, 0xd9, 0x32, 0xff,
0x34, 0xc5, 0x9e, 0xc3, 0x90, 0x4e, 0xaf, 0xea, 0x89, 0x69, 0x70, 0xfd, 0x97, 0xd0, 0xd3, 0x7f, 0x0d, 0xd7, 0x09, 0x78, 0xbf, 0xc6, 0x69, 0xca, 0x33, 0x05, 0x4b, 0x49, 0x8d, 0xda, 0x38, 0xad,
0x61, 0x4f, 0x8d, 0x38, 0xf4, 0x36, 0xeb, 0x28, 0xc9, 0xb5, 0x57, 0xae, 0x30, 0xa4, 0xff, 0x97, 0xda, 0x9c, 0x80, 0x27, 0x1b, 0x40, 0xdd, 0x27, 0x25, 0x91, 0xe7, 0x70, 0x28, 0xbf, 0x5e, 0x35,
0x03, 0x4f, 0x97, 0xf3, 0x5f, 0x82, 0x6b, 0x39, 0x5b, 0xe5, 0xd1, 0x3a, 0x61, 0xdf, 0x80, 0x8b, 0xab, 0xda, 0xd2, 0x06, 0x2f, 0xa1, 0xaf, 0x2e, 0x52, 0xc7, 0x01, 0x53, 0xe8, 0x6f, 0xd6, 0x71,
0x1f, 0x12, 0x3f, 0xbc, 0x37, 0x65, 0x65, 0x90, 0x4a, 0xe7, 0x52, 0x49, 0x16, 0x4f, 0x04, 0xa9, 0x5a, 0x28, 0x54, 0x2e, 0xd3, 0x62, 0xf0, 0x9b, 0x0d, 0x4f, 0x17, 0xb3, 0x9f, 0xc2, 0x15, 0xbf,
0xb0, 0x33, 0xe8, 0xaf, 0xd6, 0x49, 0x1e, 0x25, 0x85, 0x44, 0xbb, 0xde, 0xf4, 0xb3, 0x9a, 0xfa, 0x58, 0x16, 0xf1, 0x3a, 0x25, 0x5f, 0x81, 0x8b, 0xb7, 0x19, 0xd9, 0xc2, 0x9f, 0x92, 0x2a, 0x49,
0xcf, 0x5a, 0xb8, 0x78, 0x22, 0x4a, 0x45, 0xf6, 0x02, 0x3a, 0xaa, 0xa1, 0x31, 0x09, 0xde, 0xf4, 0xe1, 0x73, 0x2d, 0x2c, 0xf3, 0x27, 0x4c, 0xba, 0x90, 0x73, 0x18, 0x2c, 0xd7, 0x69, 0x11, 0xa7,
0xa8, 0x76, 0xe1, 0xa2, 0x88, 0x94, 0x79, 0x54, 0x50, 0x9e, 0xdc, 0x14, 0x32, 0xa5, 0x8a, 0x34, 0x25, 0xc7, 0xb8, 0xfe, 0xf4, 0x93, 0x86, 0xfb, 0x8f, 0xca, 0x38, 0x7f, 0xc2, 0x2a, 0x47, 0xf2,
0x3d, 0xb9, 0x50, 0x12, 0xe5, 0x09, 0xaa, 0xb0, 0x21, 0xb4, 0xf2, 0x2d, 0x7e, 0x42, 0x57, 0xb4, 0x02, 0x7a, 0xe2, 0x36, 0x60, 0x11, 0xfc, 0xe9, 0x71, 0x63, 0xc1, 0x55, 0x19, 0x8b, 0xf0, 0xe8,
0xf2, 0xed, 0xbc, 0xa7, 0x71, 0xc4, 0x9f, 0x81, 0x67, 0xb9, 0x5e, 0xe1, 0x8b, 0x63, 0xe3, 0x4b, 0x20, 0x90, 0xdc, 0x95, 0x3c, 0x93, 0xe7, 0xd5, 0x46, 0x72, 0x25, 0x2c, 0x02, 0x09, 0xba, 0x88,
0x0d, 0x0e, 0x5a, 0x0d, 0x38, 0xf0, 0x27, 0x30, 0xac, 0x87, 0xb3, 0x0f, 0x15, 0xfd, 0x13, 0x80, 0xa0, 0xe2, 0xf2, 0x63, 0x7d, 0xda, 0x41, 0x45, 0x57, 0x89, 0xa0, 0xc2, 0x81, 0x1c, 0x82, 0x5d,
0x2a, 0x8e, 0xbd, 0x5a, 0x5f, 0x19, 0x97, 0x30, 0x86, 0xbd, 0x6a, 0x37, 0xf0, 0x0c, 0x15, 0x48, 0x6c, 0xf1, 0xaa, 0xbb, 0xcc, 0x2e, 0xb6, 0xb3, 0xbe, 0x62, 0xab, 0xe0, 0x02, 0x7c, 0x23, 0xc7,
0xf7, 0x55, 0x94, 0xe5, 0xf3, 0x2d, 0xfd, 0xd4, 0x59, 0x12, 0x2e, 0x4b, 0xb0, 0xaa, 0x90, 0xd8, 0x9a, 0xc5, 0x2c, 0x93, 0xc5, 0x1a, 0xa4, 0x63, 0xb7, 0x48, 0x27, 0x98, 0xc0, 0x61, 0x33, 0xef,
0x69, 0x22, 0xf1, 0xfe, 0x98, 0x2a, 0xdc, 0x6a, 0x5b, 0xb8, 0xe5, 0xbf, 0x36, 0xbd, 0x20, 0xe4, 0x2e, 0xee, 0x0d, 0x4e, 0x01, 0xea, 0x84, 0x3b, 0xbd, 0xbe, 0xd0, 0x90, 0x30, 0xd9, 0x4e, 0xb7,
0x6a, 0x9d, 0x86, 0x8f, 0x46, 0xff, 0xdd, 0x56, 0x67, 0x70, 0x44, 0x56, 0x11, 0xfe, 0x1e, 0x30, 0x5f, 0x74, 0x30, 0x91, 0x68, 0x27, 0xdd, 0x57, 0xd4, 0x60, 0x1b, 0xd4, 0x50, 0xa7, 0xe9, 0x98,
0x5d, 0x9a, 0x68, 0xd9, 0x26, 0x7e, 0x82, 0x03, 0xdb, 0xb1, 0x8c, 0x7d, 0xa7, 0x20, 0x1a, 0x8f, 0x69, 0x1a, 0x77, 0xab, 0x37, 0x76, 0x8c, 0xbb, 0x15, 0xdc, 0xc1, 0x33, 0x04, 0x23, 0x37, 0x7c,
0xfa, 0x33, 0x7e, 0x52, 0xeb, 0x0e, 0x52, 0x13, 0x46, 0xc7, 0x5f, 0x00, 0xbb, 0xe7, 0x42, 0xc6, 0x15, 0xe7, 0xc5, 0x6c, 0x2b, 0xb9, 0xe7, 0x22, 0x8d, 0x16, 0x15, 0xfd, 0xd6, 0xb3, 0xc5, 0x6a,
0xa6, 0x4d, 0x23, 0xbc, 0x66, 0xc4, 0xd2, 0xad, 0x2c, 0x7d, 0x80, 0x91, 0x55, 0x95, 0xf3, 0xe4, 0xcf, 0x96, 0xee, 0xfa, 0xd5, 0x4c, 0xec, 0x18, 0x4c, 0x1c, 0xbc, 0xd6, 0x0d, 0xca, 0xf8, 0x72,
0xdd, 0x7a, 0x6f, 0x28, 0x0c, 0x3a, 0x0a, 0x74, 0x34, 0x0e, 0xe0, 0xd9, 0xca, 0x5c, 0x7b, 0x77, 0x9d, 0x45, 0x7b, 0xcf, 0xb3, 0xdd, 0x51, 0x2f, 0xe0, 0x58, 0x46, 0x45, 0x42, 0x7f, 0x24, 0x74,
0xe6, 0x3a, 0x76, 0xd8, 0x67, 0xe0, 0x09, 0xb9, 0x89, 0xf5, 0x63, 0xec, 0x04, 0x3a, 0xca, 0xb4, 0x15, 0xc2, 0x36, 0x43, 0xfc, 0x00, 0x07, 0x26, 0xb0, 0x9c, 0x7c, 0x23, 0x86, 0x0e, 0x7e, 0x2a,
0xfe, 0x99, 0x87, 0xc6, 0x59, 0x33, 0xac, 0x05, 0x4a, 0xfd, 0x6f, 0xe1, 0xb0, 0xe1, 0x21, 0xfe, 0x86, 0xf8, 0xa8, 0xd1, 0x87, 0xd2, 0x8d, 0x69, 0x9f, 0x60, 0x0e, 0xe4, 0x01, 0x84, 0x9c, 0x4c,
0x7f, 0x72, 0x8a, 0x22, 0x1d, 0x08, 0x43, 0xfa, 0x2f, 0x61, 0x64, 0x3d, 0xa1, 0xba, 0x8c, 0x3d, 0xdb, 0x41, 0x68, 0x23, 0x88, 0xe1, 0x5b, 0x47, 0x7a, 0x0f, 0x23, 0xe3, 0x54, 0x2e, 0xd3, 0x77,
0x07, 0x57, 0x49, 0x4d, 0x52, 0xee, 0xbf, 0x43, 0x62, 0x7f, 0x0e, 0xcc, 0x7a, 0x68, 0xbe, 0x15, 0xeb, 0xce, 0x54, 0x08, 0xf4, 0xc4, 0x59, 0x2a, 0x72, 0xc2, 0x6f, 0xa3, 0x72, 0xce, 0xee, 0xca,
0x6a, 0x5e, 0xfc, 0x5b, 0x61, 0x69, 0xba, 0xb4, 0xec, 0xe9, 0xf2, 0xb7, 0x03, 0xcc, 0x7a, 0xff, 0xf5, 0xcc, 0xb4, 0xcf, 0xc1, 0x67, 0x7c, 0x93, 0xa8, 0xcd, 0xc8, 0x29, 0xf4, 0x44, 0x68, 0x45,
0x21, 0x23, 0xfb, 0x1a, 0xef, 0x45, 0x39, 0x83, 0x08, 0x55, 0xee, 0x0d, 0x6c, 0x33, 0x94, 0x6a, 0x17, 0x47, 0x1a, 0xac, 0x7e, 0x7e, 0x30, 0xb4, 0x06, 0x5f, 0xc3, 0x51, 0x0b, 0x21, 0x92, 0x92,
0xf3, 0xb1, 0xd3, 0x9c, 0x8f, 0xbb, 0xb7, 0x0f, 0x6b, 0xaf, 0xe8, 0x3e, 0xb0, 0x57, 0xe0, 0x2c, 0x04, 0x25, 0x33, 0x1d, 0x32, 0x2d, 0x06, 0x2f, 0x61, 0x64, 0x6c, 0x21, 0xba, 0x8c, 0x3c, 0x07,
0xcc, 0x8b, 0x34, 0xe1, 0x3d, 0x1a, 0x2e, 0x44, 0xf9, 0x7f, 0xb6, 0xe0, 0x40, 0xc8, 0x95, 0x8c, 0x57, 0x58, 0x75, 0x51, 0x1e, 0xee, 0x23, 0xcd, 0xc1, 0x0c, 0x88, 0xb1, 0xd1, 0x6c, 0xcb, 0xb0,
0x36, 0xb9, 0xae, 0xe5, 0x63, 0x23, 0x34, 0xcd, 0xd4, 0xb6, 0x9a, 0x69, 0x67, 0xd3, 0xd4, 0x97, 0xcd, 0xf7, 0xba, 0x14, 0xc1, 0x3f, 0x16, 0x10, 0x63, 0xff, 0xc7, 0x82, 0x74, 0x35, 0xde, 0x8b,
0x0f, 0xb7, 0xb9, 0x7c, 0xd4, 0x60, 0xa1, 0xbb, 0x03, 0x16, 0x28, 0x01, 0xbd, 0x06, 0x3c, 0x56, 0x6a, 0xaa, 0x4a, 0xaa, 0x7b, 0xf0, 0x04, 0xd1, 0x63, 0xb6, 0x31, 0xf1, 0x7b, 0xed, 0x89, 0xbf,
0x49, 0xeb, 0x37, 0x93, 0xc6, 0xab, 0xf4, 0x0c, 0xa8, 0xb7, 0xec, 0x2d, 0xab, 0x5c, 0x37, 0x60, 0xfb, 0x3d, 0x65, 0xbc, 0x94, 0xbc, 0x47, 0x5e, 0x4a, 0x38, 0xdd, 0x8b, 0x32, 0x4b, 0x69, 0x5f,
0xef, 0xba, 0xe1, 0xd9, 0x0d, 0x81, 0x10, 0x74, 0x49, 0x1b, 0xa1, 0x90, 0x37, 0xff, 0x07, 0xb0, 0xce, 0x43, 0x29, 0x05, 0x7f, 0xdb, 0x70, 0xc0, 0xf8, 0x92, 0xc7, 0x9b, 0x42, 0x9d, 0xe5, 0xbe,
0xd9, 0x21, 0xb4, 0xdf, 0x49, 0xb3, 0x7e, 0xaa, 0xa3, 0xff, 0x23, 0x8c, 0x96, 0x73, 0x03, 0xdf, 0x19, 0xea, 0x66, 0x72, 0x8c, 0x66, 0xda, 0xd9, 0x34, 0xcd, 0xe7, 0x94, 0xdb, 0x7e, 0x4e, 0x35,
0x64, 0x78, 0x5f, 0x01, 0xf4, 0xe5, 0x56, 0x75, 0xf9, 0x07, 0x85, 0xd7, 0x17, 0xb8, 0x83, 0x3d, 0x68, 0xc1, 0xdb, 0x41, 0x0b, 0xb2, 0x00, 0xfd, 0x16, 0x15, 0xd7, 0x45, 0x1b, 0xb4, 0x8b, 0x46,
0xee, 0xe2, 0xf7, 0x6a, 0x1c, 0xe0, 0x17, 0x79, 0xd4, 0xbd, 0xb7, 0x5d, 0x5c, 0xc8, 0xcf, 0xfe, 0xeb, 0xf2, 0x0c, 0x65, 0x6f, 0x99, 0xef, 0xc6, 0xea, 0x01, 0x05, 0x9d, 0x0f, 0x28, 0xdf, 0x6c,
0x09, 0x00, 0x00, 0xff, 0xff, 0xda, 0x14, 0x34, 0x44, 0xa3, 0x0b, 0x00, 0x00, 0x08, 0xa4, 0xa0, 0x6b, 0xf9, 0xc6, 0x65, 0xfc, 0xee, 0xff, 0x0c, 0x07, 0x72, 0x04, 0xce, 0x3b,
0xae, 0x79, 0x56, 0x7c, 0x06, 0xdf, 0xc3, 0x68, 0x31, 0xd3, 0xa3, 0x42, 0x06, 0xee, 0x3a, 0x00,
0xb5, 0xd8, 0xae, 0x17, 0x7f, 0x27, 0x66, 0xc3, 0x15, 0xbe, 0x2a, 0xf7, 0x5b, 0xf8, 0xad, 0x98,
0x16, 0x78, 0x45, 0xf6, 0x5a, 0xf7, 0xd6, 0xc3, 0x5f, 0x8c, 0xf3, 0x7f, 0x03, 0x00, 0x00, 0xff,
0xff, 0xb4, 0x58, 0xec, 0xbf, 0x75, 0x0c, 0x00, 0x00,
} }
...@@ -46,6 +46,7 @@ func (t *PokerBullType) GetTypeMap() map[string]int32 { ...@@ -46,6 +46,7 @@ func (t *PokerBullType) GetTypeMap() map[string]int32 {
"Continue": PBGameActionContinue, "Continue": PBGameActionContinue,
"Quit": PBGameActionQuit, "Quit": PBGameActionQuit,
"Query": PBGameActionQuery, "Query": PBGameActionQuery,
"Play": PBGameActionPlay,
} }
} }
...@@ -56,5 +57,6 @@ func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo { ...@@ -56,5 +57,6 @@ func (t *PokerBullType) GetLogMap() map[int64]*types.LogInfo {
TyLogPBGameContinue: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameContinue"}, TyLogPBGameContinue: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameContinue"},
TyLogPBGameQuit: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameQuit"}, TyLogPBGameQuit: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameQuit"},
TyLogPBGameQuery: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameQuery"}, TyLogPBGameQuery: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGameQuery"},
TyLogPBGamePlay: {Ty: reflect.TypeOf(ReceiptPBGame{}), Name: "TyLogPBGamePlay"},
} }
} }
...@@ -47,5 +47,5 @@ func (ticket *Ticket) Query_MinerSourceList(param *types.ReqString) (types.Messa ...@@ -47,5 +47,5 @@ func (ticket *Ticket) Query_MinerSourceList(param *types.ReqString) (types.Messa
// Query_RandNumHash query randnumhash // Query_RandNumHash query randnumhash
func (ticket *Ticket) Query_RandNumHash(param *types.ReqRandHash) (types.Message, error) { func (ticket *Ticket) Query_RandNumHash(param *types.ReqRandHash) (types.Message, error) {
return ticket.GetRandNum(param.Height, param.BlockNum) return ticket.GetRandNum(param.Hash, param.BlockNum)
} }
...@@ -18,19 +18,20 @@ const ( ...@@ -18,19 +18,20 @@ const (
) )
// GetRandNum for ticket executor // GetRandNum for ticket executor
func (ticket *Ticket) GetRandNum(height int64, blockNum int64) (types.Message, error) { func (ticket *Ticket) GetRandNum(blockHash []byte, blockNum int64) (types.Message, error) {
tlog.Debug("GetRandNum", "height", height, "blockNum", blockNum) tlog.Debug("GetRandNum", "blockHash", blockHash, "blockNum", blockNum)
if blockNum < minBlockNum { if blockNum < minBlockNum {
blockNum = minBlockNum blockNum = minBlockNum
} else if blockNum > maxBlockNum { } else if blockNum > maxBlockNum {
blockNum = maxBlockNum blockNum = maxBlockNum
} }
if blockNum >= height { if len(blockHash) == 0 {
return nil, types.ErrNotFound return nil, types.ErrBlockNotFound
} }
txActions, err := ticket.getTxActions(height, blockNum) txActions, err := ticket.getTxActions(blockHash, blockNum)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -54,20 +55,36 @@ func (ticket *Ticket) GetRandNum(height int64, blockNum int64) (types.Message, e ...@@ -54,20 +55,36 @@ func (ticket *Ticket) GetRandNum(height int64, blockNum int64) (types.Message, e
return &types.ReplyHash{Hash: modify}, nil return &types.ReplyHash{Hash: modify}, nil
} }
func (ticket *Ticket) getTxActions(height int64, blockNum int64) ([]*tickettypes.TicketAction, error) { func (ticket *Ticket) getTxActions(blockHash []byte, blockNum int64) ([]*tickettypes.TicketAction, error) {
var txActions []*tickettypes.TicketAction var txActions []*tickettypes.TicketAction
var reqHashes types.ReqHashes
currHash := blockHash
tlog.Debug("getTxActions", "blockHash", blockHash, "blockNum", blockNum)
tlog.Debug("getTxActions", "height", height, "blockNum", blockNum) //根据blockHash,查询block,循环blockNum
for blockNum > 0 {
req := types.ReqHash{Hash: currHash}
req := &types.ReqBlocks{Start: height - blockNum + 1, End: height, IsDetail: false, Pid: []string{""}} tempBlock, err := ticket.GetAPI().GetBlockOverview(&req)
if err != nil {
return txActions, err
}
reqHashes.Hashes = append(reqHashes.Hashes, currHash)
currHash = tempBlock.Head.ParentHash
if tempBlock.Head.Height < 0 && blockNum > 1 {
return txActions, types.ErrBlockNotFound
}
blockNum--
}
blockDetails, err := ticket.GetAPI().GetBlocks(req) blockDetails, err := ticket.GetAPI().GetBlockByHashes(&reqHashes)
if err != nil { if err != nil {
tlog.Error("getTxActions", "height", height, "blockNum", blockNum, "err", err) tlog.Error("getTxActions", "blockHash", blockHash, "blockNum", blockNum, "err", err)
return txActions, err return txActions, err
} }
for _, block := range blockDetails.Items { for _, block := range blockDetails.Items {
//tlog.Debug("getTxActions", "blockHeight", block.Block.Height, "blockhash", block.Block.Hash()) tlog.Debug("getTxActions", "blockHeight", block.Block.Height, "blockhash", block.Block.Hash())
ticketAction, err := ticket.getMinerTx(block.Block) ticketAction, err := ticket.getMinerTx(block.Block)
if err != nil { if err != nil {
return txActions, err return txActions, err
......
...@@ -7,13 +7,13 @@ package commands ...@@ -7,13 +7,13 @@ package commands
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"os" "os"
"strconv" "strconv"
"strings" "strings"
"github.com/33cn/chain33/rpc/jsonclient" "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types" rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/system/dapp/commands"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
tokenty "github.com/33cn/plugin/plugin/dapp/token/types" tokenty "github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/spf13/cobra" "github.com/spf13/cobra"
...@@ -72,31 +72,7 @@ func addCreateTokenTransferFlags(cmd *cobra.Command) { ...@@ -72,31 +72,7 @@ func addCreateTokenTransferFlags(cmd *cobra.Command) {
} }
func createTokenTransfer(cmd *cobra.Command, args []string) { func createTokenTransfer(cmd *cobra.Command, args []string) {
toAddr, _ := cmd.Flags().GetString("to") commands.CreateAssetTransfer(cmd, args, tokenty.TokenX)
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
payload := &types.AssetsTransfer{
To: toAddr,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(tokenty.TokenX),
ActionName: "Transfer",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
} }
// CreateTokenTransferExecCmd create raw transfer tx // CreateTokenTransferExecCmd create raw transfer tx
...@@ -124,41 +100,7 @@ func addCreateTokenSendToExecFlags(cmd *cobra.Command) { ...@@ -124,41 +100,7 @@ func addCreateTokenSendToExecFlags(cmd *cobra.Command) {
} }
func createTokenSendToExec(cmd *cobra.Command, args []string) { func createTokenSendToExec(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName") commands.CreateAssetSendToExec(cmd, args, tokenty.TokenX)
exec, _ := cmd.Flags().GetString("exec")
exec = getRealExecName(paraName, exec)
to, err := GetExecAddr(exec)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
payload := &types.AssetsTransferToExec{
To: to,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
ExecName: exec,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(tokenty.TokenX),
ActionName: "TransferToExec",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
} }
// CreateTokenWithdrawCmd create raw withdraw tx // CreateTokenWithdrawCmd create raw withdraw tx
...@@ -186,40 +128,7 @@ func addCreateTokenWithdrawFlags(cmd *cobra.Command) { ...@@ -186,40 +128,7 @@ func addCreateTokenWithdrawFlags(cmd *cobra.Command) {
} }
func createTokenWithdraw(cmd *cobra.Command, args []string) { func createTokenWithdraw(cmd *cobra.Command, args []string) {
exec, _ := cmd.Flags().GetString("exec") commands.CreateAssetWithdraw(cmd, args, tokenty.TokenX)
paraName, _ := cmd.Flags().GetString("paraName")
exec = getRealExecName(paraName, exec)
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
exec = getRealExecName(paraName, exec)
execAddr, err := GetExecAddr(exec)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
payload := &types.AssetsWithdraw{
To: execAddr,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
ExecName: exec,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpctypes.CreateTxIn{
Execer: types.ExecName(tokenty.TokenX),
ActionName: "Withdraw",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
} }
// GetTokensPreCreatedCmd get precreated tokens // GetTokensPreCreatedCmd get precreated tokens
......
...@@ -20,6 +20,11 @@ chain33背后故事: [chain33诞生记](https://mp.weixin.qq.com/s/9g5ZFDKJi9uzR ...@@ -20,6 +20,11 @@ chain33背后故事: [chain33诞生记](https://mp.weixin.qq.com/s/9g5ZFDKJi9uzR
视频教程: [视频教程](https://chain.33.cn/document/90) 视频教程: [视频教程](https://chain.33.cn/document/90)
# 感谢
[腾讯玄武实验室](https://github.com/33cn/chain33/issues?utf8=%E2%9C%93&q=label%3A%E8%85%BE%E8%AE%AF%E7%8E%84%E6%AD%A6%E5%AE%9E%E9%AA%8C%E5%AE%A4)
## Building from source ## Building from source
环境要求: Go (version 1.9 or later) 环境要求: Go (version 1.9 or later)
......
...@@ -276,8 +276,8 @@ func (acc *DB) loadAccountsHistory(api client.QueueProtocolAPI, addrs []string, ...@@ -276,8 +276,8 @@ func (acc *DB) loadAccountsHistory(api client.QueueProtocolAPI, addrs []string,
// GetBalance 获取某个状态下账户余额 // GetBalance 获取某个状态下账户余额
func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([]*types.Account, error) { func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([]*types.Account, error) {
switch in.GetExecer() { // load account
case types.ExecName("coins"): if in.AssetExec == in.Execer || "" == in.Execer {
addrs := in.GetAddresses() addrs := in.GetAddresses()
var exaddrs []string var exaddrs []string
for _, addr := range addrs { for _, addr := range addrs {
...@@ -306,7 +306,9 @@ func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([] ...@@ -306,7 +306,9 @@ func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([]
} }
} }
return accounts, nil return accounts, nil
default: }
// load exec account
execaddress := address.ExecAddress(in.GetExecer()) execaddress := address.ExecAddress(in.GetExecer())
addrs := in.GetAddresses() addrs := in.GetAddresses()
var accounts []*types.Account var accounts []*types.Account
...@@ -333,7 +335,6 @@ func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([] ...@@ -333,7 +335,6 @@ func (acc *DB) GetBalance(api client.QueueProtocolAPI, in *types.ReqBalance) ([]
accounts = append(accounts, account) accounts = append(accounts, account)
} }
return accounts, nil return accounts, nil
}
} }
// GetExecBalance 通过account模块获取地址账户在合约中的余额 // GetExecBalance 通过account模块获取地址账户在合约中的余额
......
...@@ -108,21 +108,24 @@ function start_chain33() { ...@@ -108,21 +108,24 @@ function start_chain33() {
echo "=========== #transfer to miner addr =============" echo "=========== #transfer to miner addr ============="
hash=$(${CLI} send coins transfer -a 10000 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944) hash=$(${CLI} send coins transfer -a 10000 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
echo "=========== #transfer to token amdin =============" echo "=========== #transfer to token amdin ============="
hash=$(${CLI} send coins transfer -a 10 -n test -t 1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944) hash=$(${CLI} send coins transfer -a 10 -n test -t 1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
...@@ -131,10 +134,12 @@ function start_chain33() { ...@@ -131,10 +134,12 @@ function start_chain33() {
signData=$(${CLI} wallet sign -d "${rawData}" -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc) signData=$(${CLI} wallet sign -d "${rawData}" -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
hash=$(${CLI} wallet send -d "${signData}") hash=$(${CLI} wallet send -d "${signData}")
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
......
...@@ -121,21 +121,24 @@ function start_chain33() { ...@@ -121,21 +121,24 @@ function start_chain33() {
echo "=========== #transfer to miner addr =============" echo "=========== #transfer to miner addr ============="
hash=$(${CLI} send coins transfer -a 10000 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944) hash=$(${CLI} send coins transfer -a 10000 -n test -t 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
echo "=========== #transfer to token amdin =============" echo "=========== #transfer to token amdin ============="
hash=$(${CLI} send coins transfer -a 10 -n test -t 1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944) hash=$(${CLI} send coins transfer -a 10 -n test -t 1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK -k CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944)
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
...@@ -144,10 +147,12 @@ function start_chain33() { ...@@ -144,10 +147,12 @@ function start_chain33() {
signData=$(${CLI} wallet sign -d "${rawData}" -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc) signData=$(${CLI} wallet sign -d "${rawData}" -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
hash=$(${CLI} wallet send -d "${signData}") hash=$(${CLI} wallet send -d "${signData}")
echo "${hash}"
sleep ${chain33BlockTime} sleep ${chain33BlockTime}
txs=$(${CLI} tx query_hash -s "${hash}" | jq ".txs") result=$(${CLI} tx query -s "${hash}" | jq '.receipt.tyName')
if [ "${txs}" == "null" ]; then if [[ ${result} != '"ExecOk"' ]]; then
echo "transferTokenAdmin cannot find tx" echo "Failed"
${CLI} tx query -s "${hash}" | jq '.' | cat
exit 1 exit 1
fi fi
......
...@@ -206,7 +206,20 @@ func (c *channelClient) GetAddrOverview(parm *types.ReqAddr) (*types.AddrOvervie ...@@ -206,7 +206,20 @@ func (c *channelClient) GetAddrOverview(parm *types.ReqAddr) (*types.AddrOvervie
// GetBalance get balance // GetBalance get balance
func (c *channelClient) GetBalance(in *types.ReqBalance) ([]*types.Account, error) { func (c *channelClient) GetBalance(in *types.ReqBalance) ([]*types.Account, error) {
// in.AssetExec & in.AssetSymbol 新增参数,
// 不填时兼容原来的调用
if in.AssetExec == "" || in.AssetSymbol == "" {
in.AssetSymbol = "bty"
in.AssetExec = "coins"
return c.accountdb.GetBalance(c.QueueProtocolAPI, in) return c.accountdb.GetBalance(c.QueueProtocolAPI, in)
}
acc, err := account.NewAccountDB(in.AssetExec, in.AssetSymbol, nil)
if err != nil {
log.Error("GetBalance", "Error", err.Error())
return nil, err
}
return acc.GetBalance(c.QueueProtocolAPI, in)
} }
// GetAllExecBalance get balance of exec // GetAllExecBalance get balance of exec
...@@ -288,3 +301,49 @@ func (c *channelClient) GetExecBalance(in *types.ReqGetExecBalance) (*types.Repl ...@@ -288,3 +301,49 @@ func (c *channelClient) GetExecBalance(in *types.ReqGetExecBalance) (*types.Repl
} }
return resp, nil return resp, nil
} }
// GetAssetBalance 通用的获得资产的接口
func (c *channelClient) GetAssetBalance(in *types.ReqBalance) ([]*types.Account, error) {
if in.AssetSymbol == "" || in.AssetExec == "" {
return nil, types.ErrInvalidParam
}
acc, err := account.NewAccountDB(in.AssetExec, in.AssetSymbol, nil)
if err != nil {
return nil, err
}
// load balance
if in.AssetExec == in.Execer || in.Execer == "" {
addrs := in.GetAddresses()
var queryAddrs []string
for _, addr := range addrs {
if err := address.CheckAddress(addr); err != nil {
addr = string(acc.AccountKey(addr))
}
queryAddrs = append(queryAddrs, addr)
}
accounts, err := acc.LoadAccounts(c.QueueProtocolAPI, queryAddrs)
if err != nil {
log.Error("GetAssetBalance", "err", err.Error(), "exec", in.AssetExec, "symbol", in.AssetSymbol,
"address", queryAddrs)
return nil, err
}
return accounts, nil
}
// load exec balance
execaddress := address.ExecAddress(in.GetExecer())
addrs := in.GetAddresses()
var accounts []*types.Account
for _, addr := range addrs {
acc, err := acc.LoadExecAccountQueue(c.QueueProtocolAPI, addr, execaddress)
if err != nil {
log.Error("GetAssetBalance for exector", "err", err.Error(), "exec", in.AssetExec,
"symbol", in.AssetSymbol, "address", addr, "where", in.Execer)
continue
}
accounts = append(accounts, acc)
}
return accounts, nil
}
...@@ -361,3 +361,66 @@ func TestChannelClient_GetBalance(t *testing.T) { ...@@ -361,3 +361,66 @@ func TestChannelClient_GetBalance(t *testing.T) {
// assert.NotNil(t, data) // assert.NotNil(t, data)
// assert.Nil(t, err) // assert.Nil(t, err)
// } // }
func testChannelClient_GetAssetBalanceCoin(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
db := new(account.DB)
client := &channelClient{
QueueProtocolAPI: api,
accountdb: db,
}
head := &types.Header{StateHash: []byte("sdfadasds")}
api.On("GetLastHeader").Return(head, nil)
var acc = &types.Account{Addr: "1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt", Balance: 100}
accv := types.Encode(acc)
storevalue := &types.StoreReplyValue{}
storevalue.Values = append(storevalue.Values, accv)
api.On("StoreGet", mock.Anything).Return(storevalue, nil)
var addrs = []string{"1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt"}
var in = &types.ReqBalance{
AssetSymbol: "bty",
AssetExec: "coins",
Execer: "coins",
Addresses: addrs,
}
data, err := client.GetAssetBalance(in)
assert.Nil(t, err)
assert.Equal(t, acc.Addr, data[0].Addr)
}
func testChannelClient_GetAssetBalanceOther(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
db := new(account.DB)
client := &channelClient{
QueueProtocolAPI: api,
accountdb: db,
}
head := &types.Header{StateHash: []byte("sdfadasds")}
api.On("GetLastHeader").Return(head, nil)
var acc = &types.Account{Addr: "1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt", Balance: 100}
accv := types.Encode(acc)
storevalue := &types.StoreReplyValue{}
storevalue.Values = append(storevalue.Values, accv)
api.On("StoreGet", mock.Anything).Return(storevalue, nil)
var addrs = []string{"1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt"}
var in = &types.ReqBalance{
AssetSymbol: "bty",
AssetExec: "coins",
Execer: types.ExecName("ticket"),
Addresses: addrs,
}
data, err := client.GetAssetBalance(in)
assert.Nil(t, err)
assert.Equal(t, acc.Addr, data[0].Addr)
}
func TestChannelClient_GetAssetBalance(t *testing.T) {
testChannelClient_GetAssetBalanceCoin(t)
testChannelClient_GetAssetBalanceOther(t)
}
...@@ -741,19 +741,12 @@ func (c *Chain33) GetWalletStatus(in types.ReqNil, result *interface{}) error { ...@@ -741,19 +741,12 @@ func (c *Chain33) GetWalletStatus(in types.ReqNil, result *interface{}) error {
// GetBalance get balance // GetBalance get balance
func (c *Chain33) GetBalance(in types.ReqBalance, result *interface{}) error { func (c *Chain33) GetBalance(in types.ReqBalance, result *interface{}) error {
balances, err := c.cli.GetBalance(&in) balances, err := c.cli.GetBalance(&in)
if err != nil { if err != nil {
return err return err
} }
var accounts []*rpctypes.Account
for _, balance := range balances { *result = fmtAccount(balances)
accounts = append(accounts, &rpctypes.Account{Addr: balance.GetAddr(),
Balance: balance.GetBalance(),
Currency: balance.GetCurrency(),
Frozen: balance.GetFrozen()})
}
*result = accounts
return nil return nil
} }
...@@ -1209,3 +1202,14 @@ func convertBlockDetails(details []*types.BlockDetail, retDetails *rpctypes.Bloc ...@@ -1209,3 +1202,14 @@ func convertBlockDetails(details []*types.BlockDetail, retDetails *rpctypes.Bloc
} }
return nil return nil
} }
func fmtAccount(balances []*types.Account) []*rpctypes.Account {
var accounts []*rpctypes.Account
for _, balance := range balances {
accounts = append(accounts, &rpctypes.Account{Addr: balance.GetAddr(),
Balance: balance.GetBalance(),
Currency: balance.GetCurrency(),
Frozen: balance.GetFrozen()})
}
return accounts
}
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"encoding/hex" "encoding/hex"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client/mocks" "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
rpctypes "github.com/33cn/chain33/rpc/types" rpctypes "github.com/33cn/chain33/rpc/types"
...@@ -373,6 +374,7 @@ func newTestChain33(api *mocks.QueueProtocolAPI) *Chain33 { ...@@ -373,6 +374,7 @@ func newTestChain33(api *mocks.QueueProtocolAPI) *Chain33 {
return &Chain33{ return &Chain33{
cli: channelClient{ cli: channelClient{
QueueProtocolAPI: api, QueueProtocolAPI: api,
accountdb: account.NewCoinsAccount(),
}, },
} }
} }
...@@ -1290,3 +1292,58 @@ func TestChain33_GetExecBalance(t *testing.T) { ...@@ -1290,3 +1292,58 @@ func TestChain33_GetExecBalance(t *testing.T) {
err = client.GetExecBalance(in, &testResult2) err = client.GetExecBalance(in, &testResult2)
assert.NotNil(t, err) assert.NotNil(t, err)
} }
func TestChain33_GetBalance(t *testing.T) {
api := new(mocks.QueueProtocolAPI)
client := newTestChain33(api)
var addrs = []string{"1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt"}
cases := []struct {
In types.ReqBalance
}{
{In: types.ReqBalance{
Execer: types.ExecName("coins"),
Addresses: addrs,
}},
{In: types.ReqBalance{
Execer: types.ExecName("ticket"),
Addresses: addrs,
}},
{In: types.ReqBalance{
AssetSymbol: "bty",
AssetExec: "coins",
Execer: types.ExecName("ticket"),
Addresses: addrs,
}},
{In: types.ReqBalance{
AssetSymbol: "bty",
AssetExec: "coins",
Execer: types.ExecName("coins"),
Addresses: addrs,
}},
}
for _, c := range cases {
c := c
t.Run("test GetBalance", func(t *testing.T) {
head := &types.Header{StateHash: []byte("sdfadasds")}
api.On("GetLastHeader").Return(head, nil)
var acc = &types.Account{Addr: "1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt", Balance: 100}
accv := types.Encode(acc)
storevalue := &types.StoreReplyValue{}
storevalue.Values = append(storevalue.Values, accv)
api.On("StoreGet", mock.Anything).Return(storevalue, nil)
var data interface{}
err := client.GetBalance(c.In, &data)
assert.Nil(t, err)
result := data.([]*rpctypes.Account)
assert.Equal(t, 1, len(result))
//t.Error("result", "x", result)
assert.Equal(t, acc.Addr, result[0].Addr)
assert.Equal(t, int64(100), result[0].Balance)
})
}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"encoding/json"
"fmt"
"math"
"os"
"strings"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/rpc/jsonclient"
rpcTypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
"github.com/spf13/cobra"
)
// AssetCmd command
func AssetCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "asset",
Short: "Asset query",
Args: cobra.MinimumNArgs(1),
}
cmd.AddCommand(
GetAssetBalanceCmd(),
)
return cmd
}
// GetAssetBalanceCmd query asset balance
func GetAssetBalanceCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "balance",
Short: "Query asset balance",
Run: assetBalance,
}
addAssetBalanceFlags(cmd)
return cmd
}
func addAssetBalanceFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "account addr")
cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("exec", "e", "", getExecuterNameString())
cmd.Flags().StringP("asset_exec", "", "coins", "the asset executor")
cmd.MarkFlagRequired("asset_exec")
cmd.Flags().StringP("asset_symbol", "", "bty", "the asset symbol")
cmd.MarkFlagRequired("asset_symbol")
cmd.Flags().IntP("height", "", -1, "block height")
}
func assetBalance(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
addr, _ := cmd.Flags().GetString("addr")
execer, _ := cmd.Flags().GetString("exec")
asset_symbol, _ := cmd.Flags().GetString("asset_symbol")
asset_exec, _ := cmd.Flags().GetString("asset_exec")
height, _ := cmd.Flags().GetInt("height")
err := address.CheckAddress(addr)
if err != nil {
if err = address.CheckMultiSignAddress(addr); err != nil {
fmt.Fprintln(os.Stderr, types.ErrInvalidAddress)
return
}
}
if execer == "" {
execer = asset_exec
}
if ok := types.IsAllowExecName([]byte(execer), []byte(execer)); !ok {
fmt.Fprintln(os.Stderr, types.ErrExecNameNotAllow)
return
}
stateHash := ""
if height >= 0 {
params := types.ReqBlocks{
Start: int64(height),
End: int64(height),
IsDetail: false,
}
var res rpcTypes.Headers
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.GetHeaders", params, &res)
_, err := ctx.RunResult()
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
h := res.Items[0]
stateHash = h.StateHash
}
var addrs []string
addrs = append(addrs, addr)
params := types.ReqBalance{
Addresses: addrs,
Execer: execer,
StateHash: stateHash,
AssetExec: asset_exec,
AssetSymbol: asset_symbol,
}
var res []*rpcTypes.Account
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.GetBalance", params, &res)
ctx.SetResultCb(parseGetBalanceRes)
ctx.Run()
}
// CreateAssetSendToExec 通用的创建 send_exec 交易, 额外指定资产合约
func CreateAssetSendToExec(cmd *cobra.Command, args []string, fromExec string) {
paraName, _ := cmd.Flags().GetString("paraName")
exec, _ := cmd.Flags().GetString("exec")
exec = getRealExecName(paraName, exec)
to, err := GetExecAddr(exec)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
payload := &types.AssetsTransferToExec{
To: to,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
ExecName: exec,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec),
ActionName: "TransferToExec",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
// CreateAssetWithdraw 通用的创建 withdraw 交易, 额外指定资产合约
func CreateAssetWithdraw(cmd *cobra.Command, args []string, fromExec string) {
exec, _ := cmd.Flags().GetString("exec")
paraName, _ := cmd.Flags().GetString("paraName")
exec = getRealExecName(paraName, exec)
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
exec = getRealExecName(paraName, exec)
execAddr, err := GetExecAddr(exec)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
payload := &types.AssetsWithdraw{
To: execAddr,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
ExecName: exec,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec),
ActionName: "Withdraw",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
// CreateAssetTransfer 通用的创建 transfer 交易, 额外指定资产合约
func CreateAssetTransfer(cmd *cobra.Command, args []string, fromExec string) {
toAddr, _ := cmd.Flags().GetString("to")
amount, _ := cmd.Flags().GetFloat64("amount")
note, _ := cmd.Flags().GetString("note")
symbol, _ := cmd.Flags().GetString("symbol")
payload := &types.AssetsTransfer{
To: toAddr,
Amount: int64(math.Trunc((amount+0.0000001)*1e4)) * 1e4,
Note: []byte(note),
Cointoken: symbol,
}
data, err := json.Marshal(&payload)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return
}
params := &rpcTypes.CreateTxIn{
Execer: types.ExecName(fromExec),
ActionName: "Transfer",
Payload: data,
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
// GetExecAddr 获取执行器地址
func GetExecAddr(exec string) (string, error) {
if ok := types.IsAllowExecName([]byte(exec), []byte(exec)); !ok {
return "", types.ErrExecNameNotAllow
}
addrResult := address.ExecAddress(exec)
result := addrResult
return result, nil
}
func getRealExecName(paraName string, name string) string {
if strings.HasPrefix(name, "user.p.") {
return name
}
return paraName + name
}
...@@ -205,6 +205,8 @@ type ReqBalance struct { ...@@ -205,6 +205,8 @@ type ReqBalance struct {
//执行器名称 //执行器名称
Execer string `protobuf:"bytes,2,opt,name=execer,proto3" json:"execer,omitempty"` Execer string `protobuf:"bytes,2,opt,name=execer,proto3" json:"execer,omitempty"`
StateHash string `protobuf:"bytes,3,opt,name=stateHash,proto3" json:"stateHash,omitempty"` StateHash string `protobuf:"bytes,3,opt,name=stateHash,proto3" json:"stateHash,omitempty"`
AssetExec string `protobuf:"bytes,4,opt,name=asset_exec,json=assetExec,proto3" json:"asset_exec,omitempty"`
AssetSymbol string `protobuf:"bytes,5,opt,name=asset_symbol,json=assetSymbol,proto3" json:"asset_symbol,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -256,6 +258,20 @@ func (m *ReqBalance) GetStateHash() string { ...@@ -256,6 +258,20 @@ func (m *ReqBalance) GetStateHash() string {
return "" return ""
} }
func (m *ReqBalance) GetAssetExec() string {
if m != nil {
return m.AssetExec
}
return ""
}
func (m *ReqBalance) GetAssetSymbol() string {
if m != nil {
return m.AssetSymbol
}
return ""
}
// Account 的列表 // Account 的列表
type Accounts struct { type Accounts struct {
Acc []*Account `protobuf:"bytes,1,rep,name=acc,proto3" json:"acc,omitempty"` Acc []*Account `protobuf:"bytes,1,rep,name=acc,proto3" json:"acc,omitempty"`
...@@ -403,28 +419,30 @@ func init() { ...@@ -403,28 +419,30 @@ func init() {
func init() { proto.RegisterFile("account.proto", fileDescriptor_8e28828dcb8d24f0) } func init() { proto.RegisterFile("account.proto", fileDescriptor_8e28828dcb8d24f0) }
var fileDescriptor_8e28828dcb8d24f0 = []byte{ var fileDescriptor_8e28828dcb8d24f0 = []byte{
// 360 bytes of a gzipped FileDescriptorProto // 399 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0x41, 0x4f, 0x32, 0x31, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xc1, 0x8e, 0xd3, 0x30,
0x10, 0x4d, 0x59, 0x60, 0xd9, 0x21, 0x1f, 0x87, 0x1e, 0xc8, 0x86, 0x7c, 0xc6, 0xcd, 0x9e, 0xf6, 0x10, 0x95, 0x9b, 0x76, 0xb3, 0x99, 0xc2, 0x1e, 0x7c, 0x58, 0x59, 0x2b, 0x56, 0x84, 0x9c, 0x72,
0x60, 0x96, 0xc4, 0xf5, 0x0f, 0x40, 0x62, 0xe2, 0xcd, 0xa4, 0xf1, 0xc4, 0xc9, 0x52, 0x06, 0x21, 0x40, 0xa9, 0x44, 0xf8, 0x81, 0x56, 0x42, 0xe2, 0x86, 0x64, 0x38, 0xf5, 0x82, 0x1c, 0x77, 0x4a,
0x62, 0x77, 0x6d, 0x8b, 0x11, 0x7f, 0x80, 0xbf, 0xdb, 0xb4, 0x74, 0x61, 0x91, 0x68, 0xbc, 0xf5, 0x2b, 0xd2, 0x24, 0xd8, 0x2e, 0xa2, 0x7c, 0x00, 0x1f, 0xc2, 0x97, 0x22, 0x4f, 0x9d, 0x36, 0xa5,
0xcd, 0xeb, 0xbc, 0xf7, 0x66, 0x5a, 0xf8, 0xc7, 0x85, 0x28, 0xb7, 0xd2, 0xe4, 0x95, 0x2a, 0x4d, 0x02, 0xed, 0xad, 0xf3, 0xde, 0xcc, 0xbc, 0xe7, 0xd7, 0x09, 0x3c, 0x57, 0x5a, 0xb7, 0xfb, 0xc6,
0x49, 0x3b, 0x66, 0x57, 0xa1, 0x4e, 0x9f, 0x21, 0x9c, 0xec, 0xeb, 0x74, 0x04, 0x3d, 0xb1, 0x55, 0x15, 0x9d, 0x69, 0x5d, 0xcb, 0x27, 0xee, 0xd0, 0xa1, 0xcd, 0xbe, 0x42, 0x3c, 0x3f, 0xe2, 0xfc,
0x0a, 0xa5, 0xd8, 0xc5, 0x24, 0x21, 0x59, 0x87, 0x1d, 0x30, 0x8d, 0x21, 0x9c, 0xf3, 0x0d, 0x97, 0x01, 0x6e, 0xf5, 0xde, 0x18, 0x6c, 0xf4, 0x41, 0xb0, 0x94, 0xe5, 0x13, 0x79, 0xaa, 0xb9, 0x80,
0x02, 0xe3, 0x56, 0x42, 0xb2, 0x80, 0xd5, 0x90, 0x0e, 0xa1, 0xbb, 0x54, 0xe5, 0x07, 0xca, 0x38, 0xb8, 0x52, 0xb5, 0x6a, 0x34, 0x8a, 0x51, 0xca, 0xf2, 0x48, 0xf6, 0x25, 0xbf, 0x87, 0x9b, 0xb5,
0x70, 0x84, 0x47, 0x94, 0x42, 0x9b, 0x2f, 0x16, 0x2a, 0x6e, 0x27, 0x24, 0x8b, 0x98, 0x3b, 0xa7, 0x69, 0x7f, 0x62, 0x23, 0x22, 0x22, 0x42, 0xc5, 0x39, 0x8c, 0xd5, 0x6a, 0x65, 0xc4, 0x38, 0x65,
0x9f, 0x04, 0x46, 0x0c, 0x05, 0xae, 0x2b, 0x73, 0xfb, 0x8e, 0xc2, 0x1b, 0x3f, 0x28, 0x2e, 0xf5, 0x79, 0x22, 0xe9, 0x77, 0xf6, 0x8b, 0xc1, 0x83, 0x44, 0x8d, 0xdb, 0xce, 0xbd, 0xfb, 0x81, 0x3a,
0x12, 0x95, 0x0d, 0x80, 0xb6, 0x6c, 0xdb, 0x88, 0x6b, 0x3b, 0x60, 0x9a, 0x42, 0xbb, 0x52, 0xf8, 0x08, 0x7f, 0x32, 0xaa, 0xb1, 0x6b, 0x34, 0xde, 0x00, 0x7a, 0xd8, 0x8f, 0x31, 0x1a, 0x3b, 0xd5,
0xe6, 0xdc, 0xfb, 0xd7, 0x83, 0xdc, 0xa5, 0xcf, 0xbd, 0x02, 0x73, 0x1c, 0xcd, 0x20, 0xdc, 0x07, 0x3c, 0x83, 0x71, 0x67, 0xf0, 0x3b, 0xa9, 0x4f, 0xdf, 0xdc, 0x15, 0xe4, 0xbe, 0x08, 0x1b, 0x24,
0x36, 0x2e, 0xcb, 0xf9, 0xb5, 0x9a, 0x4e, 0x97, 0x30, 0xf4, 0x39, 0xbe, 0x67, 0xa8, 0x7d, 0xc8, 0x71, 0x3c, 0x87, 0xf8, 0x68, 0xd8, 0x91, 0x97, 0xeb, 0xb6, 0x9e, 0xce, 0xd6, 0x70, 0x1f, 0x7c,
0xdf, 0x7c, 0x5a, 0xbf, 0xfb, 0x3c, 0x02, 0x30, 0x7c, 0x9d, 0xfa, 0x55, 0xfd, 0x87, 0xc8, 0xae, 0xfc, 0xed, 0xa1, 0xd7, 0x61, 0x4f, 0xd3, 0x19, 0xfd, 0x5f, 0xe7, 0x37, 0x03, 0x90, 0xf8, 0x6d,
0x01, 0xb5, 0x46, 0x1d, 0x93, 0x24, 0xc8, 0x22, 0x76, 0x2c, 0xd8, 0x45, 0xda, 0x69, 0x51, 0x39, 0x11, 0xb2, 0x7a, 0x01, 0x89, 0xcf, 0x01, 0xad, 0x45, 0x2b, 0x58, 0x1a, 0xe5, 0x89, 0x3c, 0x03,
0xd1, 0x88, 0x79, 0x64, 0xbb, 0xb4, 0xe1, 0x06, 0xef, 0xb8, 0x5e, 0xb9, 0xb9, 0x22, 0x76, 0x2c, 0x3e, 0x49, 0xff, 0x5c, 0x34, 0xb4, 0x35, 0x91, 0xa1, 0xf2, 0x53, 0xd6, 0x29, 0x87, 0xef, 0x95,
0xa4, 0x57, 0xd0, 0xf3, 0xae, 0x9a, 0x26, 0x10, 0x70, 0x21, 0x9c, 0xf2, 0x79, 0x26, 0x4b, 0xa5, 0xdd, 0xd0, 0xc3, 0x12, 0x79, 0x06, 0xf8, 0x23, 0x80, 0xb2, 0x16, 0xdd, 0x67, 0xdf, 0x1d, 0xd2,
0xf7, 0xd0, 0x6f, 0x2c, 0xbe, 0x61, 0x49, 0x4e, 0x2c, 0x33, 0x08, 0xfd, 0x67, 0xf9, 0x69, 0x40, 0x4e, 0x08, 0xf1, 0x11, 0xf3, 0x57, 0xf0, 0xec, 0x48, 0xdb, 0xc3, 0xae, 0x6a, 0x6b, 0x31, 0xa1,
0x4f, 0xa7, 0x33, 0x18, 0x4c, 0x36, 0x1b, 0xab, 0x59, 0x0f, 0x59, 0xbf, 0x3b, 0x39, 0xbe, 0x3b, 0x86, 0x29, 0x61, 0x1f, 0x09, 0xca, 0x5e, 0xc3, 0x6d, 0x30, 0x6e, 0x79, 0x0a, 0x91, 0xd2, 0x9a,
0xbd, 0x39, 0xb1, 0x8d, 0x5b, 0x2e, 0x20, 0xf5, 0x9a, 0x0d, 0x86, 0x35, 0xaf, 0x4d, 0x2f, 0x67, 0xbc, 0x5d, 0x3f, 0xcb, 0x53, 0xd9, 0x07, 0x98, 0x0e, 0xfe, 0xbb, 0x81, 0x69, 0x76, 0x61, 0x3a,
0x17, 0x4f, 0x6b, 0xb3, 0xda, 0xce, 0x73, 0x51, 0xbe, 0x8c, 0x8b, 0x42, 0xc8, 0xb1, 0x58, 0xf1, 0x87, 0x38, 0xdc, 0xdb, 0xbf, 0x32, 0x0a, 0x74, 0xb6, 0x84, 0xbb, 0x79, 0x5d, 0xfb, 0x9d, 0x7d,
0xb5, 0x2c, 0x8a, 0xb1, 0xeb, 0x9c, 0x77, 0xdd, 0x4f, 0x2e, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xfd, 0xe9, 0xb0, 0xf3, 0xe9, 0xf0, 0xb7, 0x17, 0xb2, 0x62, 0x44, 0x06, 0x79, 0xd8, 0x39,
0x7b, 0xae, 0x1c, 0x1e, 0xda, 0x02, 0x00, 0x00, 0x60, 0xe4, 0xb0, 0x6d, 0xf1, 0x72, 0xf9, 0xf8, 0x65, 0xeb, 0x36, 0xfb, 0xaa, 0xd0, 0xed, 0x6e,
0x56, 0x96, 0xba, 0x99, 0xe9, 0x8d, 0xda, 0x36, 0x65, 0x39, 0xa3, 0xc9, 0xea, 0x86, 0x3e, 0x86,
0xf2, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb3, 0x61, 0x7c, 0x60, 0x1d, 0x03, 0x00, 0x00,
} }
...@@ -40,6 +40,8 @@ message ReqBalance { ...@@ -40,6 +40,8 @@ message ReqBalance {
//执行器名称 //执行器名称
string execer = 2; string execer = 2;
string stateHash = 3; string stateHash = 3;
string asset_exec = 4;
string asset_symbol = 5;
} }
// Account 的列表 // Account 的列表
......
...@@ -60,6 +60,7 @@ func init() { ...@@ -60,6 +60,7 @@ func init() {
commands.VersionCmd(), commands.VersionCmd(),
sendCmd, sendCmd,
closeCmd, closeCmd,
commands.AssetCmd(),
) )
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment