Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
plugin
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
link33
plugin
Commits
09d43a1a
Commit
09d43a1a
authored
Nov 20, 2018
by
harrylee2015
Committed by
vipwzw
Nov 20, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rejust code for golint,vet,ineffassign
parent
1dd4066a
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
226 additions
and
204 deletions
+226
-204
game.go
plugin/dapp/game/commands/game.go
+1
-0
doc.go
plugin/dapp/game/executor/doc.go
+6
-0
exec.go
plugin/dapp/game/executor/exec.go
+4
-0
exec_del_local.go
plugin/dapp/game/executor/exec_del_local.go
+5
-0
exec_local.go
plugin/dapp/game/executor/exec_local.go
+5
-0
game.go
plugin/dapp/game/executor/game.go
+22
-14
gamedb.go
plugin/dapp/game/executor/gamedb.go
+129
-111
query.go
plugin/dapp/game/executor/query.go
+5
-1
const.go
plugin/dapp/game/types/const.go
+10
-8
errors.go
plugin/dapp/game/types/errors.go
+10
-9
tx.go
plugin/dapp/game/types/tx.go
+7
-42
types.go
plugin/dapp/game/types/types.go
+22
-19
No files found.
plugin/dapp/game/commands/game.go
View file @
09d43a1a
...
...
@@ -6,6 +6,7 @@ package commands
import
"github.com/spf13/cobra"
// Cmd The command line is not used.
func
Cmd
()
*
cobra
.
Command
{
return
nil
}
plugin/dapp/game/executor/doc.go
View file @
09d43a1a
...
...
@@ -26,3 +26,8 @@ status: Create 1 -> Match 2 -> Cancel 3 -> Close 4
//1. 我的所有赌局,按照状态进行分类 (按照地址查询)
//2. 系统所有正在进行的赌局 (按照时间进行排序)
*/
//game 的状态变化:
// staus == 1 (创建,开始猜拳游戏)
// status == 2 (匹配,参与)
// status == 3 (取消)
// status == 4 (Close的情况)
\ No newline at end of file
plugin/dapp/game/executor/exec.go
View file @
09d43a1a
...
...
@@ -9,21 +9,25 @@ import (
gt
"github.com/33cn/plugin/plugin/dapp/game/types"
)
// Exec_Create Create game
func
(
g
*
Game
)
Exec_Create
(
payload
*
gt
.
GameCreate
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
g
,
tx
,
index
)
return
action
.
GameCreate
(
payload
)
}
// Exec_Cancel Cancel game
func
(
g
*
Game
)
Exec_Cancel
(
payload
*
gt
.
GameCancel
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
g
,
tx
,
index
)
return
action
.
GameCancel
(
payload
)
}
// Exec_Close Close game
func
(
g
*
Game
)
Exec_Close
(
payload
*
gt
.
GameClose
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
g
,
tx
,
index
)
return
action
.
GameClose
(
payload
)
}
// Exec_Match Match game
func
(
g
*
Game
)
Exec_Match
(
payload
*
gt
.
GameMatch
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
NewAction
(
g
,
tx
,
index
)
return
action
.
GameMatch
(
payload
)
...
...
plugin/dapp/game/executor/exec_del_local.go
View file @
09d43a1a
...
...
@@ -9,6 +9,7 @@ import (
gt
"github.com/33cn/plugin/plugin/dapp/game/types"
)
// roll back local db data
func
(
g
*
Game
)
execDelLocal
(
receiptData
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receiptData
.
GetTy
()
!=
types
.
ExecOk
{
...
...
@@ -28,18 +29,22 @@ func (g *Game) execDelLocal(receiptData *types.ReceiptData) (*types.LocalDBSet,
return
dbSet
,
nil
}
// ExecDelLocal_Create roll back local db data for create
func
(
g
*
Game
)
ExecDelLocal_Create
(
payload
*
gt
.
GameCreate
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execDelLocal
(
receiptData
)
}
// ExecDelLocal_Cancel roll back local db data for cancel
func
(
g
*
Game
)
ExecDelLocal_Cancel
(
payload
*
gt
.
GameCancel
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execDelLocal
(
receiptData
)
}
// ExecDelLocal_Close roll back local db data for close
func
(
g
*
Game
)
ExecDelLocal_Close
(
payload
*
gt
.
GameClose
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execDelLocal
(
receiptData
)
}
// ExecDelLocal_Match roll back local db data for match
func
(
g
*
Game
)
ExecDelLocal_Match
(
payload
*
gt
.
GameMatch
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execDelLocal
(
receiptData
)
}
plugin/dapp/game/executor/exec_local.go
View file @
09d43a1a
...
...
@@ -9,6 +9,7 @@ import (
gt
"github.com/33cn/plugin/plugin/dapp/game/types"
)
// save receiptData to local db
func
(
g
*
Game
)
execLocal
(
receiptData
*
types
.
ReceiptData
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
if
receiptData
.
GetTy
()
!=
types
.
ExecOk
{
...
...
@@ -28,18 +29,22 @@ func (g *Game) execLocal(receiptData *types.ReceiptData) (*types.LocalDBSet, err
return
dbSet
,
nil
}
// ExecLocal_Create save receiptData for create
func
(
g
*
Game
)
ExecLocal_Create
(
payload
*
gt
.
GameCreate
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
// ExecLocal_Cancel save receiptData for cancel
func
(
g
*
Game
)
ExecLocal_Cancel
(
payload
*
gt
.
GameCancel
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
// ExecLocal_Close save receiptData for close
func
(
g
*
Game
)
ExecLocal_Close
(
payload
*
gt
.
GameClose
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
// ExecLocal_Match save receiptData for Match
func
(
g
*
Game
)
ExecLocal_Match
(
payload
*
gt
.
GameMatch
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
return
g
.
execLocal
(
receiptData
)
}
plugin/dapp/game/executor/game.go
View file @
09d43a1a
...
...
@@ -22,32 +22,36 @@ func init() {
ety
.
InitFuncList
(
types
.
ListMethod
(
&
Game
{}))
}
// Init register dapp
func
Init
(
name
string
,
sub
[]
byte
)
{
drivers
.
Register
(
GetName
(),
newGame
,
types
.
GetDappFork
(
driverName
,
"Enable"
))
}
// Game the game inherits all the attributes of the driverBase.
type
Game
struct
{
drivers
.
DriverBase
}
func
newGame
()
drivers
.
Driver
{
t
:=
&
Game
{}
t
.
SetChild
(
t
)
t
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
t
g
:=
&
Game
{}
g
.
SetChild
(
g
)
g
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
g
}
// GetName get name
func
GetName
()
string
{
return
newGame
()
.
GetName
()
}
// GetDriverName get driver name
func
(
g
*
Game
)
GetDriverName
()
string
{
return
driverName
}
//
更新索引
//
update Index
func
(
g
*
Game
)
updateIndex
(
log
*
gt
.
ReceiptGame
)
(
kvs
[]
*
types
.
KeyValue
)
{
//
先保存本次Action产生的索引
//
save the index generated by this action first.
kvs
=
append
(
kvs
,
addGameAddrIndex
(
log
.
Status
,
log
.
GameId
,
log
.
Addr
,
log
.
Index
))
kvs
=
append
(
kvs
,
addGameStatusIndex
(
log
.
Status
,
log
.
GameId
,
log
.
Index
))
if
log
.
Status
==
gt
.
GameActionMatch
{
...
...
@@ -69,9 +73,9 @@ func (g *Game) updateIndex(log *gt.ReceiptGame) (kvs []*types.KeyValue) {
return
kvs
}
//
回滚索引
//
rollback Index
func
(
g
*
Game
)
rollbackIndex
(
log
*
gt
.
ReceiptGame
)
(
kvs
[]
*
types
.
KeyValue
)
{
//先删除本次Action产生的索引
kvs
=
append
(
kvs
,
delGameAddrIndex
(
log
.
Status
,
log
.
Addr
,
log
.
Index
))
kvs
=
append
(
kvs
,
delGameStatusIndex
(
log
.
Status
,
log
.
Index
))
...
...
@@ -112,21 +116,21 @@ func calcGameAddrIndexPrefix(status int32, addr string) []byte {
key
:=
fmt
.
Sprintf
(
"LODB-game-addr:%d:%s:"
,
status
,
addr
)
return
[]
byte
(
key
)
}
func
addGameStatusIndex
(
status
int32
,
gameI
d
string
,
index
int64
)
*
types
.
KeyValue
{
func
addGameStatusIndex
(
status
int32
,
gameI
D
string
,
index
int64
)
*
types
.
KeyValue
{
kv
:=
&
types
.
KeyValue
{}
kv
.
Key
=
calcGameStatusIndexKey
(
status
,
index
)
record
:=
&
gt
.
GameRecord
{
GameId
:
gameI
d
,
GameId
:
gameI
D
,
Index
:
index
,
}
kv
.
Value
=
types
.
Encode
(
record
)
return
kv
}
func
addGameAddrIndex
(
status
int32
,
gameI
d
,
addr
string
,
index
int64
)
*
types
.
KeyValue
{
func
addGameAddrIndex
(
status
int32
,
gameI
D
,
addr
string
,
index
int64
)
*
types
.
KeyValue
{
kv
:=
&
types
.
KeyValue
{}
kv
.
Key
=
calcGameAddrIndexKey
(
status
,
addr
,
index
)
record
:=
&
gt
.
GameRecord
{
GameId
:
gameI
d
,
GameId
:
gameI
D
,
Index
:
index
,
}
kv
.
Value
=
types
.
Encode
(
record
)
...
...
@@ -146,19 +150,23 @@ func delGameAddrIndex(status int32, addr string, index int64) *types.KeyValue {
return
kv
}
// ReplyGameList the data structure returned when querying the game list.
type
ReplyGameList
struct
{
Games
[]
*
Game
`json:"games"`
}
// ReplyGame the data structure returned when querying a single game.
type
ReplyGame
struct
{
Game
*
Game
`json:"game"`
}
func
(
c
*
Game
)
GetPayloadValue
()
types
.
Message
{
// GetPayloadValue get payload value
func
(
g
*
Game
)
GetPayloadValue
()
types
.
Message
{
return
&
gt
.
GameAction
{}
}
func
(
c
*
Game
)
GetTypeMap
()
map
[
string
]
int32
{
// GetTypeMap get TypeMap
func
(
g
*
Game
)
GetTypeMap
()
map
[
string
]
int32
{
return
map
[
string
]
int32
{
"Create"
:
gt
.
GameActionCreate
,
"Match"
:
gt
.
GameActionMatch
,
...
...
plugin/dapp/game/executor/gamedb.go
View file @
09d43a1a
...
...
@@ -20,64 +20,65 @@ import (
)
const
(
//剪刀
// Scissor 剪刀
Scissor
=
int32
(
1
)
//石头
// Rock 石头
Rock
=
int32
(
2
)
//布
//
Paper
布
Paper
=
int32
(
3
)
//未知结果
// Unknown 未知结果
Unknown
=
int32
(
4
)
//游戏结果
//平局
// IsDraw 平局
IsDraw
=
int32
(
1
)
// IsCreatorWin creator win
IsCreatorWin
=
int32
(
2
)
// IsMatcherWin matcher win
IsMatcherWin
=
int32
(
3
)
//开奖超时
// IsTimeOut 开奖超时
IsTimeOut
=
int32
(
4
)
// ListDESC desc query
ListDESC
=
int32
(
0
)
// ListASC asc query
ListASC
=
int32
(
1
)
GameCount
=
"GameCount"
//根据状态,地址统计整个合约目前总共成功执行了多少场游戏。
// GameCount 根据状态,地址统计整个合约目前总共成功执行了多少场游戏
GameCount
=
"GameCount"
// MaxGameAmount max game amount.单位为types.Coin 1e8
MaxGameAmount
=
int64
(
100
)
MaxGameAmount
=
int64
(
100
)
//单位为types.Coin 1e8
// MinGameAmount min game amount
MinGameAmount
=
int64
(
2
)
DefaultCount
=
int64
(
20
)
//默认一次取多少条记录
MaxCount
=
int64
(
100
)
//最多取100条
//从有matcher参与游戏开始计算本局游戏开奖的有效时间,单位为天
// DefaultCount 默认一次取多少条记录
DefaultCount
=
int64
(
20
)
// MaxCount 最多取100条
MaxCount
=
int64
(
100
)
//ActiveTime 从有matcher参与游戏开始计算本局游戏开奖的有效时间,单位为天
ActiveTime
=
int64
(
24
)
)
// name configured in manager
var
(
ConfName
_
ActiveTime
=
gt
.
GameX
+
":"
+
"activeTime"
ConfName
_
DefaultCount
=
gt
.
GameX
+
":"
+
"defaultCount"
ConfName
_
MaxCount
=
gt
.
GameX
+
":"
+
"maxCount"
ConfName
_
MaxGameAmount
=
gt
.
GameX
+
":"
+
"maxGameAmount"
ConfName
_
MinGameAmount
=
gt
.
GameX
+
":"
+
"minGameAmount"
ConfNameActiveTime
=
gt
.
GameX
+
":"
+
"activeTime"
ConfNameDefaultCount
=
gt
.
GameX
+
":"
+
"defaultCount"
ConfNameMaxCount
=
gt
.
GameX
+
":"
+
"maxCount"
ConfNameMaxGameAmount
=
gt
.
GameX
+
":"
+
"maxGameAmount"
ConfNameMinGameAmount
=
gt
.
GameX
+
":"
+
"minGameAmount"
)
//game 的状态变化:
// staus == 1 (创建,开始猜拳游戏)
// status == 2 (匹配,参与)
// status == 3 (取消)
// status == 4 (Close的情况)
/*
在石头剪刀布游戏中,一局游戏的生命周期只有四种状态,其中创建者参与了整个的生命周期,因此当一局游戏 发生状态变更时,
都需要及时建立相应的索引与之关联,同时还要删除老状态时的索引,以免形成脏数据。
分页查询接口的实现:
1.索引建立规则;
根据状态索引建立: key= status:HeightIndex
状态地址索引建立:key= status:addr:HeightIndex
value=gameId
HeightIndex=fmt.Sprintf("%018d", d.GetHeight()*types.MaxTxsPerBlock+int64(d.GetIndex()))
2.利用状态数据库中Game中存有相应的Action时的txhash,从而去查询相应action时的 height和index,
继而可以得到准确的key,从而删除localDB中的臃余索引。
*/
// GetReceiptLog get receipt log
func
(
action
*
Action
)
GetReceiptLog
(
game
*
gt
.
Game
)
*
types
.
ReceiptLog
{
log
:=
&
types
.
ReceiptLog
{}
r
:=
&
gt
.
ReceiptGame
{}
...
...
@@ -108,47 +109,53 @@ func (action *Action) GetReceiptLog(game *gt.Game) *types.ReceiptLog {
return
log
}
//
fmt.Sprintf("%018d", action.height*types.MaxTxsPerBlock+int64(action.index))
//
GetIndex get index
func
(
action
*
Action
)
GetIndex
(
game
*
gt
.
Game
)
int64
{
return
action
.
height
*
types
.
MaxTxsPerBlock
+
int64
(
action
.
index
)
}
//GetKVSet get kv set
func
(
action
*
Action
)
GetKVSet
(
game
*
gt
.
Game
)
(
kvset
[]
*
types
.
KeyValue
)
{
value
:=
types
.
Encode
(
game
)
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
Key
(
game
.
GameId
),
value
})
return
kvset
}
func
(
action
*
Action
)
updateCount
(
status
int32
,
addr
string
)
(
kvset
[]
*
types
.
KeyValue
)
{
count
,
err
:=
queryCountByStatusAndAddr
(
action
.
db
,
status
,
addr
)
if
err
!=
nil
{
glog
.
Error
(
"Query count have err:"
,
err
.
Error
())
glog
.
Error
(
"
updateCount"
,
"
Query count have err:"
,
err
.
Error
())
}
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
C
alcCountKey
(
status
,
addr
),
[]
byte
(
strconv
.
FormatInt
(
count
+
1
,
10
))})
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
c
alcCountKey
(
status
,
addr
),
[]
byte
(
strconv
.
FormatInt
(
count
+
1
,
10
))})
return
kvset
}
func
(
action
*
Action
)
updateStateDBCache
(
status
int32
,
addr
string
)
{
count
,
err
:=
queryCountByStatusAndAddr
(
action
.
db
,
status
,
addr
)
if
err
!=
nil
{
glog
.
Error
(
"Query count have err:"
,
err
.
Error
())
glog
.
Error
(
"
updateStateDBCache"
,
"
Query count have err:"
,
err
.
Error
())
}
action
.
db
.
Set
(
C
alcCountKey
(
status
,
addr
),
[]
byte
(
strconv
.
FormatInt
(
count
+
1
,
10
)))
action
.
db
.
Set
(
c
alcCountKey
(
status
,
addr
),
[]
byte
(
strconv
.
FormatInt
(
count
+
1
,
10
)))
}
func
(
action
*
Action
)
saveStateDB
(
game
*
gt
.
Game
)
{
action
.
db
.
Set
(
Key
(
game
.
GetGameId
()),
types
.
Encode
(
game
))
}
func
CalcCountKey
(
status
int32
,
addr
string
)
(
key
[]
byte
)
{
func
calcCountKey
(
status
int32
,
addr
string
)
(
key
[]
byte
)
{
key
=
append
(
key
,
[]
byte
(
"mavl-"
+
gt
.
GameX
+
"-"
)
...
)
key
=
append
(
key
,
[]
byte
(
fmt
.
Sprintf
(
"%s:%d:%s"
,
GameCount
,
status
,
addr
))
...
)
return
key
}
//gameId to save key
//
Key
gameId to save key
func
Key
(
id
string
)
(
key
[]
byte
)
{
key
=
append
(
key
,
[]
byte
(
"mavl-"
+
gt
.
GameX
+
"-"
)
...
)
key
=
append
(
key
,
[]
byte
(
id
)
...
)
return
key
}
// Action action struct
type
Action
struct
{
coinsAccount
*
account
.
DB
db
dbm
.
KV
...
...
@@ -161,35 +168,39 @@ type Action struct {
index
int
}
// NewAction new action
func
NewAction
(
g
*
Game
,
tx
*
types
.
Transaction
,
index
int
)
*
Action
{
hash
:=
tx
.
Hash
()
fromaddr
:=
tx
.
From
()
return
&
Action
{
g
.
GetCoinsAccount
(),
g
.
GetStateDB
(),
hash
,
fromaddr
,
g
.
GetBlockTime
(),
g
.
GetHeight
(),
dapp
.
ExecAddress
(
string
(
tx
.
Execer
)),
g
.
GetLocalDB
(),
index
}
}
func
(
action
*
Action
)
CheckExecAccountBalance
(
fromAddr
string
,
ToFrozen
,
ToActive
int64
)
bool
{
func
(
action
*
Action
)
checkExecAccountBalance
(
fromAddr
string
,
ToFrozen
,
ToActive
int64
)
bool
{
acc
:=
action
.
coinsAccount
.
LoadExecAccount
(
fromAddr
,
action
.
execaddr
)
if
acc
.
GetBalance
()
>=
ToFrozen
&&
acc
.
GetFrozen
()
>=
ToActive
{
return
true
}
return
false
}
// GameCreate create game
func
(
action
*
Action
)
GameCreate
(
create
*
gt
.
GameCreate
)
(
*
types
.
Receipt
,
error
)
{
gameI
d
:=
common
.
ToHex
(
action
.
txhash
)
gameI
D
:=
common
.
ToHex
(
action
.
txhash
)
var
logs
[]
*
types
.
ReceiptLog
var
kv
[]
*
types
.
KeyValue
maxGameAmount
:=
GetConfValue
(
action
.
db
,
ConfName_
MaxGameAmount
,
MaxGameAmount
)
maxGameAmount
:=
getConfValue
(
action
.
db
,
ConfName
MaxGameAmount
,
MaxGameAmount
)
if
create
.
GetValue
()
>
maxGameAmount
*
types
.
Coin
{
glog
.
Error
(
"Create the game, the deposit is too big "
,
"value"
,
create
.
GetValue
())
glog
.
Error
(
"Create the game, the deposit is too big "
,
"value"
,
create
.
GetValue
()
,
"err"
,
gt
.
ErrGameCreateAmount
.
Error
()
)
return
nil
,
gt
.
ErrGameCreateAmount
}
minGameAmount
:=
GetConfValue
(
action
.
db
,
ConfName_
MinGameAmount
,
MinGameAmount
)
minGameAmount
:=
getConfValue
(
action
.
db
,
ConfName
MinGameAmount
,
MinGameAmount
)
if
create
.
GetValue
()
<
minGameAmount
*
types
.
Coin
||
math
.
Remainder
(
float64
(
create
.
GetValue
()),
2
)
!=
0
{
return
nil
,
fmt
.
Errorf
(
"
The amount you participate in cannot be less than 2 and must be an even number.
"
)
return
nil
,
fmt
.
Errorf
(
"
%s"
,
"The amount you participate in cannot be less than 2 and must be an even number!
"
)
}
if
!
action
.
C
heckExecAccountBalance
(
action
.
fromaddr
,
create
.
GetValue
(),
0
)
{
if
!
action
.
c
heckExecAccountBalance
(
action
.
fromaddr
,
create
.
GetValue
(),
0
)
{
glog
.
Error
(
"GameCreate"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
gameI
d
,
"err"
,
types
.
ErrNoBalance
)
gameI
D
,
"err"
,
types
.
ErrNoBalance
.
Error
()
)
return
nil
,
types
.
ErrNoBalance
}
//冻结子账户资金
...
...
@@ -199,14 +210,14 @@ func (action *Action) GameCreate(create *gt.GameCreate) (*types.Receipt, error)
return
nil
,
err
}
game
:=
&
gt
.
Game
{
GameId
:
gameI
d
,
GameId
:
gameI
D
,
Value
:
create
.
GetValue
(),
HashType
:
create
.
GetHashType
(),
HashValue
:
create
.
GetHashValue
(),
CreateTime
:
action
.
blocktime
,
CreateAddress
:
action
.
fromaddr
,
Status
:
gt
.
GameActionCreate
,
CreateTxHash
:
gameI
d
,
CreateTxHash
:
gameI
D
,
}
//更新stateDB缓存,用于计数
action
.
updateStateDBCache
(
game
.
GetStatus
(),
""
)
...
...
@@ -224,27 +235,27 @@ func (action *Action) GameCreate(create *gt.GameCreate) (*types.Receipt, error)
return
receipt
,
nil
}
//match game
//
GameMatch
match game
func
(
action
*
Action
)
GameMatch
(
match
*
gt
.
GameMatch
)
(
*
types
.
Receipt
,
error
)
{
game
,
err
:=
action
.
readGame
(
match
.
GetGameId
())
if
err
!=
nil
{
glog
.
Error
(
"GameMatch"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"get game failed"
,
match
.
GetGameId
(),
"err"
,
err
)
match
.
GetGameId
(),
"err"
,
err
.
Error
()
)
return
nil
,
err
}
if
game
.
GetStatus
()
!=
gt
.
GameActionCreate
{
glog
.
Error
(
"GameMatch"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
match
.
GetGameId
(),
"err"
,
gt
.
ErrGameMatchStatus
)
match
.
GetGameId
(),
"err"
,
gt
.
ErrGameMatchStatus
.
Error
()
)
return
nil
,
gt
.
ErrGameMatchStatus
}
if
game
.
GetCreateAddress
()
==
action
.
fromaddr
{
glog
.
Error
(
"GameMatch"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
match
.
GetGameId
(),
"err"
,
gt
.
ErrGameMatch
)
match
.
GetGameId
(),
"err"
,
gt
.
ErrGameMatch
.
Error
()
)
return
nil
,
gt
.
ErrGameMatch
}
if
!
action
.
C
heckExecAccountBalance
(
action
.
fromaddr
,
game
.
GetValue
()
/
2
,
0
)
{
if
!
action
.
c
heckExecAccountBalance
(
action
.
fromaddr
,
game
.
GetValue
()
/
2
,
0
)
{
glog
.
Error
(
"GameMatch"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
match
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
)
match
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
.
Error
()
)
return
nil
,
types
.
ErrNoBalance
}
//冻结 game value 中资金的一半
...
...
@@ -278,32 +289,34 @@ func (action *Action) GameMatch(match *gt.GameMatch) (*types.Receipt, error) {
receipts
:=
&
types
.
Receipt
{
types
.
ExecOk
,
kvs
,
logs
}
return
receipts
,
nil
}
// GameCancel cancel game
func
(
action
*
Action
)
GameCancel
(
cancel
*
gt
.
GameCancel
)
(
*
types
.
Receipt
,
error
)
{
game
,
err
:=
action
.
readGame
(
cancel
.
GetGameId
())
if
err
!=
nil
{
glog
.
Error
(
"GameCancel "
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"get game failed"
,
cancel
.
GetGameId
(),
"err"
,
err
)
cancel
.
GetGameId
(),
"err"
,
err
.
Error
()
)
return
nil
,
err
}
if
game
.
GetCreateAddress
()
!=
action
.
fromaddr
{
glog
.
Error
(
"GameCancel "
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
cancel
.
GetGameId
(),
"err"
,
gt
.
ErrGameCancleAddr
)
cancel
.
GetGameId
(),
"err"
,
gt
.
ErrGameCancleAddr
.
Error
()
)
return
nil
,
gt
.
ErrGameCancleAddr
}
if
game
.
GetStatus
()
!=
gt
.
GameActionCreate
{
glog
.
Error
(
"GameCancel "
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
cancel
.
GetGameId
(),
"err"
,
gt
.
ErrGameCancleStatus
)
cancel
.
GetGameId
(),
"err"
,
gt
.
ErrGameCancleStatus
.
Error
()
)
return
nil
,
gt
.
ErrGameCancleStatus
}
if
!
action
.
C
heckExecAccountBalance
(
action
.
fromaddr
,
0
,
game
.
GetValue
())
{
if
!
action
.
c
heckExecAccountBalance
(
action
.
fromaddr
,
0
,
game
.
GetValue
())
{
glog
.
Error
(
"GameCancel"
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
)
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
.
Error
()
)
return
nil
,
types
.
ErrNoBalance
}
receipt
,
err
:=
action
.
coinsAccount
.
ExecActive
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
game
.
GetValue
())
if
err
!=
nil
{
glog
.
Error
(
"GameCancel "
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"id"
,
cancel
.
GetGameId
(),
"amount"
,
game
.
GetValue
(),
"err"
,
err
)
cancel
.
GetGameId
(),
"amount"
,
game
.
GetValue
(),
"err"
,
err
.
Error
()
)
return
nil
,
err
}
game
.
Closetime
=
action
.
blocktime
...
...
@@ -328,13 +341,14 @@ func (action *Action) GameCancel(cancel *gt.GameCancel) (*types.Receipt, error)
return
&
types
.
Receipt
{
types
.
ExecOk
,
kv
,
logs
},
nil
}
// GameClose close game
func
(
action
*
Action
)
GameClose
(
close
*
gt
.
GameClose
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
var
kv
[]
*
types
.
KeyValue
game
,
err
:=
action
.
readGame
(
close
.
GetGameId
())
if
err
!=
nil
{
glog
.
Error
(
"GameClose "
,
"addr"
,
action
.
fromaddr
,
"execaddr"
,
action
.
execaddr
,
"get game failed"
,
close
.
GetGameId
(),
"err"
,
err
)
close
.
GetGameId
(),
"err"
,
err
.
Error
()
)
return
nil
,
err
}
//开奖时间控制
...
...
@@ -348,14 +362,14 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
return
nil
,
gt
.
ErrGameCloseStatus
}
//各自冻结余额检查
if
!
action
.
C
heckExecAccountBalance
(
game
.
GetCreateAddress
(),
0
,
2
*
game
.
GetValue
()
/
3
)
{
if
!
action
.
c
heckExecAccountBalance
(
game
.
GetCreateAddress
(),
0
,
2
*
game
.
GetValue
()
/
3
)
{
glog
.
Error
(
"GameClose"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"id"
,
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
)
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
.
Error
()
)
return
nil
,
types
.
ErrNoBalance
}
if
!
action
.
C
heckExecAccountBalance
(
game
.
GetMatchAddress
(),
0
,
game
.
GetValue
()
/
3
)
{
if
!
action
.
c
heckExecAccountBalance
(
game
.
GetMatchAddress
(),
0
,
game
.
GetValue
()
/
3
)
{
glog
.
Error
(
"GameClose"
,
"addr"
,
game
.
GetMatchAddress
(),
"execaddr"
,
action
.
execaddr
,
"id"
,
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
)
game
.
GetGameId
(),
"err"
,
types
.
ErrNoBalance
.
Error
()
)
return
nil
,
types
.
ErrNoBalance
}
result
,
creatorGuess
:=
action
.
checkGameResult
(
game
,
close
)
...
...
@@ -364,7 +378,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
receipt
,
err
:=
action
.
coinsAccount
.
ExecActive
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
2
*
game
.
GetValue
()
/
3
)
if
err
!=
nil
{
glog
.
Error
(
"GameClose.execActive"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
2
*
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -373,7 +387,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
if
err
!=
nil
{
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
2
*
game
.
GetValue
()
/
3
)
// rollback
glog
.
Error
(
"GameClose.ExecTransferFrozen"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
2
*
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -383,7 +397,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
receipt
,
err
:=
action
.
coinsAccount
.
ExecActive
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
if
err
!=
nil
{
glog
.
Error
(
"GameClose.ExecActive"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -392,7 +406,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
if
err
!=
nil
{
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
// rollback
glog
.
Error
(
"GameClose.ExecActive"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -402,7 +416,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
// rollback
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetMatchAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
// rollback
glog
.
Error
(
"GameClose.ExecTransferFrozen"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -413,7 +427,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
receipt
,
err
:=
action
.
coinsAccount
.
ExecActive
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
2
*
game
.
GetValue
()
/
3
)
if
err
!=
nil
{
glog
.
Error
(
"GameClose.ExecActive"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
2
*
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -422,7 +436,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
if
err
!=
nil
{
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetCreateAddress
(),
action
.
execaddr
,
2
*
game
.
GetValue
()
/
3
)
// rollback
glog
.
Error
(
"GameClose.ExecActive"
,
"addr"
,
game
.
GetMatchAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -432,7 +446,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
receipt
,
err
:=
action
.
coinsAccount
.
ExecActive
(
game
.
GetMatchAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
if
err
!=
nil
{
glog
.
Error
(
"GameClose.ExecActive"
,
"addr"
,
game
.
GetCreateAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
2
*
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -441,7 +455,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
if
err
!=
nil
{
action
.
coinsAccount
.
ExecFrozen
(
game
.
GetMatchAddress
(),
action
.
execaddr
,
game
.
GetValue
()
/
3
)
// rollback
glog
.
Error
(
"GameClose.ExecTransferFrozen"
,
"addr"
,
game
.
GetMatchAddress
(),
"execaddr"
,
action
.
execaddr
,
"amount"
,
game
.
GetValue
()
/
3
,
"err"
,
err
)
"err"
,
err
.
Error
()
)
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
...
...
@@ -472,7 +486,7 @@ func (action *Action) GameClose(close *gt.GameClose) (*types.Receipt, error) {
// 检查开奖是否超时,若超过一天,则不让庄家开奖,但其他人可以开奖,
// 若没有一天,则其他人没有开奖权限,只有庄家有开奖权限
func
(
action
*
Action
)
checkGameIsTimeOut
(
game
*
gt
.
Game
)
bool
{
activeTime
:=
GetConfValue
(
action
.
db
,
ConfName_
ActiveTime
,
ActiveTime
)
activeTime
:=
getConfValue
(
action
.
db
,
ConfName
ActiveTime
,
ActiveTime
)
DurTime
:=
60
*
60
*
activeTime
return
action
.
blocktime
>
(
game
.
GetMatchTime
()
+
DurTime
)
}
...
...
@@ -491,10 +505,10 @@ func (action *Action) checkGameResult(game *gt.Game, close *gt.GameClose) (int32
return
IsCreatorWin
,
Rock
}
else
if
game
.
GetMatcherGuess
()
==
Paper
{
return
IsMatcherWin
,
Rock
}
else
{
}
//其他情况说明matcher 使坏,填了其他值,当做作弊处理
return
IsCreatorWin
,
Rock
}
}
else
if
bytes
.
Equal
(
common
.
Sha256
([]
byte
(
close
.
GetSecret
()
+
string
(
Scissor
))),
game
.
GetHashValue
())
{
//此刻庄家出的剪刀
if
game
.
GetMatcherGuess
()
==
Rock
{
...
...
@@ -503,9 +517,9 @@ func (action *Action) checkGameResult(game *gt.Game, close *gt.GameClose) (int32
return
IsDraw
,
Scissor
}
else
if
game
.
GetMatcherGuess
()
==
Paper
{
return
IsCreatorWin
,
Scissor
}
else
{
return
IsCreatorWin
,
Scissor
}
return
IsCreatorWin
,
Scissor
}
else
if
bytes
.
Equal
(
common
.
Sha256
([]
byte
(
close
.
GetSecret
()
+
string
(
Paper
))),
game
.
GetHashValue
())
{
//此刻庄家出的是布
if
game
.
GetMatcherGuess
()
==
Rock
{
...
...
@@ -514,9 +528,9 @@ func (action *Action) checkGameResult(game *gt.Game, close *gt.GameClose) (int32
return
IsMatcherWin
,
Paper
}
else
if
game
.
GetMatcherGuess
()
==
Paper
{
return
IsDraw
,
Paper
}
else
{
return
IsCreatorWin
,
Paper
}
return
IsCreatorWin
,
Paper
}
//其他情况默认是matcher win
return
IsMatcherWin
,
Unknown
...
...
@@ -536,17 +550,18 @@ func (action *Action) readGame(id string) (*gt.Game, error) {
return
&
game
,
nil
}
// List query game list
func
List
(
db
dbm
.
Lister
,
stateDB
dbm
.
KV
,
param
*
gt
.
QueryGameListByStatusAndAddr
)
(
types
.
Message
,
error
)
{
return
QueryGameListByPage
(
db
,
stateDB
,
param
)
}
//分页查询
//
QueryGameListByPage
分页查询
func
QueryGameListByPage
(
db
dbm
.
Lister
,
stateDB
dbm
.
KV
,
param
*
gt
.
QueryGameListByStatusAndAddr
)
(
types
.
Message
,
error
)
{
switch
param
.
GetStatus
()
{
case
gt
.
GameActionCreate
,
gt
.
GameActionMatch
,
gt
.
GameActionClose
,
gt
.
GameActionCancel
:
return
queryGameListByStatusAndAddr
(
db
,
stateDB
,
param
)
}
return
nil
,
fmt
.
Errorf
(
"the status only fill in 1,2,3,4!"
)
return
nil
,
fmt
.
Errorf
(
"
%s"
,
"
the status only fill in 1,2,3,4!"
)
}
func
queryGameListByStatusAndAddr
(
db
dbm
.
Lister
,
stateDB
dbm
.
KV
,
param
*
gt
.
QueryGameListByStatusAndAddr
)
(
types
.
Message
,
error
)
{
...
...
@@ -554,8 +569,8 @@ func queryGameListByStatusAndAddr(db dbm.Lister, stateDB dbm.KV, param *gt.Query
if
param
.
GetDirection
()
==
ListASC
{
direction
=
ListASC
}
count
:=
int32
(
GetConfValue
(
stateDB
,
ConfName_
DefaultCount
,
DefaultCount
))
maxCount
:=
int32
(
GetConfValue
(
stateDB
,
ConfName_
MaxCount
,
MaxCount
))
count
:=
int32
(
getConfValue
(
stateDB
,
ConfName
DefaultCount
,
DefaultCount
))
maxCount
:=
int32
(
getConfValue
(
stateDB
,
ConfName
MaxCount
,
MaxCount
))
if
0
<
param
.
GetCount
()
&&
param
.
GetCount
()
<=
maxCount
{
count
=
param
.
GetCount
()
}
...
...
@@ -590,13 +605,15 @@ func queryGameListByStatusAndAddr(db dbm.Lister, stateDB dbm.KV, param *gt.Query
return
&
gt
.
ReplyGameList
{
GetGameList
(
stateDB
,
gameIds
)},
nil
}
//count数查询
//
QueryGameListCount
count数查询
func
QueryGameListCount
(
stateDB
dbm
.
KV
,
param
*
gt
.
QueryGameListCount
)
(
types
.
Message
,
error
)
{
if
param
.
Status
<
1
||
param
.
Status
>
4
{
return
nil
,
fmt
.
Errorf
(
"the status only fill in 1,2,3,4!"
)
return
nil
,
fmt
.
Errorf
(
"
%s"
,
"
the status only fill in 1,2,3,4!"
)
}
return
&
gt
.
ReplyGameListCount
{
QueryCountByStatusAndAddr
(
stateDB
,
param
.
GetStatus
(),
param
.
GetAddress
())},
nil
}
// QueryCountByStatusAndAddr query game count by status and addr
func
QueryCountByStatusAndAddr
(
stateDB
dbm
.
KV
,
status
int32
,
addr
string
)
int64
{
switch
status
{
case
gt
.
GameActionCreate
,
gt
.
GameActionMatch
,
gt
.
GameActionCancel
,
gt
.
GameActionClose
:
...
...
@@ -607,14 +624,14 @@ func QueryCountByStatusAndAddr(stateDB dbm.KV, status int32, addr string) int64
return
0
}
func
queryCountByStatusAndAddr
(
stateDB
dbm
.
KV
,
status
int32
,
addr
string
)
(
int64
,
error
)
{
data
,
err
:=
stateDB
.
Get
(
C
alcCountKey
(
status
,
addr
))
data
,
err
:=
stateDB
.
Get
(
c
alcCountKey
(
status
,
addr
))
if
err
!=
nil
{
glog
.
Error
(
"query count have err:"
,
err
.
Error
())
glog
.
Error
(
"query
CountByStatusAndAddr"
,
"query
count have err:"
,
err
.
Error
())
return
0
,
err
}
count
,
err
:=
strconv
.
ParseInt
(
string
(
data
),
10
,
64
)
if
err
!=
nil
{
glog
.
Error
(
"Type conversion error:"
,
err
.
Error
())
glog
.
Error
(
"
queryCountByStatusAndAddr"
,
"
Type conversion error:"
,
err
.
Error
())
return
0
,
err
}
return
count
,
nil
...
...
@@ -623,20 +640,21 @@ func queryCountByStatusAndAddr(stateDB dbm.KV, status int32, addr string) (int64
func
readGame
(
db
dbm
.
KV
,
id
string
)
(
*
gt
.
Game
,
error
)
{
data
,
err
:=
db
.
Get
(
Key
(
id
))
if
err
!=
nil
{
glog
.
Error
(
"query data have err:"
,
err
.
Error
())
glog
.
Error
(
"
readGame"
,
"
query data have err:"
,
err
.
Error
())
return
nil
,
err
}
var
game
gt
.
Game
//decode
err
=
types
.
Decode
(
data
,
&
game
)
if
err
!=
nil
{
glog
.
Error
(
"decode game have err:"
,
err
.
Error
())
glog
.
Error
(
"
readGame"
,
"
decode game have err:"
,
err
.
Error
())
return
nil
,
err
}
return
&
game
,
nil
}
func
Infos
(
db
dbm
.
KV
,
infos
*
gt
.
QueryGameInfos
)
(
types
.
Message
,
error
)
{
// QueryGameListByIds query game list by gameIds
func
QueryGameListByIds
(
db
dbm
.
KV
,
infos
*
gt
.
QueryGameInfos
)
(
types
.
Message
,
error
)
{
var
games
[]
*
gt
.
Game
for
i
:=
0
;
i
<
len
(
infos
.
GameIds
);
i
++
{
id
:=
infos
.
GameIds
[
i
]
...
...
@@ -649,7 +667,7 @@ func Infos(db dbm.KV, infos *gt.QueryGameInfos) (types.Message, error) {
return
&
gt
.
ReplyGameList
{
Games
:
games
},
nil
}
//安全批量查询方式,防止因为脏数据导致查询接口奔溃
//
GetGameList
安全批量查询方式,防止因为脏数据导致查询接口奔溃
func
GetGameList
(
db
dbm
.
KV
,
values
[]
string
)
[]
*
gt
.
Game
{
var
games
[]
*
gt
.
Game
for
_
,
value
:=
range
values
{
...
...
@@ -661,29 +679,29 @@ func GetGameList(db dbm.KV, values []string) []*gt.Game {
}
return
games
}
func
GetConfValue
(
db
dbm
.
KV
,
key
string
,
default_v
alue
int64
)
int64
{
func
getConfValue
(
db
dbm
.
KV
,
key
string
,
defaultV
alue
int64
)
int64
{
var
item
types
.
ConfigItem
value
,
err
:=
getManageKey
(
key
,
db
)
if
err
!=
nil
{
return
default
_v
alue
return
default
V
alue
}
if
value
!=
nil
{
err
=
types
.
Decode
(
value
,
&
item
)
if
err
!=
nil
{
glog
.
Error
(
"gamedb
GetConfValue"
,
"decode db key:"
,
key
,
err
.
Error
())
return
default
_v
alue
glog
.
Error
(
"gamedb
getConfValue"
,
"decode db key:"
,
key
,
"err"
,
err
.
Error
())
return
default
V
alue
}
}
values
:=
item
.
GetArr
()
.
GetValue
()
if
len
(
values
)
==
0
{
glog
.
Error
(
"gamedb
G
etConfValue"
,
"can't get value from values arr. key:"
,
key
)
return
default
_v
alue
glog
.
Error
(
"gamedb
g
etConfValue"
,
"can't get value from values arr. key:"
,
key
)
return
default
V
alue
}
//取数组最后一位,作为最新配置项的值
v
,
err
:=
strconv
.
ParseInt
(
values
[
len
(
values
)
-
1
],
10
,
64
)
if
err
!=
nil
{
glog
.
Error
(
"gamedb
G
etConfValue"
,
"Type conversion error:"
,
err
.
Error
())
return
default
_v
alue
glog
.
Error
(
"gamedb
g
etConfValue"
,
"Type conversion error:"
,
err
.
Error
())
return
default
V
alue
}
return
v
}
...
...
@@ -692,10 +710,10 @@ func getManageKey(key string, db dbm.KV) ([]byte, error) {
value
,
err
:=
db
.
Get
([]
byte
(
manageKey
))
if
err
!=
nil
{
if
types
.
IsPara
()
{
//平行链只有一种存储方式
glog
.
Error
(
"gamedb getManage"
,
"can't get value from db,key:"
,
key
,
err
.
Error
())
glog
.
Error
(
"gamedb getManage"
,
"can't get value from db,key:"
,
key
,
"err"
,
err
.
Error
())
return
nil
,
err
}
glog
.
Debug
(
"gamedb"
,
"get db key"
,
"not found"
)
glog
.
Debug
(
"gamedb
getManageKey
"
,
"get db key"
,
"not found"
)
return
getConfigKey
(
key
,
db
)
}
return
value
,
nil
...
...
@@ -705,7 +723,7 @@ func getConfigKey(key string, db dbm.KV) ([]byte, error) {
configKey
:=
types
.
ConfigKey
(
key
)
value
,
err
:=
db
.
Get
([]
byte
(
configKey
))
if
err
!=
nil
{
glog
.
Error
(
"gamedb getConfigKey"
,
"can't get value from db,key:"
,
key
,
err
.
Error
())
glog
.
Error
(
"gamedb getConfigKey"
,
"can't get value from db,key:"
,
key
,
"err"
,
err
.
Error
())
return
nil
,
err
}
return
value
,
nil
...
...
plugin/dapp/game/executor/query.go
View file @
09d43a1a
...
...
@@ -9,18 +9,22 @@ import (
gt
"github.com/33cn/plugin/plugin/dapp/game/types"
)
// Query_QueryGameListByIds query game list by gameIDs
func
(
g
*
Game
)
Query_QueryGameListByIds
(
in
*
gt
.
QueryGameInfos
)
(
types
.
Message
,
error
)
{
return
Info
s
(
g
.
GetStateDB
(),
in
)
return
QueryGameListById
s
(
g
.
GetStateDB
(),
in
)
}
// Query_QueryGameListCount query game count by status and addr
func
(
g
*
Game
)
Query_QueryGameListCount
(
in
*
gt
.
QueryGameListCount
)
(
types
.
Message
,
error
)
{
return
QueryGameListCount
(
g
.
GetStateDB
(),
in
)
}
// Query_QueryGameListByStatusAndAddr query game list by status and addr
func
(
g
*
Game
)
Query_QueryGameListByStatusAndAddr
(
in
*
gt
.
QueryGameListByStatusAndAddr
)
(
types
.
Message
,
error
)
{
return
List
(
g
.
GetLocalDB
(),
g
.
GetStateDB
(),
in
)
}
// Query_QueryGameById query game by gameID
func
(
g
*
Game
)
Query_QueryGameById
(
in
*
gt
.
QueryGameInfo
)
(
types
.
Message
,
error
)
{
game
,
err
:=
readGame
(
g
.
GetStateDB
(),
in
.
GetGameId
())
if
err
!=
nil
{
...
...
plugin/dapp/game/types/const.go
View file @
09d43a1a
...
...
@@ -26,16 +26,18 @@ var (
ExecerGame
=
[]
byte
(
GameX
)
)
// action name
const
(
Action
_
CreateGame
=
"createGame"
Action
_
MatchGame
=
"matchGame"
Action
_
CancelGame
=
"cancelGame"
Action
_
CloseGame
=
"closeGame"
ActionCreateGame
=
"createGame"
ActionMatchGame
=
"matchGame"
ActionCancelGame
=
"cancelGame"
ActionCloseGame
=
"closeGame"
)
// query func name
const
(
FuncName
_
QueryGameListByIds
=
"QueryGameListByIds"
FuncName
_
QueryGameListCount
=
"QueryGameListCount"
FuncName
_
QueryGameListByStatusAndAddr
=
"QueryGameListByStatusAndAddr"
FuncName
_QueryGameById
=
"QueryGameById"
FuncNameQueryGameListByIds
=
"QueryGameListByIds"
FuncNameQueryGameListCount
=
"QueryGameListCount"
FuncNameQueryGameListByStatusAndAddr
=
"QueryGameListByStatusAndAddr"
FuncName
QueryGameByID
=
"QueryGameById"
)
plugin/dapp/game/types/errors.go
View file @
09d43a1a
...
...
@@ -4,15 +4,16 @@
package
types
import
"
errors
"
import
"
fmt
"
// some errors definition
var
(
ErrGameCreateAmount
=
errors
.
New
(
"You fill in more than the maximum number of games."
)
ErrGameCancleAddr
=
errors
.
New
(
"You don't have permission to cancel someone else's game."
)
ErrGameCloseAddr
=
errors
.
New
(
"The game time has not yet expired,You don't have permission to call yet."
)
ErrGameTimeOut
=
errors
.
New
(
"The game has expired.,You don't have permission to call."
)
ErrGameMatchStatus
=
errors
.
New
(
"can't join the game, the game has matched or finished!"
)
ErrGameMatch
=
errors
.
New
(
"can't join the game, You can't match the game you created!"
)
ErrGameCancleStatus
=
errors
.
New
(
"can't cancle the game, the game has matched!"
)
ErrGameCloseStatus
=
errors
.
New
(
"can't close the game again, the game has finished!"
)
ErrGameCreateAmount
=
fmt
.
Errorf
(
"%s"
,
"You fill in more than the maximum number of games."
)
ErrGameCancleAddr
=
fmt
.
Errorf
(
"%s"
,
"You don't have permission to cancel someone else's game."
)
ErrGameCloseAddr
=
fmt
.
Errorf
(
"%s"
,
"The game time has not yet expired,You don't have permission to call yet."
)
ErrGameTimeOut
=
fmt
.
Errorf
(
"%s"
,
"The game has expired.,You don't have permission to call."
)
ErrGameMatchStatus
=
fmt
.
Errorf
(
"%s"
,
"can't join the game, the game has matched or finished!"
)
ErrGameMatch
=
fmt
.
Errorf
(
"%s"
,
"can't join the game, You can't match the game you created!"
)
ErrGameCancleStatus
=
fmt
.
Errorf
(
"%s"
,
"can't cancle the game, the game has matched!"
)
ErrGameCloseStatus
=
fmt
.
Errorf
(
"%s"
,
"can't close the game again, the game has finished!"
)
)
plugin/dapp/game/types/tx.go
View file @
09d43a1a
...
...
@@ -4,6 +4,7 @@
package
types
// GamePreCreateTx pre create game,unused
type
GamePreCreateTx
struct
{
//Secret string `json:"secret"`
//下注必须时偶数,不能时级数
...
...
@@ -14,59 +15,23 @@ type GamePreCreateTx struct {
Fee
int64
`json:"fee"`
}
// GamePreMatchTx pre match game,unused
type
GamePreMatchTx
struct
{
GameI
d
string
`json:"gameI
d"`
GameI
D
string
`json:"game_i_
d"`
Guess
int32
`json:"guess"`
Fee
int64
`json:"fee"`
}
// GamePreCancelTx pre cancel tx,unused
type
GamePreCancelTx
struct
{
GameI
d
string
`json:"gameI
d"`
GameI
D
string
`json:"game_i_
d"`
Fee
int64
`json:"fee"`
}
// GamePreCloseTx pre close game, unused
type
GamePreCloseTx
struct
{
GameI
d
string
`json:"gameI
d"`
GameI
D
string
`json:"game_i_
d"`
Secret
string
`json:"secret"`
Result
int32
`json:"result"`
Fee
int64
`json:"fee"`
}
type
GameData
struct
{
// 默认是由创建这局游戏的txHash作为gameId
GameId
string
`json:"gameId"`
// create 1 -> Match 2 -> Cancel 3 -> Close 4 Pending 5 //表示有人参与游戏,但还未打包
Status
int32
`json:"status"`
// 创建时间
CreateTime
int64
`json:"createTime"`
// 匹配时间(何时参与对赌)
MatchTime
int64
`json:"matchTime"`
// 状态close的时间(包括cancel)
Closetime
int64
`json:"closetime"`
// 赌注
Value
int64
`json:"value"`
// 发起者账号地址
CreateAddress
string
`json:"createAddress"`
// 对赌者账号地址
MatchAddress
string
`json:"matchAddress"`
// hash 类型,预留字段
HashType
string
`json:"hashType"`
// 庄家创建游戏时,庄家自己出拳结果加密后的hash值
HashValue
[]
byte
`json:"hashValue"`
// 用来公布庄家出拳结果的私钥
Secret
string
`json:"secret"`
// 1平局,2 庄家获胜,3 matcher获胜,4 庄家开奖超时,matcher获胜,并获得本局所有赌资
Result
int32
`json:"result"`
// matcher 出拳结果
MatcherGuess
int32
`json:"matcherGuess"`
// create txHash
CreateTxHash
string
`json:"createTxHash"`
// matche交易hash
MatchTxHash
string
`json:"matchTxHash"`
// close txhash
CloseTxHash
string
`json:"closeTxHash"`
// cancel txhash
CancelTxHash
string
`json:"cancelTxHash"`
CreatorGuess
int32
`json:"creatorGuess"`
Index
int64
`json:"index"`
}
plugin/dapp/game/types/types.go
View file @
09d43a1a
...
...
@@ -30,18 +30,20 @@ func getRealExecName(paraName string) string {
return
types
.
ExecName
(
paraName
+
GameX
)
}
// NewType new type
func
NewType
()
*
GameType
{
c
:=
&
GameType
{}
c
.
SetChild
(
c
)
return
c
}
//
exec
//
GameType execType
type
GameType
struct
{
types
.
ExecTypeBase
}
func
(
at
*
GameType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
// GetLogMap get log
func
(
gt
*
GameType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
return
map
[
int64
]
*
types
.
LogInfo
{
TyLogCreateGame
:
{
reflect
.
TypeOf
(
ReceiptGame
{}),
"LogLotteryCreate"
},
TyLogCancleGame
:
{
reflect
.
TypeOf
(
ReceiptGame
{}),
"LogCancleGame"
},
...
...
@@ -50,11 +52,13 @@ func (at *GameType) GetLogMap() map[int64]*types.LogInfo {
}
}
func
(
g
*
GameType
)
GetPayload
()
types
.
Message
{
// GetPayload get payload
func
(
gt
*
GameType
)
GetPayload
()
types
.
Message
{
return
&
GameAction
{}
}
func
(
g
*
GameType
)
GetTypeMap
()
map
[
string
]
int32
{
// GetTypeMap get typeMap
func
(
gt
*
GameType
)
GetTypeMap
()
map
[
string
]
int32
{
return
map
[
string
]
int32
{
"Create"
:
GameActionCreate
,
"Cancel"
:
GameActionCancel
,
...
...
@@ -63,11 +67,10 @@ func (g *GameType) GetTypeMap() map[string]int32 {
}
}
//
TODO createTx接口暂时没法用,作为一个预留接口
func
(
g
ame
GameType
)
CreateTx
(
action
string
,
message
json
.
RawMessage
)
(
*
types
.
Transaction
,
error
)
{
//
CreateTx unused,just empty implementation
func
(
g
t
GameType
)
CreateTx
(
action
string
,
message
json
.
RawMessage
)
(
*
types
.
Transaction
,
error
)
{
tlog
.
Debug
(
"Game.CreateTx"
,
"action"
,
action
)
var
tx
*
types
.
Transaction
if
action
==
Action_CreateGame
{
if
action
==
ActionCreateGame
{
var
param
GamePreCreateTx
err
:=
json
.
Unmarshal
(
message
,
&
param
)
if
err
!=
nil
{
...
...
@@ -76,7 +79,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return
CreateRawGamePreCreateTx
(
&
param
)
}
else
if
action
==
Action
_
MatchGame
{
}
else
if
action
==
ActionMatchGame
{
var
param
GamePreMatchTx
err
:=
json
.
Unmarshal
(
message
,
&
param
)
if
err
!=
nil
{
...
...
@@ -85,7 +88,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return
CreateRawGamePreMatchTx
(
&
param
)
}
else
if
action
==
Action
_
CancelGame
{
}
else
if
action
==
ActionCancelGame
{
var
param
GamePreCancelTx
err
:=
json
.
Unmarshal
(
message
,
&
param
)
if
err
!=
nil
{
...
...
@@ -94,7 +97,7 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return
CreateRawGamePreCancelTx
(
&
param
)
}
else
if
action
==
Action
_
CloseGame
{
}
else
if
action
==
ActionCloseGame
{
var
param
GamePreCloseTx
err
:=
json
.
Unmarshal
(
message
,
&
param
)
if
err
!=
nil
{
...
...
@@ -103,13 +106,11 @@ func (game GameType) CreateTx(action string, message json.RawMessage) (*types.Tr
}
return
CreateRawGamePreCloseTx
(
&
param
)
}
else
{
return
nil
,
types
.
ErrNotSupport
}
return
tx
,
nil
return
nil
,
types
.
ErrNotSupport
}
// CreateRawGamePreCreateTx unused,just empty implementation
func
CreateRawGamePreCreateTx
(
parm
*
GamePreCreateTx
)
(
*
types
.
Transaction
,
error
)
{
if
parm
==
nil
{
tlog
.
Error
(
"CreateRawGamePreCreateTx"
,
"parm"
,
parm
)
...
...
@@ -139,13 +140,14 @@ func CreateRawGamePreCreateTx(parm *GamePreCreateTx) (*types.Transaction, error)
return
tx
,
nil
}
// CreateRawGamePreMatchTx unused,just empty implementation
func
CreateRawGamePreMatchTx
(
parm
*
GamePreMatchTx
)
(
*
types
.
Transaction
,
error
)
{
if
parm
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
v
:=
&
GameMatch
{
GameId
:
parm
.
GameI
d
,
GameId
:
parm
.
GameI
D
,
Guess
:
parm
.
Guess
,
}
game
:=
&
GameAction
{
...
...
@@ -166,12 +168,13 @@ func CreateRawGamePreMatchTx(parm *GamePreMatchTx) (*types.Transaction, error) {
return
tx
,
nil
}
// CreateRawGamePreCancelTx unused,just empty implementation
func
CreateRawGamePreCancelTx
(
parm
*
GamePreCancelTx
)
(
*
types
.
Transaction
,
error
)
{
if
parm
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
v
:=
&
GameCancel
{
GameId
:
parm
.
GameI
d
,
GameId
:
parm
.
GameI
D
,
}
cancel
:=
&
GameAction
{
Ty
:
GameActionCancel
,
...
...
@@ -191,13 +194,13 @@ func CreateRawGamePreCancelTx(parm *GamePreCancelTx) (*types.Transaction, error)
return
tx
,
nil
}
//
CreateRawGamePreCloseTx
//
CreateRawGamePreCloseTx unused,just empty implementation
func
CreateRawGamePreCloseTx
(
parm
*
GamePreCloseTx
)
(
*
types
.
Transaction
,
error
)
{
if
parm
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
v
:=
&
GameClose
{
GameId
:
parm
.
GameI
d
,
GameId
:
parm
.
GameI
D
,
Secret
:
parm
.
Secret
,
}
close
:=
&
GameAction
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment