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
47bbff03
Commit
47bbff03
authored
Dec 12, 2018
by
陈德海
Browse files
Options
Browse Files
Download
Plain Diff
merge mempool trade
parents
053827a8
5e735848
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
52 changed files
with
478 additions
and
149 deletions
+478
-149
chain33.toml
chain33.toml
+3
-3
paracommitmsg_test.go
plugin/consensus/para/paracommitmsg_test.go
+3
-5
chain33.test.toml
plugin/consensus/pbft/chain33.test.toml
+1
-0
pbft_test.go
plugin/consensus/pbft/pbft_test.go
+2
-2
chain33.test.toml
plugin/consensus/raft/chain33.test.toml
+1
-0
raft_test.go
plugin/consensus/raft/raft_test.go
+2
-2
chain33.test.toml
plugin/consensus/tendermint/chain33.test.toml
+1
-0
tendermint_test.go
plugin/consensus/tendermint/tendermint_test.go
+2
-2
chain33.cfg.toml
plugin/consensus/ticket/testdata/chain33.cfg.toml
+1
-0
ticket.go
plugin/consensus/ticket/ticket.go
+5
-0
ticket_test.go
plugin/consensus/ticket/ticket_test.go
+19
-1
chain33.para.test.toml
plugin/dapp/paracross/cmd/build/chain33.para.test.toml
+1
-0
chain33.para.toml
plugin/dapp/paracross/cmd/build/chain33.para.toml
+1
-0
privacybizpolicy_test.go
plugin/dapp/privacy/wallet/privacybizpolicy_test.go
+1
-2
tradedb.go
plugin/dapp/trade/executor/tradedb.go
+26
-0
const.go
plugin/mempool/trade/const.go
+0
-3
blockstore.go
vendor/github.com/33cn/chain33/blockchain/blockstore.go
+2
-2
chain_test.go
vendor/github.com/33cn/chain33/blockchain/chain_test.go
+3
-2
proc.go
vendor/github.com/33cn/chain33/blockchain/proc.go
+6
-4
reindex_test.go
vendor/github.com/33cn/chain33/blockchain/reindex_test.go
+1
-1
copy-autotest.sh
...r/github.com/33cn/chain33/build/autotest/copy-autotest.sh
+1
-1
mock_blockchain_test.go
...or/github.com/33cn/chain33/client/mock_blockchain_test.go
+3
-0
api.go
vendor/github.com/33cn/chain33/client/mocks/api.go
+23
-0
queueprotocol.go
vendor/github.com/33cn/chain33/client/queueprotocol.go
+19
-0
queueprotocol_test.go
vendor/github.com/33cn/chain33/client/queueprotocol_test.go
+9
-0
queueprotocolapi.go
vendor/github.com/33cn/chain33/client/queueprotocolapi.go
+2
-0
rpc_ctx_test.go
vendor/github.com/33cn/chain33/client/rpc_ctx_test.go
+6
-0
address.go
vendor/github.com/33cn/chain33/common/address/address.go
+59
-17
address_test.go
...or/github.com/33cn/chain33/common/address/address_test.go
+28
-5
client.go
vendor/github.com/33cn/chain33/rpc/client.go
+3
-0
client_test.go
vendor/github.com/33cn/chain33/rpc/client_test.go
+0
-17
grpchandler.go
vendor/github.com/33cn/chain33/rpc/grpchandler.go
+8
-2
jrpchandler.go
vendor/github.com/33cn/chain33/rpc/jrpchandler.go
+18
-48
jrpchandler_test.go
vendor/github.com/33cn/chain33/rpc/jrpchandler_test.go
+3
-3
rpc_real_test.go
vendor/github.com/33cn/chain33/rpc/rpc_real_test.go
+48
-6
server_test.go
vendor/github.com/33cn/chain33/rpc/server_test.go
+25
-1
types.go
vendor/github.com/33cn/chain33/rpc/types/types.go
+13
-0
base.go
vendor/github.com/33cn/chain33/system/consensus/base.go
+5
-1
cfg.go
vendor/github.com/33cn/chain33/types/cfg.go
+13
-12
config.go
vendor/github.com/33cn/chain33/types/config.go
+7
-1
const.go
vendor/github.com/33cn/chain33/types/const.go
+1
-0
executor.go
vendor/github.com/33cn/chain33/types/executor.go
+8
-4
executor_test.go
vendor/github.com/33cn/chain33/types/executor_test.go
+0
-1
chain33client.go
vendor/github.com/33cn/chain33/types/mocks/chain33client.go
+30
-0
rpc.proto
vendor/github.com/33cn/chain33/types/proto/rpc.proto
+3
-0
transaction.proto
vendor/github.com/33cn/chain33/types/proto/transaction.proto
+1
-0
rpc.pb.go
vendor/github.com/33cn/chain33/types/rpc.pb.go
+0
-0
transaction.pb.go
vendor/github.com/33cn/chain33/types/transaction.pb.go
+0
-0
types.go
vendor/github.com/33cn/chain33/types/types.go
+4
-1
types_real_test.go
vendor/github.com/33cn/chain33/types/types_real_test.go
+43
-0
types_test.go
vendor/github.com/33cn/chain33/types/types_test.go
+6
-0
testnode.go
vendor/github.com/33cn/chain33/util/testnode/testnode.go
+8
-0
No files found.
chain33.toml
View file @
47bbff03
...
@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"]
...
@@ -62,7 +62,7 @@ grpcFuncWhitelist=["*"]
[mempool]
[mempool]
name
=
"t
rad
e"
name
=
"t
imelin
e"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
maxTxNumPerAccount
=
10000
maxTxNumPerAccount
=
10000
...
@@ -77,8 +77,8 @@ poolCacheSize=10240
...
@@ -77,8 +77,8 @@ poolCacheSize=10240
minTxFee
=
100000
minTxFee
=
100000
maxTxNumPerAccount
=
10000
maxTxNumPerAccount
=
10000
timeParam
=
1
#时间占价格比例
timeParam
=
1
#时间占价格比例
priceConstant
=
1
#一个合适的常量
priceConstant
=
1
544
#手续费相对于时间的一个合适的常量,取当前unxi时间戳前四位数,排序时手续费高1e-5~=快1s
pricePower
=
0
#手续费占
常量比例
pricePower
=
1
#
常量比例
[consensus]
[consensus]
name
=
"ticket"
name
=
"ticket"
...
...
plugin/consensus/para/paracommitmsg_test.go
View file @
47bbff03
...
@@ -48,7 +48,7 @@ type suiteParaCommitMsg struct {
...
@@ -48,7 +48,7 @@ type suiteParaCommitMsg struct {
block
*
blockchain
.
BlockChain
block
*
blockchain
.
BlockChain
exec
*
executor
.
Executor
exec
*
executor
.
Executor
store
queue
.
Module
store
queue
.
Module
mem
*
mempool
.
Mempool
mem
queue
.
Module
network
*
p2p
.
P2p
network
*
p2p
.
P2p
}
}
...
@@ -84,17 +84,15 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
...
@@ -84,17 +84,15 @@ func (s *suiteParaCommitMsg) initEnv(cfg *types.Config, sub *types.ConfigSubModu
s
.
para
.
grpcClient
=
s
.
grpcCli
s
.
para
.
grpcClient
=
s
.
grpcCli
s
.
para
.
SetQueueClient
(
q
.
Client
())
s
.
para
.
SetQueueClient
(
q
.
Client
())
s
.
mem
=
mempool
.
New
(
cfg
.
Mem
Poo
l
)
s
.
mem
=
mempool
.
New
(
cfg
.
Mem
pool
,
ni
l
)
s
.
mem
.
SetQueueClient
(
q
.
Client
())
s
.
mem
.
SetQueueClient
(
q
.
Client
())
s
.
mem
.
SetSync
(
true
)
s
.
mem
.
Wait
()
s
.
mem
.
WaitPollLastHeader
()
s
.
network
=
p2p
.
New
(
cfg
.
P2P
)
s
.
network
=
p2p
.
New
(
cfg
.
P2P
)
s
.
network
.
SetQueueClient
(
q
.
Client
())
s
.
network
.
SetQueueClient
(
q
.
Client
())
s
.
para
.
wg
.
Add
(
1
)
s
.
para
.
wg
.
Add
(
1
)
go
walletProcess
(
q
,
s
.
para
)
go
walletProcess
(
q
,
s
.
para
)
}
}
func
walletProcess
(
q
queue
.
Queue
,
para
*
client
)
{
func
walletProcess
(
q
queue
.
Queue
,
para
*
client
)
{
...
...
plugin/consensus/pbft/chain33.test.toml
View file @
47bbff03
...
@@ -51,6 +51,7 @@ verMix=118
...
@@ -51,6 +51,7 @@ verMix=118
verMax
=
119
verMax
=
119
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
...
...
plugin/consensus/pbft/pbft_test.go
View file @
47bbff03
...
@@ -62,14 +62,14 @@ func TestPbft(t *testing.T) {
...
@@ -62,14 +62,14 @@ func TestPbft(t *testing.T) {
clearTestData
()
clearTestData
()
}
}
func
initEnvPbft
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
*
p2p
.
P2p
,
queue
.
Module
,
*
mempool
.
Mempool
,
queue
.
Module
,
queue
.
Module
,
queue
.
Module
)
{
func
initEnvPbft
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
*
p2p
.
P2p
,
queue
.
Module
,
queue
.
Module
,
*
executor
.
Executor
,
queue
.
Module
,
queue
.
Module
)
{
var
q
=
queue
.
New
(
"channel"
)
var
q
=
queue
.
New
(
"channel"
)
flag
.
Parse
()
flag
.
Parse
()
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
types
.
Init
(
cfg
.
Title
,
cfg
)
types
.
Init
(
cfg
.
Title
,
cfg
)
chain
:=
blockchain
.
New
(
cfg
.
BlockChain
)
chain
:=
blockchain
.
New
(
cfg
.
BlockChain
)
chain
.
SetQueueClient
(
q
.
Client
())
chain
.
SetQueueClient
(
q
.
Client
())
mem
:=
mempool
.
New
(
cfg
.
Mem
Poo
l
)
mem
:=
mempool
.
New
(
cfg
.
Mem
pool
,
ni
l
)
mem
.
SetQueueClient
(
q
.
Client
())
mem
.
SetQueueClient
(
q
.
Client
())
exec
:=
executor
.
New
(
cfg
.
Exec
,
sub
.
Exec
)
exec
:=
executor
.
New
(
cfg
.
Exec
,
sub
.
Exec
)
exec
.
SetQueueClient
(
q
.
Client
())
exec
.
SetQueueClient
(
q
.
Client
())
...
...
plugin/consensus/raft/chain33.test.toml
View file @
47bbff03
...
@@ -59,6 +59,7 @@ jrpcFuncWhitelist=["*"]
...
@@ -59,6 +59,7 @@ jrpcFuncWhitelist=["*"]
grpcFuncWhitelist
=
["*"]
grpcFuncWhitelist
=
["*"]
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
...
...
plugin/consensus/raft/raft_test.go
View file @
47bbff03
...
@@ -63,7 +63,7 @@ func RaftPerf() {
...
@@ -63,7 +63,7 @@ func RaftPerf() {
sendReplyList
(
q
)
sendReplyList
(
q
)
}
}
func
initEnvRaft
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
queue
.
Module
,
*
mempool
.
Mempool
,
queue
.
Module
,
queue
.
Module
,
queue
.
Module
)
{
func
initEnvRaft
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
queue
.
Module
,
queue
.
Module
,
*
executor
.
Executor
,
queue
.
Module
,
queue
.
Module
)
{
var
q
=
queue
.
New
(
"channel"
)
var
q
=
queue
.
New
(
"channel"
)
flag
.
Parse
()
flag
.
Parse
()
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
...
@@ -80,7 +80,7 @@ func initEnvRaft() (queue.Queue, *blockchain.BlockChain, queue.Module, *mempool.
...
@@ -80,7 +80,7 @@ func initEnvRaft() (queue.Queue, *blockchain.BlockChain, queue.Module, *mempool.
cs
:=
NewRaftCluster
(
cfg
.
Consensus
,
sub
.
Consensus
[
"raft"
])
cs
:=
NewRaftCluster
(
cfg
.
Consensus
,
sub
.
Consensus
[
"raft"
])
cs
.
SetQueueClient
(
q
.
Client
())
cs
.
SetQueueClient
(
q
.
Client
())
mem
:=
mempool
.
New
(
cfg
.
Mem
Poo
l
)
mem
:=
mempool
.
New
(
cfg
.
Mem
pool
,
ni
l
)
mem
.
SetQueueClient
(
q
.
Client
())
mem
.
SetQueueClient
(
q
.
Client
())
network
:=
p2p
.
New
(
cfg
.
P2P
)
network
:=
p2p
.
New
(
cfg
.
P2P
)
...
...
plugin/consensus/tendermint/chain33.test.toml
View file @
47bbff03
...
@@ -60,6 +60,7 @@ jrpcFuncWhitelist=["*"]
...
@@ -60,6 +60,7 @@ jrpcFuncWhitelist=["*"]
grpcFuncWhitelist
=
["*"]
grpcFuncWhitelist
=
["*"]
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
...
...
plugin/consensus/tendermint/tendermint_test.go
View file @
47bbff03
...
@@ -76,7 +76,7 @@ func RaftPerf() {
...
@@ -76,7 +76,7 @@ func RaftPerf() {
time
.
Sleep
(
10
*
time
.
Second
)
time
.
Sleep
(
10
*
time
.
Second
)
}
}
func
initEnvTendermint
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
queue
.
Module
,
*
mempool
.
Mempool
,
queue
.
Module
,
queue
.
Module
,
queue
.
Module
)
{
func
initEnvTendermint
()
(
queue
.
Queue
,
*
blockchain
.
BlockChain
,
queue
.
Module
,
queue
.
Module
,
*
executor
.
Executor
,
queue
.
Module
,
queue
.
Module
)
{
var
q
=
queue
.
New
(
"channel"
)
var
q
=
queue
.
New
(
"channel"
)
flag
.
Parse
()
flag
.
Parse
()
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
cfg
,
sub
:=
types
.
InitCfg
(
"chain33.test.toml"
)
...
@@ -93,7 +93,7 @@ func initEnvTendermint() (queue.Queue, *blockchain.BlockChain, queue.Module, *me
...
@@ -93,7 +93,7 @@ func initEnvTendermint() (queue.Queue, *blockchain.BlockChain, queue.Module, *me
cs
:=
New
(
cfg
.
Consensus
,
sub
.
Consensus
[
"tendermint"
])
cs
:=
New
(
cfg
.
Consensus
,
sub
.
Consensus
[
"tendermint"
])
cs
.
SetQueueClient
(
q
.
Client
())
cs
.
SetQueueClient
(
q
.
Client
())
mem
:=
mempool
.
New
(
cfg
.
Mem
Poo
l
)
mem
:=
mempool
.
New
(
cfg
.
Mem
pool
,
ni
l
)
mem
.
SetQueueClient
(
q
.
Client
())
mem
.
SetQueueClient
(
q
.
Client
())
network
:=
p2p
.
New
(
cfg
.
P2P
)
network
:=
p2p
.
New
(
cfg
.
P2P
)
...
...
plugin/consensus/ticket/testdata/chain33.cfg.toml
View file @
47bbff03
...
@@ -60,6 +60,7 @@ jrpcFuncWhitelist=["*"]
...
@@ -60,6 +60,7 @@ jrpcFuncWhitelist=["*"]
grpcFuncWhitelist
=
["*"]
grpcFuncWhitelist
=
["*"]
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
maxTxNumPerAccount
=
10000
maxTxNumPerAccount
=
10000
...
...
plugin/consensus/ticket/ticket.go
View file @
47bbff03
...
@@ -201,6 +201,11 @@ func (client *Client) setTicket(tlist *ty.ReplyTicketList, privmap map[string]cr
...
@@ -201,6 +201,11 @@ func (client *Client) setTicket(tlist *ty.ReplyTicketList, privmap map[string]cr
client
.
ticketmu
.
Lock
()
client
.
ticketmu
.
Lock
()
defer
client
.
ticketmu
.
Unlock
()
defer
client
.
ticketmu
.
Unlock
()
client
.
ticketsMap
=
make
(
map
[
string
]
*
ty
.
Ticket
)
client
.
ticketsMap
=
make
(
map
[
string
]
*
ty
.
Ticket
)
if
tlist
==
nil
||
privmap
==
nil
{
client
.
ticketsMap
=
nil
client
.
privmap
=
nil
return
}
for
_
,
ticket
:=
range
tlist
.
Tickets
{
for
_
,
ticket
:=
range
tlist
.
Tickets
{
client
.
ticketsMap
[
ticket
.
GetTicketId
()]
=
ticket
client
.
ticketsMap
[
ticket
.
GetTicketId
()]
=
ticket
}
}
...
...
plugin/consensus/ticket/ticket_test.go
View file @
47bbff03
...
@@ -104,11 +104,29 @@ func TestTicketMap(t *testing.T) {
...
@@ -104,11 +104,29 @@ func TestTicketMap(t *testing.T) {
{
TicketId
:
"3333"
},
{
TicketId
:
"3333"
},
{
TicketId
:
"4444"
},
{
TicketId
:
"4444"
},
}
}
privmap
:=
make
(
map
[
string
]
crypto
.
PrivKey
)
//通过privkey生成一个pubkey然后换算成对应的addr
cr
,
_
:=
crypto
.
New
(
"secp256k1"
)
priv
,
_
:=
cr
.
PrivKeyFromBytes
([]
byte
(
"2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989"
))
privmap
[
"1111"
]
=
priv
privmap
[
"2222"
]
=
priv
privmap
[
"3333"
]
=
priv
privmap
[
"4444"
]
=
priv
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
0
))
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
0
))
c
.
setTicket
(
ticketList
,
nil
)
c
.
setTicket
(
ticketList
,
privmap
)
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
4
))
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
4
))
c
.
delTicket
(
"3333"
)
c
.
delTicket
(
"3333"
)
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
3
))
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
3
))
c
.
setTicket
(
ticketList
,
nil
)
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
0
))
c
.
setTicket
(
nil
,
privmap
)
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
0
))
c
.
setTicket
(
nil
,
nil
)
assert
.
Equal
(
t
,
c
.
getTicketCount
(),
int64
(
0
))
}
}
func
TestProcEvent
(
t
*
testing
.
T
)
{
func
TestProcEvent
(
t
*
testing
.
T
)
{
...
...
plugin/dapp/paracross/cmd/build/chain33.para.test.toml
View file @
47bbff03
...
@@ -62,6 +62,7 @@ grpcFuncWhitelist=["*"]
...
@@ -62,6 +62,7 @@ grpcFuncWhitelist=["*"]
mainnetJrpcAddr
=
"http://localhost:8801"
mainnetJrpcAddr
=
"http://localhost:8801"
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
maxTxNumPerAccount
=
10000
maxTxNumPerAccount
=
10000
...
...
plugin/dapp/paracross/cmd/build/chain33.para.toml
View file @
47bbff03
...
@@ -63,6 +63,7 @@ grpcFuncWhitelist=["*"]
...
@@ -63,6 +63,7 @@ grpcFuncWhitelist=["*"]
mainnetJrpcAddr
=
"http://localhost:8801"
mainnetJrpcAddr
=
"http://localhost:8801"
[mempool]
[mempool]
name
=
"timeline"
poolCacheSize
=
10240
poolCacheSize
=
10240
minTxFee
=
100000
minTxFee
=
100000
maxTxNumPerAccount
=
10000
maxTxNumPerAccount
=
10000
...
...
plugin/dapp/privacy/wallet/privacybizpolicy_test.go
View file @
47bbff03
...
@@ -100,9 +100,8 @@ func (mock *testDataMock) initMember() {
...
@@ -100,9 +100,8 @@ func (mock *testDataMock) initMember() {
if
mock
.
mockMempool
{
if
mock
.
mockMempool
{
mock
.
mockMempoolProc
(
q
)
mock
.
mockMempoolProc
(
q
)
}
else
{
}
else
{
mempool
:=
mempool
.
New
(
cfg
.
Mem
Poo
l
)
mempool
:=
mempool
.
New
(
cfg
.
Mem
pool
,
ni
l
)
mempool
.
SetQueueClient
(
q
.
Client
())
mempool
.
SetQueueClient
(
q
.
Client
())
mempool
.
SetMinFee
(
1e5
)
mock
.
modules
=
append
(
mock
.
modules
,
mempool
)
mock
.
modules
=
append
(
mock
.
modules
,
mempool
)
}
}
...
...
plugin/dapp/trade/executor/tradedb.go
View file @
47bbff03
...
@@ -5,6 +5,8 @@
...
@@ -5,6 +5,8 @@
package
executor
package
executor
import
(
import
(
"errors"
"fmt"
"strconv"
"strconv"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/account"
...
@@ -412,10 +414,34 @@ func (action *tradeAction) tradeRevokeSell(revoke *pty.TradeForRevokeSell) (*typ
...
@@ -412,10 +414,34 @@ func (action *tradeAction) tradeRevokeSell(revoke *pty.TradeForRevokeSell) (*typ
return
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
},
nil
return
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
},
nil
}
}
//不同合约之间查询的需求后面要考虑,现在先重复处理一下,原则上不能直接引用其他合约的代码
//后面可能会有一套查询规则 和 写规则, 合约对其他合约只读
func
calcTokenKey
(
token
string
)
(
key
[]
byte
)
{
tokenCreated
:=
"mavl-token-"
return
[]
byte
(
fmt
.
Sprintf
(
tokenCreated
+
"%s"
,
token
))
}
func
checkTokenExist
(
token
string
,
db
dbm
.
KV
)
bool
{
_
,
err
:=
db
.
Get
(
calcTokenKey
(
token
))
return
err
==
nil
}
func
(
action
*
tradeAction
)
tradeBuyLimit
(
buy
*
pty
.
TradeForBuyLimit
)
(
*
types
.
Receipt
,
error
)
{
func
(
action
*
tradeAction
)
tradeBuyLimit
(
buy
*
pty
.
TradeForBuyLimit
)
(
*
types
.
Receipt
,
error
)
{
// ErrTokenNotExist error token symbol not exist
errTokenNotExist
:=
errors
.
New
(
"ErrTokenSymbolNotExist"
)
if
buy
.
TotalBoardlot
<
0
||
buy
.
PricePerBoardlot
<
0
||
buy
.
MinBoardlot
<
0
||
buy
.
AmountPerBoardlot
<
0
{
if
buy
.
TotalBoardlot
<
0
||
buy
.
PricePerBoardlot
<
0
||
buy
.
MinBoardlot
<
0
||
buy
.
AmountPerBoardlot
<
0
{
return
nil
,
types
.
ErrInvalidParam
return
nil
,
types
.
ErrInvalidParam
}
}
// 这个检查会比较鸡肋, 按目前的想法的能支持更多的资产, 各种资产检查不一样
// 可以先让订单成功, 如果不合适, 自己撤单也行
// 或后续跨合约注册一个检测的函数
if
buy
.
AssetExec
==
""
||
buy
.
AssetExec
==
defaultAssetExec
{
// check token exist
if
!
checkTokenExist
(
buy
.
TokenSymbol
,
action
.
db
)
{
return
nil
,
errTokenNotExist
}
}
if
!
checkAsset
(
action
.
height
,
buy
.
AssetExec
,
buy
.
TokenSymbol
)
{
if
!
checkAsset
(
action
.
height
,
buy
.
AssetExec
,
buy
.
TokenSymbol
)
{
return
nil
,
types
.
ErrInvalidParam
return
nil
,
types
.
ErrInvalidParam
...
...
plugin/mempool/trade/const.go
View file @
47bbff03
...
@@ -24,7 +24,4 @@ var (
...
@@ -24,7 +24,4 @@ var (
// TODO
// TODO
func
init
()
{
func
init
()
{
processNum
=
runtime
.
NumCPU
()
processNum
=
runtime
.
NumCPU
()
//if processNum >= 2 {
//processNum -= 1
//}
}
}
vendor/github.com/33cn/chain33/blockchain/blockstore.go
View file @
47bbff03
...
@@ -943,7 +943,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
...
@@ -943,7 +943,7 @@ func (bs *BlockStore) saveBlockSequence(storeBatch dbm.Batch, hash []byte, heigh
storeBatch
.
Set
(
calcSequenceToHashKey
(
newSequence
),
BlockSequenceByte
)
storeBatch
.
Set
(
calcSequenceToHashKey
(
newSequence
),
BlockSequenceByte
)
//parachain hash->seq 只记录add block时的hash和seq对应关系
//parachain hash->seq 只记录add block时的hash和seq对应关系
if
Type
==
AddBlock
&&
isParaChain
{
if
Type
==
AddBlock
{
Sequencebytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
newSequence
})
Sequencebytes
:=
types
.
Encode
(
&
types
.
Int64
{
Data
:
newSequence
})
storeBatch
.
Set
(
calcHashToSequenceKey
(
hash
),
Sequencebytes
)
storeBatch
.
Set
(
calcHashToSequenceKey
(
hash
),
Sequencebytes
)
}
}
...
@@ -991,7 +991,7 @@ func (bs *BlockStore) GetSequenceByHash(hash []byte) (int64, error) {
...
@@ -991,7 +991,7 @@ func (bs *BlockStore) GetSequenceByHash(hash []byte) (int64, error) {
if
err
!=
dbm
.
ErrNotFoundInDb
{
if
err
!=
dbm
.
ErrNotFoundInDb
{
storeLog
.
Error
(
"GetSequenceByHash"
,
"error"
,
err
)
storeLog
.
Error
(
"GetSequenceByHash"
,
"error"
,
err
)
}
}
return
-
1
,
types
.
ErrH
eight
NotExist
return
-
1
,
types
.
ErrH
ash
NotExist
}
}
err
=
types
.
Decode
(
seqbytes
,
&
seq
)
err
=
types
.
Decode
(
seqbytes
,
&
seq
)
...
...
vendor/github.com/33cn/chain33/blockchain/chain_test.go
View file @
47bbff03
...
@@ -634,6 +634,7 @@ func testGetSeqByHash(t *testing.T, blockchain *blockchain.BlockChain) {
...
@@ -634,6 +634,7 @@ func testGetSeqByHash(t *testing.T, blockchain *blockchain.BlockChain) {
reqBlock
.
IsDetail
=
true
reqBlock
.
IsDetail
=
true
hashes
:=
make
([][]
byte
,
1
)
hashes
:=
make
([][]
byte
,
1
)
Sequences
,
err
:=
blockchain
.
GetBlockSequences
(
&
reqBlock
)
Sequences
,
err
:=
blockchain
.
GetBlockSequences
(
&
reqBlock
)
if
err
==
nil
&&
Sequences
!=
nil
{
if
err
==
nil
&&
Sequences
!=
nil
{
for
index
,
sequence
:=
range
Sequences
.
Items
{
for
index
,
sequence
:=
range
Sequences
.
Items
{
hashes
[
index
]
=
sequence
.
Hash
hashes
[
index
]
=
sequence
.
Hash
...
@@ -641,8 +642,8 @@ func testGetSeqByHash(t *testing.T, blockchain *blockchain.BlockChain) {
...
@@ -641,8 +642,8 @@ func testGetSeqByHash(t *testing.T, blockchain *blockchain.BlockChain) {
}
}
seq
,
_
:=
blockchain
.
ProcGetSeqByHash
(
hashes
[
0
])
seq
,
_
:=
blockchain
.
ProcGetSeqByHash
(
hashes
[
0
])
if
seq
!
=
-
1
{
if
seq
=
=
-
1
{
t
.
Error
(
"
testGetSeqByHash only para chain GetSeqByHash
"
)
t
.
Error
(
"
GetSeqByHash err
"
)
}
}
chainlog
.
Info
(
"testGetSeqByHash end --------------------"
)
chainlog
.
Info
(
"testGetSeqByHash end --------------------"
)
...
...
vendor/github.com/33cn/chain33/blockchain/proc.go
View file @
47bbff03
...
@@ -455,11 +455,13 @@ func (chain *BlockChain) addParaChainBlockDetail(msg queue.Message) {
...
@@ -455,11 +455,13 @@ func (chain *BlockChain) addParaChainBlockDetail(msg queue.Message) {
//parachian 通过blockhash获取对应的seq,只记录了addblock时的seq
//parachian 通过blockhash获取对应的seq,只记录了addblock时的seq
func
(
chain
*
BlockChain
)
getSeqByHash
(
msg
queue
.
Message
)
{
func
(
chain
*
BlockChain
)
getSeqByHash
(
msg
queue
.
Message
)
{
var
sequence
types
.
Int64
blockhash
:=
(
msg
.
Data
)
.
(
*
types
.
ReqHash
)
blockhash
:=
(
msg
.
Data
)
.
(
*
types
.
ReqHash
)
sequence
.
Data
,
_
=
chain
.
ProcGetSeqByHash
(
blockhash
.
Hash
)
seq
,
err
:=
chain
.
ProcGetSeqByHash
(
blockhash
.
Hash
)
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventGetSeqByHash
,
&
sequence
))
if
err
!=
nil
{
chainlog
.
Error
(
"getSeqByHash"
,
"err"
,
err
.
Error
())
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventReply
,
err
))
}
msg
.
Reply
(
chain
.
client
.
NewMessage
(
"rpc"
,
types
.
EventGetSeqByHash
,
&
types
.
Int64
{
Data
:
seq
}))
}
}
//获取指定前缀key的数量
//获取指定前缀key的数量
...
...
vendor/github.com/33cn/chain33/blockchain/reindex_test.go
View file @
47bbff03
...
@@ -25,7 +25,7 @@ func TestReindex(t *testing.T) {
...
@@ -25,7 +25,7 @@ func TestReindex(t *testing.T) {
chain
:=
mock33
.
GetBlockChain
()
chain
:=
mock33
.
GetBlockChain
()
db
:=
chain
.
GetDB
()
db
:=
chain
.
GetDB
()
kvs
:=
getAllKeys
(
db
)
kvs
:=
getAllKeys
(
db
)
assert
.
Equal
(
t
,
len
(
kvs
),
19
)
assert
.
Equal
(
t
,
len
(
kvs
),
20
)
defer
mock33
.
Close
()
defer
mock33
.
Close
()
txs
:=
util
.
GenCoinsTxs
(
mock33
.
GetGenesisKey
(),
10
)
txs
:=
util
.
GenCoinsTxs
(
mock33
.
GetGenesisKey
(),
10
)
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
for
i
:=
0
;
i
<
len
(
txs
);
i
++
{
...
...
vendor/github.com/33cn/chain33/build/autotest/copy-autotest.sh
View file @
47bbff03
...
@@ -8,7 +8,7 @@ set -o pipefail
...
@@ -8,7 +8,7 @@ set -o pipefail
# os: ubuntu16.04 x64
# os: ubuntu16.04 x64
#chain33 dapp autotest root directory
#chain33 dapp autotest root directory
declare
-a
Chain33AutoTestDirs
=(
"system"
"plugin"
"vendor/github.com/33cn/chain33/system"
)
declare
-a
Chain33AutoTestDirs
=(
"system"
"plugin"
"vendor/github.com/33cn/chain33/system"
"vendor/github.com/33cn/plugin/plugin"
)
#copy auto test to specific directory
#copy auto test to specific directory
# check args
# check args
...
...
vendor/github.com/33cn/chain33/client/mock_blockchain_test.go
View file @
47bbff03
...
@@ -101,6 +101,9 @@ func (m *mockBlockChain) SetQueueClient(q queue.Queue) {
...
@@ -101,6 +101,9 @@ func (m *mockBlockChain) SetQueueClient(q queue.Queue) {
}
else
{
}
else
{
msg
.
ReplyErr
(
"Do not support"
,
types
.
ErrInvalidParam
)
msg
.
ReplyErr
(
"Do not support"
,
types
.
ErrInvalidParam
)
}
}
case
types
.
EventGetSeqByHash
:
msg
.
Reply
(
client
.
NewMessage
(
blockchainKey
,
types
.
EventReplyQuery
,
&
types
.
Int64
{
Data
:
1
}))
case
types
.
EventIsSync
:
case
types
.
EventIsSync
:
msg
.
Reply
(
client
.
NewMessage
(
blockchainKey
,
types
.
EventReplyIsSync
,
&
types
.
IsCaughtUp
{}))
msg
.
Reply
(
client
.
NewMessage
(
blockchainKey
,
types
.
EventReplyIsSync
,
&
types
.
IsCaughtUp
{}))
case
types
.
EventIsNtpClockSync
:
case
types
.
EventIsNtpClockSync
:
...
...
vendor/github.com/33cn/chain33/client/mocks/api.go
View file @
47bbff03
...
@@ -499,6 +499,29 @@ func (_m *QueueProtocolAPI) GetSeqCallBackLastNum(param *types.ReqString) (*type
...
@@ -499,6 +499,29 @@ func (_m *QueueProtocolAPI) GetSeqCallBackLastNum(param *types.ReqString) (*type
return
r0
,
r1
return
r0
,
r1
}
}
// GetSequenceByHash provides a mock function with given fields: param
func
(
_m
*
QueueProtocolAPI
)
GetSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
{
ret
:=
_m
.
Called
(
param
)
var
r0
*
types
.
Int64
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
*
types
.
ReqHash
)
*
types
.
Int64
);
ok
{
r0
=
rf
(
param
)
}
else
{
if
ret
.
Get
(
0
)
!=
nil
{
r0
=
ret
.
Get
(
0
)
.
(
*
types
.
Int64
)
}
}
var
r1
error
if
rf
,
ok
:=
ret
.
Get
(
1
)
.
(
func
(
*
types
.
ReqHash
)
error
);
ok
{
r1
=
rf
(
param
)
}
else
{
r1
=
ret
.
Error
(
1
)
}
return
r0
,
r1
}
// GetTransactionByAddr provides a mock function with given fields: param
// GetTransactionByAddr provides a mock function with given fields: param
func
(
_m
*
QueueProtocolAPI
)
GetTransactionByAddr
(
param
*
types
.
ReqAddr
)
(
*
types
.
ReplyTxInfos
,
error
)
{
func
(
_m
*
QueueProtocolAPI
)
GetTransactionByAddr
(
param
*
types
.
ReqAddr
)
(
*
types
.
ReplyTxInfos
,
error
)
{
ret
:=
_m
.
Called
(
param
)
ret
:=
_m
.
Called
(
param
)
...
...
vendor/github.com/33cn/chain33/client/queueprotocol.go
View file @
47bbff03
...
@@ -898,6 +898,25 @@ func (q *QueueProtocol) GetLastBlockSequence() (*types.Int64, error) {
...
@@ -898,6 +898,25 @@ func (q *QueueProtocol) GetLastBlockSequence() (*types.Int64, error) {
return
nil
,
types
.
ErrTypeAsset
return
nil
,
types
.
ErrTypeAsset
}
}
// GetSequenceByHash 通过hash获取对应的执行序列号
func
(
q
*
QueueProtocol
)
GetSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
{
if
param
==
nil
{
err
:=
types
.
ErrInvalidParam
log
.
Error
(
"GetSequenceByHash"
,
"Error"
,
err
)
return
nil
,
err
}
msg
,
err
:=
q
.
query
(
blockchainKey
,
types
.
EventGetSeqByHash
,
param
)
if
err
!=
nil
{
log
.
Error
(
"GetSequenceByHash"
,
"Error"
,
err
.
Error
())
return
nil
,
err
}
if
reply
,
ok
:=
msg
.
GetData
()
.
(
*
types
.
Int64
);
ok
{
return
reply
,
nil
}
return
nil
,
types
.
ErrTypeAsset
}
// WalletCreateTx create transaction
// WalletCreateTx create transaction
func
(
q
*
QueueProtocol
)
WalletCreateTx
(
param
*
types
.
ReqCreateTransaction
)
(
*
types
.
Transaction
,
error
)
{
func
(
q
*
QueueProtocol
)
WalletCreateTx
(
param
*
types
.
ReqCreateTransaction
)
(
*
types
.
Transaction
,
error
)
{
msg
,
err
:=
q
.
query
(
walletKey
,
types
.
EventWalletCreateTx
,
param
)
msg
,
err
:=
q
.
query
(
walletKey
,
types
.
EventWalletCreateTx
,
param
)
...
...
vendor/github.com/33cn/chain33/client/queueprotocol_test.go
View file @
47bbff03
...
@@ -806,6 +806,7 @@ func TestGRPC(t *testing.T) {
...
@@ -806,6 +806,7 @@ func TestGRPC(t *testing.T) {
testGetBlockOverviewGRPC
(
t
,
&
grpcMock
)
testGetBlockOverviewGRPC
(
t
,
&
grpcMock
)
testGetAddrOverviewGRPC
(
t
,
&
grpcMock
)
testGetAddrOverviewGRPC
(
t
,
&
grpcMock
)
testGetBlockHashGRPC
(
t
,
&
grpcMock
)
testGetBlockHashGRPC
(
t
,
&
grpcMock
)
testGetSequenceByHashGRPC
(
t
,
&
grpcMock
)
testGenSeedGRPC
(
t
,
&
grpcMock
)
testGenSeedGRPC
(
t
,
&
grpcMock
)
testGetSeedGRPC
(
t
,
&
grpcMock
)
testGetSeedGRPC
(
t
,
&
grpcMock
)
testSaveSeedGRPC
(
t
,
&
grpcMock
)
testSaveSeedGRPC
(
t
,
&
grpcMock
)
...
@@ -1131,3 +1132,11 @@ func testSendTxGRPC(t *testing.T, rpc *mockGRPCSystem) {
...
@@ -1131,3 +1132,11 @@ func testSendTxGRPC(t *testing.T, rpc *mockGRPCSystem) {
t
.
Error
(
"Call SendTransaction Failed."
,
err
)
t
.
Error
(
"Call SendTransaction Failed."
,
err
)
}
}
}
}
func
testGetSequenceByHashGRPC
(
t
*
testing
.
T
,
rpc
*
mockGRPCSystem
)
{
var
res
types
.
Int64
err
:=
rpc
.
newRpcCtx
(
"GetSequenceByHash"
,
&
types
.
ReqHash
{},
&
res
)
if
err
!=
nil
{
t
.
Error
(
"Call GetSequenceByHash Failed."
,
err
)
}
}
vendor/github.com/33cn/chain33/client/queueprotocolapi.go
View file @
47bbff03
...
@@ -111,6 +111,8 @@ type QueueProtocolAPI interface {
...
@@ -111,6 +111,8 @@ type QueueProtocolAPI interface {
GetBlockSequences
(
param
*
types
.
ReqBlocks
)
(
*
types
.
BlockSequences
,
error
)
GetBlockSequences
(
param
*
types
.
ReqBlocks
)
(
*
types
.
BlockSequences
,
error
)
//types.EventGetBlockByHashes:
//types.EventGetBlockByHashes:
GetBlockByHashes
(
param
*
types
.
ReqHashes
)
(
*
types
.
BlockDetails
,
error
)
GetBlockByHashes
(
param
*
types
.
ReqHashes
)
(
*
types
.
BlockDetails
,
error
)
//types.EventGetSequenceByHash:
GetSequenceByHash
(
param
*
types
.
ReqHash
)
(
*
types
.
Int64
,
error
)
// --------------- blockchain interfaces end
// --------------- blockchain interfaces end
...
...
vendor/github.com/33cn/chain33/client/rpc_ctx_test.go
View file @
47bbff03
...
@@ -315,6 +315,12 @@ func (c *GrpcCtx) Run() (err error) {
...
@@ -315,6 +315,12 @@ func (c *GrpcCtx) Run() (err error) {
*
c
.
Res
.
(
*
types
.
NodeNetInfo
)
=
*
reply
*
c
.
Res
.
(
*
types
.
NodeNetInfo
)
=
*
reply
}
}
errRet
=
err
errRet
=
err
case
"GetSequenceByHash"
:
reply
,
err
:=
rpc
.
GetSequenceByHash
(
context
.
Background
(),
c
.
Params
.
(
*
types
.
ReqHash
))
if
err
==
nil
{
*
c
.
Res
.
(
*
types
.
Int64
)
=
*
reply
}
errRet
=
err
default
:
default
:
errRet
=
errors
.
New
(
fmt
.
Sprintf
(
"Unsupport method %v"
,
c
.
Method
))
errRet
=
errors
.
New
(
fmt
.
Sprintf
(
"Unsupport method %v"
,
c
.
Method
))
}
}
...
...
vendor/github.com/33cn/chain33/common/address/address.go
View file @
47bbff03
...
@@ -18,13 +18,24 @@ import (
...
@@ -18,13 +18,24 @@ import (
var
addrSeed
=
[]
byte
(
"address seed bytes for public key"
)
var
addrSeed
=
[]
byte
(
"address seed bytes for public key"
)
var
addressCache
*
lru
.
Cache
var
addressCache
*
lru
.
Cache
var
checkAddressCache
*
lru
.
Cache
var
checkAddressCache
*
lru
.
Cache
var
multisignCache
*
lru
.
Cache
var
multiCheckAddressCache
*
lru
.
Cache
var
errVersion
=
errors
.
New
(
"check version error"
)
//MaxExecNameLength 执行器名最大长度
//MaxExecNameLength 执行器名最大长度
const
MaxExecNameLength
=
100
const
MaxExecNameLength
=
100
//NormalVer 普通地址的版本号
const
NormalVer
byte
=
0
//MultiSignVer 多重签名地址的版本号
const
MultiSignVer
byte
=
5
func
init
()
{
func
init
()
{
multisignCache
,
_
=
lru
.
New
(
10240
)
addressCache
,
_
=
lru
.
New
(
10240
)
addressCache
,
_
=
lru
.
New
(
10240
)
checkAddressCache
,
_
=
lru
.
New
(
10240
)
checkAddressCache
,
_
=
lru
.
New
(
10240
)
multiCheckAddressCache
,
_
=
lru
.
New
(
10240
)
}
}
//ExecPubKey 计算公钥
//ExecPubKey 计算公钥
...
@@ -44,12 +55,23 @@ func ExecAddress(name string) string {
...
@@ -44,12 +55,23 @@ func ExecAddress(name string) string {
if
value
,
ok
:=
addressCache
.
Get
(
name
);
ok
{
if
value
,
ok
:=
addressCache
.
Get
(
name
);
ok
{
return
value
.
(
string
)
return
value
.
(
string
)
}
}
addr
:=
PubKeyToAddress
(
ExecPubkey
(
name
)
)
addr
:=
GetExecAddress
(
name
)
addrstr
:=
addr
.
String
()
addrstr
:=
addr
.
String
()
addressCache
.
Add
(
name
,
addrstr
)
addressCache
.
Add
(
name
,
addrstr
)
return
addrstr
return
addrstr
}
}
//MultiSignAddress create a multi sign address
func
MultiSignAddress
(
pubkey
[]
byte
)
string
{
if
value
,
ok
:=
multisignCache
.
Get
(
string
(
pubkey
));
ok
{
return
value
.
(
string
)
}
addr
:=
HashToAddress
(
MultiSignVer
,
pubkey
)
addrstr
:=
addr
.
String
()
multisignCache
.
Add
(
string
(
pubkey
),
addrstr
)
return
addrstr
}
//ExecPubkey 计算公钥
//ExecPubkey 计算公钥
func
ExecPubkey
(
name
string
)
[]
byte
{
func
ExecPubkey
(
name
string
)
[]
byte
{
if
len
(
name
)
>
MaxExecNameLength
{
if
len
(
name
)
>
MaxExecNameLength
{
...
@@ -64,35 +86,27 @@ func ExecPubkey(name string) []byte {
...
@@ -64,35 +86,27 @@ func ExecPubkey(name string) []byte {
//GetExecAddress 获取地址
//GetExecAddress 获取地址
func
GetExecAddress
(
name
string
)
*
Address
{
func
GetExecAddress
(
name
string
)
*
Address
{
if
len
(
name
)
>
MaxExecNameLength
{
hash
:=
ExecPubkey
(
name
)
panic
(
"name too long"
)
}
var
bname
[
200
]
byte
buf
:=
append
(
bname
[
:
0
],
addrSeed
...
)
buf
=
append
(
buf
,
[]
byte
(
name
)
...
)
hash
:=
common
.
Sha2Sum
(
buf
)
addr
:=
PubKeyToAddress
(
hash
[
:
])
addr
:=
PubKeyToAddress
(
hash
[
:
])
return
addr
return
addr
}
}
//PubKeyToAddress 公钥转为地址
//PubKeyToAddress 公钥转为地址
func
PubKeyToAddress
(
in
[]
byte
)
*
Address
{
func
PubKeyToAddress
(
in
[]
byte
)
*
Address
{
return
HashToAddress
(
NormalVer
,
in
)
}
//HashToAddress hash32 to address
func
HashToAddress
(
version
byte
,
in
[]
byte
)
*
Address
{
a
:=
new
(
Address
)
a
:=
new
(
Address
)
a
.
Pubkey
=
make
([]
byte
,
len
(
in
))
a
.
Pubkey
=
make
([]
byte
,
len
(
in
))
copy
(
a
.
Pubkey
[
:
],
in
[
:
])
copy
(
a
.
Pubkey
[
:
],
in
[
:
])
a
.
Version
=
0
a
.
Version
=
version
a
.
Hash160
=
common
.
Rimp160AfterSha256
(
in
)
a
.
Hash160
=
common
.
Rimp160AfterSha256
(
in
)
return
a
return
a
}
}
//CheckAddress 检查地址
func
checkAddress
(
ver
byte
,
addr
string
)
(
e
error
)
{
func
CheckAddress
(
addr
string
)
(
e
error
)
{
if
value
,
ok
:=
checkAddressCache
.
Get
(
addr
);
ok
{
if
value
==
nil
{
return
nil
}
return
value
.
(
error
)
}
dec
:=
base58
.
Decode
(
addr
)
dec
:=
base58
.
Decode
(
addr
)
if
dec
==
nil
{
if
dec
==
nil
{
e
=
errors
.
New
(
"Cannot decode b58 string '"
+
addr
+
"'"
)
e
=
errors
.
New
(
"Cannot decode b58 string '"
+
addr
+
"'"
)
...
@@ -110,6 +124,34 @@ func CheckAddress(addr string) (e error) {
...
@@ -110,6 +124,34 @@ func CheckAddress(addr string) (e error) {
e
=
errors
.
New
(
"Address Checksum error"
)
e
=
errors
.
New
(
"Address Checksum error"
)
}
}
}
}
if
dec
[
0
]
!=
ver
{
e
=
errVersion
}
return
e
}
//CheckMultiSignAddress 检查多重签名地址的有效性
func
CheckMultiSignAddress
(
addr
string
)
(
e
error
)
{
if
value
,
ok
:=
multiCheckAddressCache
.
Get
(
addr
);
ok
{
if
value
==
nil
{
return
nil
}
return
value
.
(
error
)
}
e
=
checkAddress
(
MultiSignVer
,
addr
)
multiCheckAddressCache
.
Add
(
addr
,
e
)
return
}
//CheckAddress 检查地址
func
CheckAddress
(
addr
string
)
(
e
error
)
{
if
value
,
ok
:=
checkAddressCache
.
Get
(
addr
);
ok
{
if
value
==
nil
{
return
nil
}
return
value
.
(
error
)
}
e
=
checkAddress
(
NormalVer
,
addr
)
checkAddressCache
.
Add
(
addr
,
e
)
checkAddressCache
.
Add
(
addr
,
e
)
return
return
}
}
...
...
vendor/github.com/33cn/chain33/common/address/address_test.go
View file @
47bbff03
...
@@ -12,27 +12,42 @@ import (
...
@@ -12,27 +12,42 @@ import (
"time"
"time"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/crypto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
_
"github.com/33cn/chain33/system/crypto/init"
_
"github.com/33cn/chain33/system/crypto/init"
)
)
func
TestAddress
(
t
*
testing
.
T
)
{
func
genkey
()
crypto
.
PrivKey
{
c
,
err
:=
crypto
.
New
(
"secp256k1"
)
c
,
err
:=
crypto
.
New
(
"secp256k1"
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
err
)
panic
(
err
)
return
}
}
key
,
err
:=
c
.
GenKey
()
key
,
err
:=
c
.
GenKey
()
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Error
(
err
)
panic
(
err
)
return
}
}
return
key
}
func
TestAddress
(
t
*
testing
.
T
)
{
key
:=
genkey
()
t
.
Logf
(
"%X"
,
key
.
Bytes
())
t
.
Logf
(
"%X"
,
key
.
Bytes
())
addr
:=
PubKeyToAddress
(
key
.
PubKey
()
.
Bytes
())
addr
:=
PubKeyToAddress
(
key
.
PubKey
()
.
Bytes
())
t
.
Log
(
addr
)
t
.
Log
(
addr
)
}
}
func
TestMultiSignAddress
(
t
*
testing
.
T
)
{
key
:=
genkey
()
addr1
:=
MultiSignAddress
(
key
.
PubKey
()
.
Bytes
())
addr
:=
MultiSignAddress
(
key
.
PubKey
()
.
Bytes
())
assert
.
Equal
(
t
,
addr1
,
addr
)
err
:=
CheckAddress
(
addr
)
assert
.
Equal
(
t
,
errVersion
,
err
)
err
=
CheckMultiSignAddress
(
addr
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
addr
)
}
func
TestPubkeyToAddress
(
t
*
testing
.
T
)
{
func
TestPubkeyToAddress
(
t
*
testing
.
T
)
{
pubkey
:=
"024a17b0c6eb3143839482faa7e917c9b90a8cfe5008dff748789b8cea1a3d08d5"
pubkey
:=
"024a17b0c6eb3143839482faa7e917c9b90a8cfe5008dff748789b8cea1a3d08d5"
b
,
err
:=
hex
.
DecodeString
(
pubkey
)
b
,
err
:=
hex
.
DecodeString
(
pubkey
)
...
@@ -61,6 +76,14 @@ func TestCheckAddress(t *testing.T) {
...
@@ -61,6 +76,14 @@ func TestCheckAddress(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
}
}
func
TestExecAddress
(
t
*
testing
.
T
)
{
assert
.
Equal
(
t
,
"16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
,
ExecAddress
(
"ticket"
))
assert
.
Equal
(
t
,
"16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
,
ExecAddress
(
"ticket"
))
addr
,
err
:=
NewAddrFromString
(
ExecAddress
(
"ticket"
))
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
addr
.
Version
,
NormalVer
)
}
func
BenchmarkExecAddress
(
b
*
testing
.
B
)
{
func
BenchmarkExecAddress
(
b
*
testing
.
B
)
{
start
:=
time
.
Now
()
.
UnixNano
()
/
1000000
start
:=
time
.
Now
()
.
UnixNano
()
/
1000000
fmt
.
Println
(
start
)
fmt
.
Println
(
start
)
...
...
vendor/github.com/33cn/chain33/rpc/client.go
View file @
47bbff03
...
@@ -47,6 +47,9 @@ func (c *channelClient) CreateRawTransaction(param *types.CreateTx) ([]byte, err
...
@@ -47,6 +47,9 @@ func (c *channelClient) CreateRawTransaction(param *types.CreateTx) ([]byte, err
if
param
.
IsToken
{
if
param
.
IsToken
{
execer
=
types
.
ExecName
(
"token"
)
execer
=
types
.
ExecName
(
"token"
)
}
}
if
param
.
Execer
!=
""
{
execer
=
param
.
Execer
}
return
types
.
CallCreateTx
(
execer
,
""
,
param
)
return
types
.
CallCreateTx
(
execer
,
""
,
param
)
}
}
...
...
vendor/github.com/33cn/chain33/rpc/client_test.go
View file @
47bbff03
...
@@ -88,23 +88,6 @@ func testCreateRawTransactionCoinTransfer(t *testing.T) {
...
@@ -88,23 +88,6 @@ func testCreateRawTransactionCoinTransfer(t *testing.T) {
Note
:
[]
byte
(
"note"
),
Note
:
[]
byte
(
"note"
),
}
}
//v := &cty.CoinsAction_Transfer{
// Transfer:&cty.CoinsTransfer{
// Amount:ctx.Amount,
// Note:ctx.To,
// },
//}
//transfer := &cty.CoinsAction{
// Value:v,
// Ty:cty.CoinsActionTransfer,
//}
//
//tx := &types.Transaction{
// Execer:[]byte("coins"),
// Payload:types.Encode(transfer),
// To:ctx.To,
//}
client
:=
newTestChannelClient
()
client
:=
newTestChannelClient
()
txHex
,
err
:=
client
.
CreateRawTransaction
(
&
ctx
)
txHex
,
err
:=
client
.
CreateRawTransaction
(
&
ctx
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
...
...
vendor/github.com/33cn/chain33/rpc/grpchandler.go
View file @
47bbff03
...
@@ -38,7 +38,8 @@ func (g *Grpc) CreateRawTransaction(ctx context.Context, in *pb.CreateTx) (*pb.U
...
@@ -38,7 +38,8 @@ func (g *Grpc) CreateRawTransaction(ctx context.Context, in *pb.CreateTx) (*pb.U
// CreateTransaction create transaction of grpc
// CreateTransaction create transaction of grpc
func
(
g
*
Grpc
)
CreateTransaction
(
ctx
context
.
Context
,
in
*
pb
.
CreateTxIn
)
(
*
pb
.
UnsignTx
,
error
)
{
func
(
g
*
Grpc
)
CreateTransaction
(
ctx
context
.
Context
,
in
*
pb
.
CreateTxIn
)
(
*
pb
.
UnsignTx
,
error
)
{
exec
:=
pb
.
LoadExecutorType
(
string
(
in
.
Execer
))
execer
:=
pb
.
ExecName
(
string
(
in
.
Execer
))
exec
:=
pb
.
LoadExecutorType
(
execer
)
if
exec
==
nil
{
if
exec
==
nil
{
log
.
Error
(
"callExecNewTx"
,
"Error"
,
"exec not found"
)
log
.
Error
(
"callExecNewTx"
,
"Error"
,
"exec not found"
)
return
nil
,
pb
.
ErrNotSupport
return
nil
,
pb
.
ErrNotSupport
...
@@ -52,7 +53,7 @@ func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.Un
...
@@ -52,7 +53,7 @@ func (g *Grpc) CreateTransaction(ctx context.Context, in *pb.CreateTxIn) (*pb.Un
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
reply
,
err
:=
pb
.
CallCreateTx
(
string
(
in
.
Execer
)
,
in
.
ActionName
,
msg
)
reply
,
err
:=
pb
.
CallCreateTx
(
execer
,
in
.
ActionName
,
msg
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -344,6 +345,11 @@ func (g *Grpc) GetBlockByHashes(ctx context.Context, in *pb.ReqHashes) (*pb.Bloc
...
@@ -344,6 +345,11 @@ func (g *Grpc) GetBlockByHashes(ctx context.Context, in *pb.ReqHashes) (*pb.Bloc
return
g
.
cli
.
GetBlockByHashes
(
in
)
return
g
.
cli
.
GetBlockByHashes
(
in
)
}
}
// GetSequenceByHash get block sequece by hash
func
(
g
*
Grpc
)
GetSequenceByHash
(
ctx
context
.
Context
,
in
*
pb
.
ReqHash
)
(
*
pb
.
Int64
,
error
)
{
return
g
.
cli
.
GetSequenceByHash
(
in
)
}
// SignRawTx signature rawtransaction
// SignRawTx signature rawtransaction
func
(
g
*
Grpc
)
SignRawTx
(
ctx
context
.
Context
,
in
*
pb
.
ReqSignRawTx
)
(
*
pb
.
ReplySignRawTx
,
error
)
{
func
(
g
*
Grpc
)
SignRawTx
(
ctx
context
.
Context
,
in
*
pb
.
ReqSignRawTx
)
(
*
pb
.
ReplySignRawTx
,
error
)
{
return
g
.
cli
.
SignRawTx
(
in
)
return
g
.
cli
.
SignRawTx
(
in
)
...
...
vendor/github.com/33cn/chain33/rpc/jrpchandler.go
View file @
47bbff03
...
@@ -20,12 +20,26 @@ import (
...
@@ -20,12 +20,26 @@ import (
)
)
// CreateRawTransaction create rawtransaction by jrpc
// CreateRawTransaction create rawtransaction by jrpc
func
(
c
*
Chain33
)
CreateRawTransaction
(
in
*
types
.
CreateTx
,
result
*
interface
{})
error
{
func
(
c
*
Chain33
)
CreateRawTransaction
(
in
*
rpctypes
.
CreateTx
,
result
*
interface
{})
error
{
reply
,
err
:=
c
.
cli
.
CreateRawTransaction
(
in
)
if
in
==
nil
{
log
.
Error
(
"CreateRawTransaction"
,
"Error"
,
types
.
ErrInvalidParam
)
return
types
.
ErrInvalidParam
}
inpb
:=
&
types
.
CreateTx
{
To
:
in
.
To
,
Amount
:
in
.
Amount
,
Fee
:
in
.
Fee
,
Note
:
[]
byte
(
in
.
Note
),
IsWithdraw
:
in
.
IsWithdraw
,
IsToken
:
in
.
IsToken
,
TokenSymbol
:
in
.
TokenSymbol
,
ExecName
:
in
.
ExecName
,
Execer
:
in
.
Execer
,
}
reply
,
err
:=
c
.
cli
.
CreateRawTransaction
(
inpb
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
*
result
=
hex
.
EncodeToString
(
reply
)
*
result
=
hex
.
EncodeToString
(
reply
)
return
nil
return
nil
}
}
...
@@ -404,50 +418,6 @@ func (c *Chain33) ImportPrivkey(in types.ReqWalletImportPrivkey, result *interfa
...
@@ -404,50 +418,6 @@ func (c *Chain33) ImportPrivkey(in types.ReqWalletImportPrivkey, result *interfa
// SendToAddress send to address of coins
// SendToAddress send to address of coins
func
(
c
*
Chain33
)
SendToAddress
(
in
types
.
ReqWalletSendToAddress
,
result
*
interface
{})
error
{
func
(
c
*
Chain33
)
SendToAddress
(
in
types
.
ReqWalletSendToAddress
,
result
*
interface
{})
error
{
log
.
Debug
(
"Rpc SendToAddress"
,
"Tx"
,
in
)
if
types
.
IsPara
()
{
createTx
:=
&
types
.
CreateTx
{
To
:
in
.
GetTo
(),
Amount
:
in
.
GetAmount
(),
Fee
:
1e5
,
Note
:
in
.
GetNote
(),
IsWithdraw
:
false
,
IsToken
:
true
,
TokenSymbol
:
in
.
GetTokenSymbol
(),
ExecName
:
types
.
ExecName
(
"token"
),
}
tx
,
err
:=
c
.
cli
.
CreateRawTransaction
(
createTx
)
if
err
!=
nil
{
log
.
Debug
(
"ParaChain CreateRawTransaction"
,
"Error"
,
err
.
Error
())
return
err
}
//不需要自己去导出私钥,signRawTx 里面只需带入公钥地址,也回优先去查出相应的私钥,前提是私钥已经导入
reqSignRawTx
:=
&
types
.
ReqSignRawTx
{
Addr
:
in
.
From
,
Privkey
:
""
,
TxHex
:
hex
.
EncodeToString
(
tx
),
Expire
:
"300s"
,
Index
:
0
,
Token
:
""
,
}
replySignRawTx
,
err
:=
c
.
cli
.
SignRawTx
(
reqSignRawTx
)
if
err
!=
nil
{
log
.
Debug
(
"ParaChain SignRawTx"
,
"Error"
,
err
.
Error
())
return
err
}
rawParm
:=
rpctypes
.
RawParm
{
Token
:
""
,
Data
:
replySignRawTx
.
GetTxHex
(),
}
var
txHash
interface
{}
err
=
forwardTranToMainNet
(
rawParm
,
&
txHash
)
if
err
!=
nil
{
log
.
Debug
(
"ParaChain forwardTranToMainNet"
,
"Error"
,
err
.
Error
())
return
err
}
*
result
=
&
rpctypes
.
ReplyHash
{
Hash
:
txHash
.
(
string
)}
return
nil
}
reply
,
err
:=
c
.
cli
.
WalletSendToAddress
(
&
in
)
reply
,
err
:=
c
.
cli
.
WalletSendToAddress
(
&
in
)
if
err
!=
nil
{
if
err
!=
nil
{
log
.
Debug
(
"SendToAddress"
,
"Error"
,
err
.
Error
())
log
.
Debug
(
"SendToAddress"
,
"Error"
,
err
.
Error
())
...
@@ -1120,7 +1090,7 @@ func (c *Chain33) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{}
...
@@ -1120,7 +1090,7 @@ func (c *Chain33) CreateTransaction(in *rpctypes.CreateTxIn, result *interface{}
if
in
==
nil
{
if
in
==
nil
{
return
types
.
ErrInvalidParam
return
types
.
ErrInvalidParam
}
}
btx
,
err
:=
types
.
CallCreateTxJSON
(
in
.
Execer
,
in
.
ActionName
,
in
.
Payload
)
btx
,
err
:=
types
.
CallCreateTxJSON
(
types
.
ExecName
(
in
.
Execer
)
,
in
.
ActionName
,
in
.
Payload
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
vendor/github.com/33cn/chain33/rpc/jrpchandler_test.go
View file @
47bbff03
...
@@ -387,11 +387,11 @@ func TestChain33_CreateRawTransaction(t *testing.T) {
...
@@ -387,11 +387,11 @@ func TestChain33_CreateRawTransaction(t *testing.T) {
assert
.
Nil
(
t
,
testResult
)
assert
.
Nil
(
t
,
testResult
)
assert
.
NotNil
(
t
,
err
)
assert
.
NotNil
(
t
,
err
)
tx
:=
&
types
.
CreateTx
{
tx
:=
&
rpc
types
.
CreateTx
{
To
:
"
qew
"
,
To
:
"
184wj4nsgVxKyz2NhM3Yb5RK5Ap6AFRFq2
"
,
Amount
:
10
,
Amount
:
10
,
Fee
:
1
,
Fee
:
1
,
Note
:
[]
byte
(
"12312"
)
,
Note
:
"12312"
,
IsWithdraw
:
false
,
IsWithdraw
:
false
,
IsToken
:
false
,
IsToken
:
false
,
TokenSymbol
:
""
,
TokenSymbol
:
""
,
...
...
vendor/github.com/33cn/chain33/rpc/rpc_real_test.go
View file @
47bbff03
...
@@ -5,10 +5,10 @@
...
@@ -5,10 +5,10 @@
package
rpc_test
package
rpc_test
import
(
import
(
"fmt"
"testing"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"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/types"
"github.com/33cn/chain33/types"
...
@@ -19,16 +19,18 @@ import (
...
@@ -19,16 +19,18 @@ import (
_
"github.com/33cn/chain33/system"
_
"github.com/33cn/chain33/system"
)
)
func
getRPCClient
(
t
*
testing
.
T
,
mocker
*
testnode
.
Chain33Mock
)
*
jsonclient
.
JSONClient
{
jrpcClient
:=
mocker
.
GetJSONC
()
assert
.
NotNil
(
t
,
jrpcClient
)
return
jrpcClient
}
func
TestErrLog
(
t
*
testing
.
T
)
{
func
TestErrLog
(
t
*
testing
.
T
)
{
// 启动RPCmocker
// 启动RPCmocker
mocker
:=
testnode
.
New
(
"--free--"
,
nil
)
mocker
:=
testnode
.
New
(
"--free--"
,
nil
)
defer
mocker
.
Close
()
defer
mocker
.
Close
()
mocker
.
Listen
()
mocker
.
Listen
()
jrpcClient
:=
getRPCClient
(
t
,
mocker
)
rpcCfg
:=
mocker
.
GetCfg
()
.
RPC
jrpcClient
,
err
:=
jsonclient
.
NewJSONClient
(
fmt
.
Sprintf
(
"http://%s/"
,
rpcCfg
.
JrpcBindAddr
))
assert
.
NoError
(
t
,
err
)
assert
.
NotNil
(
t
,
jrpcClient
)
gen
:=
mocker
.
GetGenesisKey
()
gen
:=
mocker
.
GetGenesisKey
()
//发送交易到区块链
//发送交易到区块链
addr1
,
key1
:=
util
.
Genaddress
()
addr1
,
key1
:=
util
.
Genaddress
()
...
@@ -55,3 +57,43 @@ func TestErrLog(t *testing.T) {
...
@@ -55,3 +57,43 @@ func TestErrLog(t *testing.T) {
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
string
(
testResult
.
Receipt
.
Logs
[
0
]
.
Log
),
`"ErrNoBalance"`
)
assert
.
Equal
(
t
,
string
(
testResult
.
Receipt
.
Logs
[
0
]
.
Log
),
`"ErrNoBalance"`
)
}
}
func
getTx
(
t
*
testing
.
T
,
hex
string
)
*
types
.
Transaction
{
data
,
err
:=
common
.
FromHex
(
hex
)
assert
.
Nil
(
t
,
err
)
var
tx
types
.
Transaction
err
=
types
.
Decode
(
data
,
&
tx
)
assert
.
Nil
(
t
,
err
)
return
&
tx
}
func
TestSendToExec
(
t
*
testing
.
T
)
{
mocker
:=
testnode
.
New
(
"--free--"
,
nil
)
defer
mocker
.
Close
()
mocker
.
Listen
()
jrpcClient
:=
getRPCClient
(
t
,
mocker
)
//1. 调用createrawtransaction 创建交易
req
:=
&
rpctypes
.
CreateTx
{
To
:
address
.
ExecAddress
(
"user.f3d"
),
Amount
:
10
,
Fee
:
1
,
Note
:
"12312"
,
IsWithdraw
:
false
,
IsToken
:
false
,
TokenSymbol
:
""
,
ExecName
:
"user.f3d"
,
}
var
res
string
err
:=
jrpcClient
.
Call
(
"Chain33.CreateRawTransaction"
,
req
,
&
res
)
assert
.
Nil
(
t
,
err
)
gen
:=
mocker
.
GetGenesisKey
()
tx
:=
getTx
(
t
,
res
)
tx
.
Sign
(
types
.
SECP256K1
,
gen
)
reply
,
err
:=
mocker
.
GetAPI
()
.
SendTx
(
tx
)
assert
.
Nil
(
t
,
err
)
_
,
err
=
mocker
.
WaitTx
(
reply
.
GetMsg
())
assert
.
Nil
(
t
,
err
)
block
:=
mocker
.
GetLastBlock
()
balance
:=
mocker
.
GetExecAccount
(
block
.
StateHash
,
"user.f3d"
,
mocker
.
GetGenesisAddress
())
.
Balance
assert
.
Equal
(
t
,
int64
(
10
),
balance
)
}
vendor/github.com/33cn/chain33/rpc/server_test.go
View file @
47bbff03
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
package
rpc
package
rpc
import
(
import
(
"encoding/hex"
"errors"
"errors"
"testing"
"testing"
"time"
"time"
...
@@ -114,10 +115,33 @@ func TestJSONClient_Call(t *testing.T) {
...
@@ -114,10 +115,33 @@ func TestJSONClient_Call(t *testing.T) {
err
=
jsonClient
.
Call
(
"Chain33.IsNtpClockSync"
,
&
types
.
ReqNil
{},
&
retNtp
)
err
=
jsonClient
.
Call
(
"Chain33.IsNtpClockSync"
,
&
types
.
ReqNil
{},
&
retNtp
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
assert
.
True
(
t
,
retNtp
)
assert
.
True
(
t
,
retNtp
)
testCreateTxCoins
(
t
,
jsonClient
)
server
.
Close
()
server
.
Close
()
mock
.
AssertExpectationsForObjects
(
t
,
api
)
mock
.
AssertExpectationsForObjects
(
t
,
api
)
}
}
func
testCreateTxCoins
(
t
*
testing
.
T
,
jsonClient
*
jsonclient
.
JSONClient
)
{
req
:=
&
rpctypes
.
CreateTx
{
To
:
"184wj4nsgVxKyz2NhM3Yb5RK5Ap6AFRFq2"
,
Amount
:
10
,
Fee
:
1
,
Note
:
"12312"
,
IsWithdraw
:
false
,
IsToken
:
false
,
TokenSymbol
:
""
,
ExecName
:
types
.
ExecName
(
"coins"
),
}
var
res
string
err
:=
jsonClient
.
Call
(
"Chain33.CreateRawTransaction"
,
req
,
&
res
)
assert
.
Nil
(
t
,
err
)
txbytes
,
err
:=
hex
.
DecodeString
(
res
)
assert
.
Nil
(
t
,
err
)
var
tx
types
.
Transaction
err
=
types
.
Decode
(
txbytes
,
&
tx
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
"184wj4nsgVxKyz2NhM3Yb5RK5Ap6AFRFq2"
,
tx
.
To
)
}
func
TestGrpc_Call
(
t
*
testing
.
T
)
{
func
TestGrpc_Call
(
t
*
testing
.
T
)
{
rpcCfg
=
new
(
types
.
RPC
)
rpcCfg
=
new
(
types
.
RPC
)
rpcCfg
.
GrpcBindAddr
=
"127.0.0.1:8101"
rpcCfg
.
GrpcBindAddr
=
"127.0.0.1:8101"
...
...
vendor/github.com/33cn/chain33/rpc/types/types.go
View file @
47bbff03
...
@@ -360,3 +360,16 @@ type ExecAccount struct {
...
@@ -360,3 +360,16 @@ type ExecAccount struct {
type
ExecNameParm
struct
{
type
ExecNameParm
struct
{
ExecName
string
`json:"execname"`
ExecName
string
`json:"execname"`
}
}
//CreateTx 为了简化Note 的创建过程,在json rpc 中,note 采用string 格式
type
CreateTx
struct
{
To
string
`json:"to,omitempty"`
Amount
int64
`json:"amount,omitempty"`
Fee
int64
`json:"fee,omitempty"`
Note
string
`json:"note,omitempty"`
IsWithdraw
bool
`json:"isWithdraw,omitempty"`
IsToken
bool
`json:"isToken,omitempty"`
TokenSymbol
string
`json:"tokenSymbol,omitempty"`
ExecName
string
`json:"execName,omitempty"`
//TransferToExec and Withdraw 的执行器
Execer
string
`json:"execer,omitempty"`
//执行器名称
}
vendor/github.com/33cn/chain33/system/consensus/base.go
View file @
47bbff03
...
@@ -337,6 +337,10 @@ func buildHashList(deltx []*types.Transaction) *types.TxHashList {
...
@@ -337,6 +337,10 @@ func buildHashList(deltx []*types.Transaction) *types.TxHashList {
//WriteBlock 向blockchain写区块
//WriteBlock 向blockchain写区块
func
(
bc
*
BaseClient
)
WriteBlock
(
prev
[]
byte
,
block
*
types
.
Block
)
error
{
func
(
bc
*
BaseClient
)
WriteBlock
(
prev
[]
byte
,
block
*
types
.
Block
)
error
{
//保存block的原始信息用于删除mempool中的错误交易
rawtxs
:=
make
([]
*
types
.
Transaction
,
len
(
block
.
Txs
))
copy
(
rawtxs
,
block
.
Txs
)
blockdetail
:=
&
types
.
BlockDetail
{
Block
:
block
}
blockdetail
:=
&
types
.
BlockDetail
{
Block
:
block
}
msg
:=
bc
.
client
.
NewMessage
(
"blockchain"
,
types
.
EventAddBlockDetail
,
blockdetail
)
msg
:=
bc
.
client
.
NewMessage
(
"blockchain"
,
types
.
EventAddBlockDetail
,
blockdetail
)
bc
.
client
.
Send
(
msg
,
true
)
bc
.
client
.
Send
(
msg
,
true
)
...
@@ -346,7 +350,7 @@ func (bc *BaseClient) WriteBlock(prev []byte, block *types.Block) error {
...
@@ -346,7 +350,7 @@ func (bc *BaseClient) WriteBlock(prev []byte, block *types.Block) error {
}
}
blockdetail
=
resp
.
GetData
()
.
(
*
types
.
BlockDetail
)
blockdetail
=
resp
.
GetData
()
.
(
*
types
.
BlockDetail
)
//从mempool 中删除错误的交易
//从mempool 中删除错误的交易
deltx
:=
diffTx
(
block
.
T
xs
,
blockdetail
.
Block
.
Txs
)
deltx
:=
diffTx
(
rawt
xs
,
blockdetail
.
Block
.
Txs
)
if
len
(
deltx
)
>
0
{
if
len
(
deltx
)
>
0
{
bc
.
delMempoolTx
(
deltx
)
bc
.
delMempoolTx
(
deltx
)
}
}
...
...
vendor/github.com/33cn/chain33/types/cfg.go
View file @
47bbff03
...
@@ -64,18 +64,19 @@ type Mempool struct {
...
@@ -64,18 +64,19 @@ type Mempool struct {
// Consensus 配置
// Consensus 配置
type
Consensus
struct
{
type
Consensus
struct
{
Name
string
`protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Name
string
`protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
GenesisBlockTime
int64
`protobuf:"varint,2,opt,name=genesisBlockTime" json:"genesisBlockTime,omitempty"`
GenesisBlockTime
int64
`protobuf:"varint,2,opt,name=genesisBlockTime" json:"genesisBlockTime,omitempty"`
Minerstart
bool
`protobuf:"varint,3,opt,name=minerstart" json:"minerstart,omitempty"`
Minerstart
bool
`protobuf:"varint,3,opt,name=minerstart" json:"minerstart,omitempty"`
Genesis
string
`protobuf:"bytes,4,opt,name=genesis" json:"genesis,omitempty"`
Genesis
string
`protobuf:"bytes,4,opt,name=genesis" json:"genesis,omitempty"`
HotkeyAddr
string
`protobuf:"bytes,5,opt,name=hotkeyAddr" json:"hotkeyAddr,omitempty"`
HotkeyAddr
string
`protobuf:"bytes,5,opt,name=hotkeyAddr" json:"hotkeyAddr,omitempty"`
ForceMining
bool
`protobuf:"varint,6,opt,name=forceMining" json:"forceMining,omitempty"`
ForceMining
bool
`protobuf:"varint,6,opt,name=forceMining" json:"forceMining,omitempty"`
WriteBlockSeconds
int64
`protobuf:"varint,20,opt,name=writeBlockSeconds" json:"writeBlockSeconds,omitempty"`
WriteBlockSeconds
int64
`protobuf:"varint,20,opt,name=writeBlockSeconds" json:"writeBlockSeconds,omitempty"`
ParaRemoteGrpcClient
string
`protobuf:"bytes,22,opt,name=paraRemoteGrpcClient" json:"paraRemoteGrpcClient,omitempty"`
ParaRemoteGrpcClient
string
`protobuf:"bytes,22,opt,name=paraRemoteGrpcClient" json:"paraRemoteGrpcClient,omitempty"`
StartHeight
int64
`protobuf:"varint,23,opt,name=startHeight" json:"startHeight,omitempty"`
StartHeight
int64
`protobuf:"varint,23,opt,name=startHeight" json:"startHeight,omitempty"`
EmptyBlockInterval
int64
`protobuf:"varint,24,opt,name=emptyBlockInterval" json:"emptyBlockInterval,omitempty"`
EmptyBlockInterval
int64
`protobuf:"varint,24,opt,name=emptyBlockInterval" json:"emptyBlockInterval,omitempty"`
AuthAccount
string
`protobuf:"bytes,25,opt,name=authAccount" json:"authAccount,omitempty"`
AuthAccount
string
`protobuf:"bytes,25,opt,name=authAccount" json:"authAccount,omitempty"`
WaitBlocks4CommitMsg
int32
`protobuf:"varint,26,opt,name=waitBlocks4CommitMsg" json:"waitBlocks4CommitMsg,omitempty"`
WaitBlocks4CommitMsg
int32
`protobuf:"varint,26,opt,name=waitBlocks4CommitMsg" json:"waitBlocks4CommitMsg,omitempty"`
SearchHashMatchedBlockDepth
int32
`protobuf:"varint,27,opt,name=searchHashMatchedBlockDepth" json:"searchHashMatchedBlockDepth,omitempty"`
}
}
// Wallet 配置
// Wallet 配置
...
...
vendor/github.com/33cn/chain33/types/config.go
View file @
47bbff03
...
@@ -225,6 +225,13 @@ func S(key string, value interface{}) {
...
@@ -225,6 +225,13 @@ func S(key string, value interface{}) {
setChainConfig
(
key
,
value
)
setChainConfig
(
key
,
value
)
}
}
//SetTitleOnlyForTest set title only for test use
func
SetTitleOnlyForTest
(
ti
string
)
{
mu
.
Lock
()
defer
mu
.
Unlock
()
title
=
ti
}
// Init 初始化
// Init 初始化
func
Init
(
t
string
,
cfg
*
Config
)
{
func
Init
(
t
string
,
cfg
*
Config
)
{
mu
.
Lock
()
mu
.
Lock
()
...
@@ -303,7 +310,6 @@ func SetMinFee(fee int64) {
...
@@ -303,7 +310,6 @@ func SetMinFee(fee int64) {
}
}
func
isPara
()
bool
{
func
isPara
()
bool
{
//user.p.guodun.
return
strings
.
Count
(
title
,
"."
)
==
3
&&
strings
.
HasPrefix
(
title
,
ParaKeyX
)
return
strings
.
Count
(
title
,
"."
)
==
3
&&
strings
.
HasPrefix
(
title
,
ParaKeyX
)
}
}
...
...
vendor/github.com/33cn/chain33/types/const.go
View file @
47bbff03
...
@@ -9,6 +9,7 @@ import (
...
@@ -9,6 +9,7 @@ import (
)
)
var
slash
=
[]
byte
(
"-"
)
var
slash
=
[]
byte
(
"-"
)
var
sharp
=
[]
byte
(
"#"
)
//Debug 调试开关
//Debug 调试开关
var
Debug
=
false
var
Debug
=
false
...
...
vendor/github.com/33cn/chain33/types/executor.go
View file @
47bbff03
...
@@ -109,8 +109,8 @@ func CallExecNewTx(execName, action string, param interface{}) ([]byte, error) {
...
@@ -109,8 +109,8 @@ func CallExecNewTx(execName, action string, param interface{}) ([]byte, error) {
return
FormatTxEncode
(
execName
,
tx
)
return
FormatTxEncode
(
execName
,
tx
)
}
}
//
CallCreateTx 构造交易信息
//
CallCreateTransaction 创建一个交易
func
CallCreateT
x
(
execName
,
action
string
,
param
Message
)
([]
byte
,
error
)
{
func
CallCreateT
ransaction
(
execName
,
action
string
,
param
Message
)
(
*
Transaction
,
error
)
{
exec
:=
LoadExecutorType
(
execName
)
exec
:=
LoadExecutorType
(
execName
)
if
exec
==
nil
{
if
exec
==
nil
{
tlog
.
Error
(
"CallCreateTx"
,
"Error"
,
"exec not found"
)
tlog
.
Error
(
"CallCreateTx"
,
"Error"
,
"exec not found"
)
...
@@ -121,9 +121,13 @@ func CallCreateTx(execName, action string, param Message) ([]byte, error) {
...
@@ -121,9 +121,13 @@ func CallCreateTx(execName, action string, param Message) ([]byte, error) {
tlog
.
Error
(
"CallCreateTx"
,
"Error"
,
"param in nil"
)
tlog
.
Error
(
"CallCreateTx"
,
"Error"
,
"param in nil"
)
return
nil
,
ErrInvalidParam
return
nil
,
ErrInvalidParam
}
}
tx
,
err
:=
exec
.
Create
(
action
,
param
)
return
exec
.
Create
(
action
,
param
)
}
// CallCreateTx 构造交易信息
func
CallCreateTx
(
execName
,
action
string
,
param
Message
)
([]
byte
,
error
)
{
tx
,
err
:=
CallCreateTransaction
(
execName
,
action
,
param
)
if
err
!=
nil
{
if
err
!=
nil
{
tlog
.
Error
(
"CallCreateTx"
,
"Error"
,
err
)
return
nil
,
err
return
nil
,
err
}
}
return
FormatTxEncode
(
execName
,
tx
)
return
FormatTxEncode
(
execName
,
tx
)
...
...
vendor/github.com/33cn/chain33/types/executor_test.go
View file @
47bbff03
...
@@ -132,5 +132,4 @@ func TestCallCreateTx(t *testing.T) {
...
@@ -132,5 +132,4 @@ func TestCallCreateTx(t *testing.T) {
assert
.
Equal
(
t
,
tx
.
Execer
,
[]
byte
(
"manage"
))
assert
.
Equal
(
t
,
tx
.
Execer
,
[]
byte
(
"manage"
))
fee
,
_
=
tx
.
GetRealFee
(
GInt
(
"MinFee"
))
fee
,
_
=
tx
.
GetRealFee
(
GInt
(
"MinFee"
))
assert
.
Equal
(
t
,
tx
.
Fee
,
fee
)
assert
.
Equal
(
t
,
tx
.
Fee
,
fee
)
}
}
vendor/github.com/33cn/chain33/types/mocks/chain33client.go
View file @
47bbff03
...
@@ -762,6 +762,36 @@ func (_m *Chain33Client) GetSeed(ctx context.Context, in *types.GetSeedByPw, opt
...
@@ -762,6 +762,36 @@ func (_m *Chain33Client) GetSeed(ctx context.Context, in *types.GetSeedByPw, opt
return
r0
,
r1
return
r0
,
r1
}
}
// GetSequenceByHash provides a mock function with given fields: ctx, in, opts
func
(
_m
*
Chain33Client
)
GetSequenceByHash
(
ctx
context
.
Context
,
in
*
types
.
ReqHash
,
opts
...
grpc
.
CallOption
)
(
*
types
.
Int64
,
error
)
{
_va
:=
make
([]
interface
{},
len
(
opts
))
for
_i
:=
range
opts
{
_va
[
_i
]
=
opts
[
_i
]
}
var
_ca
[]
interface
{}
_ca
=
append
(
_ca
,
ctx
,
in
)
_ca
=
append
(
_ca
,
_va
...
)
ret
:=
_m
.
Called
(
_ca
...
)
var
r0
*
types
.
Int64
if
rf
,
ok
:=
ret
.
Get
(
0
)
.
(
func
(
context
.
Context
,
*
types
.
ReqHash
,
...
grpc
.
CallOption
)
*
types
.
Int64
);
ok
{
r0
=
rf
(
ctx
,
in
,
opts
...
)
}
else
{
if
ret
.
Get
(
0
)
!=
nil
{
r0
=
ret
.
Get
(
0
)
.
(
*
types
.
Int64
)
}
}
var
r1
error
if
rf
,
ok
:=
ret
.
Get
(
1
)
.
(
func
(
context
.
Context
,
*
types
.
ReqHash
,
...
grpc
.
CallOption
)
error
);
ok
{
r1
=
rf
(
ctx
,
in
,
opts
...
)
}
else
{
r1
=
ret
.
Error
(
1
)
}
return
r0
,
r1
}
// GetTransactionByAddr provides a mock function with given fields: ctx, in, opts
// GetTransactionByAddr provides a mock function with given fields: ctx, in, opts
func
(
_m
*
Chain33Client
)
GetTransactionByAddr
(
ctx
context
.
Context
,
in
*
types
.
ReqAddr
,
opts
...
grpc
.
CallOption
)
(
*
types
.
ReplyTxInfos
,
error
)
{
func
(
_m
*
Chain33Client
)
GetTransactionByAddr
(
ctx
context
.
Context
,
in
*
types
.
ReqAddr
,
opts
...
grpc
.
CallOption
)
(
*
types
.
ReplyTxInfos
,
error
)
{
_va
:=
make
([]
interface
{},
len
(
opts
))
_va
:=
make
([]
interface
{},
len
(
opts
))
...
...
vendor/github.com/33cn/chain33/types/proto/rpc.proto
View file @
47bbff03
...
@@ -125,6 +125,9 @@ service chain33 {
...
@@ -125,6 +125,9 @@ service chain33 {
//获取指定区间的block加载序列号信息
//获取指定区间的block加载序列号信息
rpc
GetBlockSequences
(
ReqBlocks
)
returns
(
BlockSequences
)
{}
rpc
GetBlockSequences
(
ReqBlocks
)
returns
(
BlockSequences
)
{}
//get add block's sequence by hash
rpc
GetSequenceByHash
(
ReqHash
)
returns
(
Int64
)
{}
//通过block hash 获取对应的blocks信息
//通过block hash 获取对应的blocks信息
rpc
GetBlockByHashes
(
ReqHashes
)
returns
(
BlockDetails
)
{}
rpc
GetBlockByHashes
(
ReqHashes
)
returns
(
BlockDetails
)
{}
//关闭chain33
//关闭chain33
...
...
vendor/github.com/33cn/chain33/types/proto/transaction.proto
View file @
47bbff03
...
@@ -49,6 +49,7 @@ message CreateTx {
...
@@ -49,6 +49,7 @@ message CreateTx {
bool
isToken
=
6
;
bool
isToken
=
6
;
string
tokenSymbol
=
7
;
string
tokenSymbol
=
7
;
string
execName
=
8
;
string
execName
=
8
;
string
execer
=
9
;
}
}
message
CreateTransactionGroup
{
message
CreateTransactionGroup
{
...
...
vendor/github.com/33cn/chain33/types/rpc.pb.go
View file @
47bbff03
This diff is collapsed.
Click to expand it.
vendor/github.com/33cn/chain33/types/transaction.pb.go
View file @
47bbff03
This diff is collapsed.
Click to expand it.
vendor/github.com/33cn/chain33/types/types.go
View file @
47bbff03
...
@@ -41,6 +41,9 @@ type TxGroup interface {
...
@@ -41,6 +41,9 @@ type TxGroup interface {
//ExecName 执行器name
//ExecName 执行器name
func
ExecName
(
name
string
)
string
{
func
ExecName
(
name
string
)
string
{
if
len
(
name
)
>
1
&&
name
[
0
]
==
'#'
{
return
name
[
1
:
]
}
if
IsParaExecName
(
name
)
{
if
IsParaExecName
(
name
)
{
return
name
return
name
}
}
...
@@ -61,7 +64,7 @@ func IsAllowExecName(name []byte, execer []byte) bool {
...
@@ -61,7 +64,7 @@ func IsAllowExecName(name []byte, execer []byte) bool {
return
false
return
false
}
}
// name中不允许有 "-"
// name中不允许有 "-"
if
bytes
.
Contains
(
name
,
slash
)
{
if
bytes
.
Contains
(
name
,
slash
)
||
bytes
.
Contains
(
name
,
sharp
)
{
return
false
return
false
}
}
if
!
bytes
.
Equal
(
name
,
execer
)
&&
!
bytes
.
Equal
(
name
,
GetRealExecName
(
execer
))
{
if
!
bytes
.
Equal
(
name
,
execer
)
&&
!
bytes
.
Equal
(
name
,
GetRealExecName
(
execer
))
{
...
...
vendor/github.com/33cn/chain33/types/types_real_test.go
View file @
47bbff03
...
@@ -5,5 +5,48 @@
...
@@ -5,5 +5,48 @@
package
types_test
package
types_test
import
(
import
(
"testing"
"github.com/33cn/chain33/common/address"
_
"github.com/33cn/chain33/system"
_
"github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
"github.com/stretchr/testify/assert"
)
)
//how to create transafer for para
func
TestCallCreateTxPara
(
t
*
testing
.
T
)
{
ti
:=
types
.
GetTitle
()
defer
types
.
SetTitleOnlyForTest
(
ti
)
types
.
SetTitleOnlyForTest
(
"user.p.sto."
)
req
:=
&
types
.
CreateTx
{
To
:
"184wj4nsgVxKyz2NhM3Yb5RK5Ap6AFRFq2"
,
Amount
:
10
,
Fee
:
1
,
Note
:
[]
byte
(
"12312"
),
IsWithdraw
:
false
,
IsToken
:
false
,
TokenSymbol
:
""
,
ExecName
:
types
.
ExecName
(
"coins"
),
}
assert
.
True
(
t
,
types
.
IsPara
())
tx
,
err
:=
types
.
CallCreateTransaction
(
"coins"
,
""
,
req
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
"coins"
,
tx
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
"coins"
,
string
(
tx
.
Execer
))
assert
.
Equal
(
t
,
address
.
ExecAddress
(
"coins"
),
tx
.
To
)
tx
,
err
=
types
.
FormatTx
(
types
.
ExecName
(
"coins"
),
tx
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
"user.p.sto.coins"
,
string
(
tx
.
Execer
))
assert
.
Equal
(
t
,
address
.
ExecAddress
(
"user.p.sto.coins"
),
tx
.
To
)
}
func
TestExecName
(
t
*
testing
.
T
)
{
assert
.
Equal
(
t
,
types
.
ExecName
(
"coins"
),
"coins"
)
ti
:=
types
.
GetTitle
()
defer
types
.
SetTitleOnlyForTest
(
ti
)
types
.
SetTitleOnlyForTest
(
"user.p.sto."
)
assert
.
Equal
(
t
,
types
.
ExecName
(
"coins"
),
"user.p.sto.coins"
)
//#在exec前面加一个 # 表示不重写执行器
assert
.
Equal
(
t
,
types
.
ExecName
(
"#coins"
),
"coins"
)
}
vendor/github.com/33cn/chain33/types/types_test.go
View file @
47bbff03
...
@@ -46,6 +46,12 @@ func TestAllowExecName(t *testing.T) {
...
@@ -46,6 +46,12 @@ func TestAllowExecName(t *testing.T) {
isok
=
IsAllowExecName
([]
byte
(
"coins"
),
[]
byte
(
"user.p.guodun.user.coins"
))
isok
=
IsAllowExecName
([]
byte
(
"coins"
),
[]
byte
(
"user.p.guodun.user.coins"
))
assert
.
Equal
(
t
,
isok
,
true
)
assert
.
Equal
(
t
,
isok
,
true
)
isok
=
IsAllowExecName
([]
byte
(
"#coins"
),
[]
byte
(
"user.p.guodun.user.coins"
))
assert
.
Equal
(
t
,
isok
,
false
)
isok
=
IsAllowExecName
([]
byte
(
"coins-"
),
[]
byte
(
"user.p.guodun.user.coins"
))
assert
.
Equal
(
t
,
isok
,
false
)
}
}
func
BenchmarkExecName
(
b
*
testing
.
B
)
{
func
BenchmarkExecName
(
b
*
testing
.
B
)
{
...
...
vendor/github.com/33cn/chain33/util/testnode/testnode.go
View file @
47bbff03
...
@@ -329,6 +329,14 @@ func (mock *Chain33Mock) GetAccount(stateHash []byte, addr string) *types.Accoun
...
@@ -329,6 +329,14 @@ func (mock *Chain33Mock) GetAccount(stateHash []byte, addr string) *types.Accoun
return
acc
.
LoadAccount
(
addr
)
return
acc
.
LoadAccount
(
addr
)
}
}
//GetExecAccount :get execer account info
func
(
mock
*
Chain33Mock
)
GetExecAccount
(
stateHash
[]
byte
,
execer
,
addr
string
)
*
types
.
Account
{
statedb
:=
executor
.
NewStateDB
(
mock
.
client
,
stateHash
,
nil
,
nil
)
acc
:=
account
.
NewCoinsAccount
()
acc
.
SetDB
(
statedb
)
return
acc
.
LoadExecAccount
(
addr
,
address
.
ExecAddress
(
execer
))
}
//GetBlock :
//GetBlock :
func
(
mock
*
Chain33Mock
)
GetBlock
(
height
int64
)
*
types
.
Block
{
func
(
mock
*
Chain33Mock
)
GetBlock
(
height
int64
)
*
types
.
Block
{
blocks
,
err
:=
mock
.
api
.
GetBlocks
(
&
types
.
ReqBlocks
{
Start
:
height
,
End
:
height
})
blocks
,
err
:=
mock
.
api
.
GetBlocks
(
&
types
.
ReqBlocks
{
Start
:
height
,
End
:
height
})
...
...
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