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
b7699804
Commit
b7699804
authored
Mar 15, 2019
by
lyn
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master'
parents
944b3e92
a4973c06
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
2339 additions
and
126 deletions
+2339
-126
Makefile
plugin/dapp/js/cmd/Makefile
+0
-4
build.sh
plugin/dapp/js/cmd/build.sh
+0
-11
js.go
plugin/dapp/js/command/js.go
+1
-1
plugin.go
plugin/dapp/js/plugin.go
+2
-2
lottery.go
plugin/dapp/lottery/executor/lottery.go
+21
-14
action.go
plugin/dapp/multisig/executor/action.go
+1
-1
asset-transfer.md
plugin/dapp/paracross/executor/asset-transfer.md
+0
-2
privacy_test.go
plugin/dapp/privacy/crypto/privacy_test.go
+8
-2
build.sh
plugin/dapp/relay/cmd/build.sh
+12
-11
testcase.sh
plugin/dapp/relay/cmd/build/testcase.sh
+1
-0
token.go
plugin/dapp/token/autotest/token.go
+2
-0
token.toml
plugin/dapp/token/autotest/token.toml
+14
-1
tokenCase.go
plugin/dapp/token/autotest/tokenCase.go
+108
-0
token.go
plugin/dapp/token/commands/token.go
+118
-0
exec.go
plugin/dapp/token/executor/exec.go
+10
-0
exec_del_local.go
plugin/dapp/token/executor/exec_del_local.go
+64
-0
exec_local.go
plugin/dapp/token/executor/exec_local.go
+86
-0
logs.go
plugin/dapp/token/executor/logs.go
+100
-0
query.go
plugin/dapp/token/executor/query.go
+22
-0
token_new_test.go
plugin/dapp/token/executor/token_new_test.go
+73
-0
token_test.go
plugin/dapp/token/executor/token_test.go
+243
-0
tokendb.go
plugin/dapp/token/executor/tokendb.go
+130
-1
transwithdraw.go
plugin/dapp/token/executor/transwithdraw.go
+4
-1
token.proto
plugin/dapp/token/proto/token.proto
+28
-0
rpc.go
plugin/dapp/token/rpc/rpc.go
+26
-0
const.go
plugin/dapp/token/types/const.go
+13
-0
token.pb.go
plugin/dapp/token/types/token.pb.go
+0
-0
types.go
plugin/dapp/token/types/types.go
+4
-0
init.go
plugin/store/init/init.go
+4
-3
kvmvcc_mavl.go
plugin/store/kvmvccmavl/kvmvcc_mavl.go
+315
-0
kvmvcc_mavl_test.go
plugin/store/kvmvccmavl/kvmvcc_mavl_test.go
+0
-0
kvmvccdb.go
plugin/store/kvmvccmavl/kvmvccdb.go
+0
-0
mavl.go
plugin/store/kvmvccmavl/mavl.go
+160
-0
.travis.yml
vendor/github.com/33cn/chain33/.travis.yml
+1
-1
account.go
vendor/github.com/33cn/chain33/account/account.go
+37
-0
account_test.go
vendor/github.com/33cn/chain33/account/account_test.go
+10
-0
bityuan.toml
vendor/github.com/33cn/chain33/cmd/chain33/bityuan.toml
+4
-0
chain33.test.toml
vendor/github.com/33cn/chain33/cmd/chain33/chain33.test.toml
+4
-0
chain33.toml
vendor/github.com/33cn/chain33/cmd/chain33/chain33.toml
+4
-0
execenv.go
vendor/github.com/33cn/chain33/executor/execenv.go
+14
-1
executor_real_test.go
...or/github.com/33cn/chain33/executor/executor_real_test.go
+9
-3
executor_test.go
vendor/github.com/33cn/chain33/executor/executor_test.go
+2
-0
localdb.go
vendor/github.com/33cn/chain33/executor/localdb.go
+40
-9
localdb_test.go
vendor/github.com/33cn/chain33/executor/localdb_test.go
+28
-0
types.go
...github.com/33cn/chain33/system/dapp/manage/types/types.go
+1
-1
memmavl.go
...r/github.com/33cn/chain33/system/store/mavl/db/memmavl.go
+204
-0
node.go
vendor/github.com/33cn/chain33/system/store/mavl/db/node.go
+4
-0
tree.go
vendor/github.com/33cn/chain33/system/store/mavl/db/tree.go
+144
-4
tree_test.go
...github.com/33cn/chain33/system/store/mavl/db/tree_test.go
+146
-0
mavl.go
vendor/github.com/33cn/chain33/system/store/mavl/mavl.go
+12
-1
account.pb.go
vendor/github.com/33cn/chain33/types/account.pb.go
+82
-33
const.go
vendor/github.com/33cn/chain33/types/const.go
+3
-0
error.go
vendor/github.com/33cn/chain33/types/error.go
+3
-0
account.proto
vendor/github.com/33cn/chain33/types/proto/account.proto
+5
-0
exec.go
vendor/github.com/33cn/chain33/util/exec.go
+8
-16
util.go
vendor/github.com/33cn/chain33/util/util.go
+2
-2
util_test.go
vendor/github.com/33cn/chain33/util/util_test.go
+2
-1
No files found.
plugin/dapp/js/cmd/Makefile
deleted
100644 → 0
View file @
944b3e92
all
:
chmod
+x ./build.sh
./build.sh
$(OUT)
$(FLAG)
\ No newline at end of file
plugin/dapp/js/cmd/build.sh
deleted
100755 → 0
View file @
944b3e92
#!/bin/sh
strpwd
=
$(
pwd
)
strcmd
=
${
strpwd
##*dapp/
}
strapp
=
${
strcmd
%/cmd*
}
OUT_DIR
=
"
${
1
}
/
$strapp
"
#FLAG=$2
mkdir
-p
"
${
OUT_DIR
}
"
cp
./build/
*
"
${
OUT_DIR
}
"
plugin/dapp/js/c
m
d/js.go
→
plugin/dapp/js/c
omman
d/js.go
View file @
b7699804
...
...
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
c
m
d
package
c
omman
d
import
(
"fmt"
...
...
plugin/dapp/js/plugin.go
View file @
b7699804
...
...
@@ -2,12 +2,12 @@ package js
import
(
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/js/cmd"
"github.com/33cn/plugin/plugin/dapp/js/executor"
ptypes
"github.com/33cn/plugin/plugin/dapp/js/types"
// init auto test
_
"github.com/33cn/plugin/plugin/dapp/js/autotest"
"github.com/33cn/plugin/plugin/dapp/js/command"
)
func
init
()
{
...
...
@@ -15,7 +15,7 @@ func init() {
Name
:
ptypes
.
JsX
,
ExecName
:
executor
.
GetName
(),
Exec
:
executor
.
Init
,
Cmd
:
c
m
d
.
JavaScriptCmd
,
Cmd
:
c
omman
d
.
JavaScriptCmd
,
RPC
:
nil
,
})
}
plugin/dapp/lottery/executor/lottery.go
View file @
b7699804
...
...
@@ -5,6 +5,7 @@
package
executor
import
(
"fmt"
"sort"
log
"github.com/33cn/chain33/common/log/log15"
...
...
@@ -61,25 +62,31 @@ func (lott *Lottery) GetDriverName() string {
return
pty
.
LotteryX
}
func
(
lott
*
Lottery
)
findLotteryBuyRecords
(
key
[]
byte
)
(
*
pty
.
LotteryBuyRecords
,
error
)
{
count
:=
lott
.
GetLocalDB
()
.
PrefixCount
(
key
)
llog
.
Error
(
"findLotteryBuyRecords"
,
"count"
,
count
)
values
,
err
:=
lott
.
GetLocalDB
()
.
List
(
key
,
nil
,
int32
(
count
),
0
)
if
err
!=
nil
{
return
nil
,
err
}
func
(
lott
*
Lottery
)
findLotteryBuyRecords
(
prefix
[]
byte
)
(
*
pty
.
LotteryBuyRecords
,
error
)
{
count
:=
0
var
key
[]
byte
var
records
pty
.
LotteryBuyRecords
for
_
,
value
:=
range
values
{
var
record
pty
.
LotteryBuyRecord
err
:=
types
.
Decode
(
value
,
&
record
)
for
{
values
,
err
:=
lott
.
GetLocalDB
()
.
List
(
prefix
,
key
,
DefultCount
,
0
)
if
err
!=
nil
{
continue
return
nil
,
err
}
for
_
,
value
:=
range
values
{
var
record
pty
.
LotteryBuyRecord
err
:=
types
.
Decode
(
value
,
&
record
)
if
err
!=
nil
{
continue
}
records
.
Records
=
append
(
records
.
Records
,
&
record
)
}
count
+=
len
(
values
)
if
len
(
values
)
<
int
(
DefultCount
)
{
break
}
records
.
Records
=
append
(
records
.
Records
,
&
record
)
key
=
[]
byte
(
fmt
.
Sprintf
(
"%s:%18d"
,
prefix
,
records
.
Records
[
count
-
1
]
.
Index
)
)
}
llog
.
Info
(
"findLotteryBuyRecords"
,
"count"
,
count
)
return
&
records
,
nil
}
...
...
plugin/dapp/multisig/executor/action.go
View file @
b7699804
...
...
@@ -94,7 +94,7 @@ func (a *action) MultiSigAccCreate(accountCreate *mty.MultiSigAccCreate) (*types
//通过创建交易的txhash生成一个唯一的多重签名合约 NewAddrFromString
addr
:=
address
.
MultiSignAddress
(
a
.
txhash
)
//账户去重校验
multiSig
,
err
:=
getMultiSigAcc
ount
(
a
.
local
db
,
addr
)
multiSig
,
err
:=
getMultiSigAcc
FromDb
(
a
.
db
,
addr
)
if
err
==
nil
&&
multiSig
!=
nil
{
return
nil
,
mty
.
ErrAccountHasExist
}
...
...
plugin/dapp/paracross/executor/asset-transfer.md
View file @
b7699804
...
...
@@ -36,13 +36,11 @@ asset-transfer 分两种, 主链转出, 主链转入
1.
用户主链paracross合约帐号, balance -
1.
某平行链paracross合约帐号, balance +
*
平行链(如果上面步骤失败,, 平行链会过滤掉这个交易)
1.
平行链中paracross合约帐号 balance +
1.
平行链中 用户paracross合约帐号 balance +
主链转入 withdraw
*
平行链
1.
平行链中 用户paracross合约帐号 balance -
1.
平行链中paracross合约帐号 balance -
*
主链(上面步骤失败, 不进行操作)
1.
commit 交易共识时执行
1.
某平行链paracross合约帐号, balance -
...
...
plugin/dapp/privacy/crypto/privacy_test.go
View file @
b7699804
...
...
@@ -51,11 +51,17 @@ func (*signatureMock) Equals(crypto.Signature) bool {
return
true
}
func
formatByte32
(
b
[]
byte
)
[]
byte
{
var
b32
[
32
]
byte
copy
(
b32
[
:
],
b
)
return
b32
[
:
]
}
type
privKeyMock
struct
{
}
func
(
mock
*
privKeyMock
)
Bytes
()
[]
byte
{
return
[]
byte
(
"1234"
)
return
formatByte32
([]
byte
(
"1234"
)
)
}
func
(
mock
*
privKeyMock
)
Sign
(
msg
[]
byte
)
crypto
.
Signature
{
...
...
@@ -82,7 +88,7 @@ func TestNewPrivacy(t *testing.T) {
}
func
test_RecoverOnetimePriKey
(
t
*
testing
.
T
)
{
R
:=
[]
byte
(
"1234"
)
R
:=
formatByte32
([]
byte
(
"1234"
)
)
pkm
:=
privKeyMock
{}
privKey
,
err
:=
RecoverOnetimePriKey
(
R
,
&
pkm
,
&
pkm
,
0
)
assert
.
Nil
(
t
,
err
)
...
...
plugin/dapp/relay/cmd/build.sh
View file @
b7699804
#!/usr/bin/env bash
strpwd
=
$(
pwd
)
strcmd
=
${
strpwd
##*dapp/
}
strapp
=
${
strcmd
%/cmd*
}
#strpwd=$(pwd)
#strcmd=${strpwd##*dapp/}
#strapp=${strcmd%/cmd*}
#
#OUT_DIR="${1}/$strapp"
#SRC_RELAYD=github.com/33cn/plugin/plugin/dapp/relay/cmd/relayd
#FLAG=$2
OUT_DIR
=
"
${
1
}
/
$strapp
"
SRC_RELAYD
=
github.com/33cn/plugin/plugin/dapp/relay/cmd/relayd
FLAG
=
$2
# shellcheck disable=SC2086
go build
-i
${
FLAG
}
-v
-o
"
${
OUT_DIR
}
/relayd"
"
${
SRC_RELAYD
}
"
cp
./relayd/relayd.toml
"
${
OUT_DIR
}
/relayd.toml"
cp
./build/
*
"
${
OUT_DIR
}
"
# shellcheck disable=SC2086,1072
#go build -i ${FLAG} -v -o "${OUT_DIR}/relayd" "${SRC_RELAYD}"
#cp ./relayd/relayd.toml "${OUT_DIR}/relayd.toml"
#cp ./build/* "${OUT_DIR}"
echo
"ignore"
plugin/dapp/relay/cmd/build/testcase.sh
View file @
b7699804
...
...
@@ -170,6 +170,7 @@ function relay_test() {
coinaddr
=
$(${
1
}
tx query
-s
"
${
buy_hash
}
"
| jq
-r
".receipt.logs[2].log.coinAddr"
)
if
[
"
${
coinaddr
}
"
!=
"1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT"
]
;
then
${
1
}
tx query
-s
"
${
buy_hash
}
"
echo
"wrong create order to coinaddr"
exit
1
fi
...
...
plugin/dapp/token/autotest/token.go
View file @
b7699804
...
...
@@ -18,6 +18,8 @@ type tokenAutoTest struct {
TransferCaseArr
[]
autotest
.
TransferCase
`toml:"TransferCase,omitempty"`
WithdrawCaseArr
[]
autotest
.
WithdrawCase
`toml:"WithdrawCase,omitempty"`
TokenRevokeCaseArr
[]
TokenRevokeCase
`toml:"TokenRevokeCase,omitempty"`
TokenMintCaseArr
[]
TokenMintCase
`toml:"TokenMintCase,omitempty"`
TokenBurnCaseArr
[]
TokenBurnCase
`toml:"TokenBurnCase,omitempty"`
}
func
init
()
{
...
...
plugin/dapp/token/autotest/token.toml
View file @
b7699804
...
...
@@ -7,7 +7,7 @@ command = "account import_key -k 0xc21d38be90493512a5c2417d565269a8b23ce8152010e
[[TokenPreCreateCase]]
id
=
"tokenPre"
command
=
"send token precreate -f 0.01 -i testToken -n testToken -s TC -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t 100000 -p 1 -k 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
command
=
"send token precreate -
c 1 -
f 0.01 -i testToken -n testToken -s TC -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t 100000 -p 1 -k 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
dep
=
[
"transForPrecreate"
,
"import1"
]
[[TokenPreCreateCase]]
...
...
@@ -21,6 +21,19 @@ id = "tokenFinish"
command
=
"send token finish -a 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -f 0.01 -s TC -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc"
dep
=
["tokenPre"]
[[TokenMintCase]]
id
=
"tokenMint"
command
=
"send token mint -a 100 -s TC -k 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
dep
=
["tokenFinish"]
amount
=
"100"
checkItem
=
["balance"]
[[TokenBurnCase]]
id
=
"tokenBurn"
command
=
"send token burn -a 50 -s TC -k 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
dep
=
["tokenMint"]
amount
=
"50"
checkItem
=
["balance"]
#send to token for precreate
[[TransferCase]]
...
...
plugin/dapp/token/autotest/tokenCase.go
View file @
b7699804
...
...
@@ -6,6 +6,8 @@ package autotest
import
(
"github.com/33cn/chain33/cmd/autotest/types"
"strconv"
)
// TokenPreCreateCase token precreatecase command
...
...
@@ -59,3 +61,109 @@ func (testCase *TokenFinishCreateCase) SendCommand(packID string) (types.PackFun
return
types
.
DefaultSend
(
testCase
,
&
TokenFinishCreatePack
{},
packID
)
}
// TokenMintCase token mint case
type
TokenMintCase
struct
{
types
.
BaseCase
Amount
string
`toml:"amount"`
}
// TokenMintPack token mint pack command
type
TokenMintPack
struct
{
types
.
BaseCasePack
}
// SendCommand send command function of tokenfinishcreatecase
func
(
testCase
*
TokenMintCase
)
SendCommand
(
packID
string
)
(
types
.
PackFunc
,
error
)
{
return
types
.
DefaultSend
(
testCase
,
&
TokenMintPack
{},
packID
)
}
// GetCheckHandlerMap get check handle for map
func
(
pack
*
TokenMintPack
)
GetCheckHandlerMap
()
interface
{}
{
funcMap
:=
make
(
types
.
CheckHandlerMapDiscard
,
2
)
funcMap
[
"balance"
]
=
pack
.
checkBalance
return
funcMap
}
func
(
pack
*
TokenMintPack
)
checkBalance
(
txInfo
map
[
string
]
interface
{})
bool
{
logArr
:=
txInfo
[
"receipt"
]
.
(
map
[
string
]
interface
{})[
"logs"
]
.
([]
interface
{})
logTokenBurn
:=
logArr
[
1
]
.
(
map
[
string
]
interface
{})[
"log"
]
.
(
map
[
string
]
interface
{})
logAccBurn
:=
logArr
[
2
]
.
(
map
[
string
]
interface
{})[
"log"
]
.
(
map
[
string
]
interface
{})
interCase
:=
pack
.
TCase
.
(
*
TokenMintCase
)
amount1
,
_
:=
strconv
.
ParseInt
(
interCase
.
Amount
,
10
,
64
)
amount
:=
amount1
*
1e8
pack
.
FLog
.
Info
(
"MintDetails"
,
"TestID"
,
pack
.
PackID
,
"TokenPrev"
,
logTokenBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"total"
]
.
(
string
),
"TokenCurr"
,
logTokenBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"total"
]
.
(
string
),
"AccPrev"
,
logAccBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"balance"
]
.
(
string
),
"AccCurr"
,
logAccBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"balance"
]
.
(
string
),
"amount"
,
amount1
)
totalCurrent
:=
parseInt64
(
logTokenBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"total"
])
totalPrev
:=
parseInt64
(
logTokenBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"total"
])
accCurrent
:=
parseInt64
(
logAccBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"balance"
])
accPrev
:=
parseInt64
(
logAccBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"balance"
])
return
totalCurrent
-
amount
==
totalPrev
&&
accCurrent
-
amount
==
accPrev
}
// TokenBurnCase token mint case
type
TokenBurnCase
struct
{
types
.
BaseCase
Amount
string
`toml:"amount"`
}
// TokenBurnPack token mint pack command
type
TokenBurnPack
struct
{
types
.
BaseCasePack
}
// SendCommand send command function
func
(
testCase
*
TokenBurnCase
)
SendCommand
(
packID
string
)
(
types
.
PackFunc
,
error
)
{
return
types
.
DefaultSend
(
testCase
,
&
TokenBurnPack
{},
packID
)
}
// GetCheckHandlerMap get check handle for map
func
(
pack
*
TokenBurnPack
)
GetCheckHandlerMap
()
interface
{}
{
funcMap
:=
make
(
types
.
CheckHandlerMapDiscard
,
2
)
funcMap
[
"balance"
]
=
pack
.
checkBalance
return
funcMap
}
func
(
pack
*
TokenBurnPack
)
checkBalance
(
txInfo
map
[
string
]
interface
{})
bool
{
logArr
:=
txInfo
[
"receipt"
]
.
(
map
[
string
]
interface
{})[
"logs"
]
.
([]
interface
{})
logTokenBurn
:=
logArr
[
1
]
.
(
map
[
string
]
interface
{})[
"log"
]
.
(
map
[
string
]
interface
{})
logAccBurn
:=
logArr
[
2
]
.
(
map
[
string
]
interface
{})[
"log"
]
.
(
map
[
string
]
interface
{})
interCase
:=
pack
.
TCase
.
(
*
TokenBurnCase
)
amount1
,
_
:=
strconv
.
ParseInt
(
interCase
.
Amount
,
10
,
64
)
amount
:=
amount1
*
1e8
pack
.
FLog
.
Info
(
"BurnDetails"
,
"TestID"
,
pack
.
PackID
,
"TokenPrev"
,
logTokenBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"total"
]
.
(
string
),
"TokenCurr"
,
logTokenBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"total"
]
.
(
string
),
"AccPrev"
,
logAccBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"balance"
]
.
(
string
),
"AccCurr"
,
logAccBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"balance"
]
.
(
string
),
"amount"
,
amount1
)
totalCurrent
:=
parseInt64
(
logTokenBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"total"
])
totalPrev
:=
parseInt64
(
logTokenBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"total"
])
accCurrent
:=
parseInt64
(
logAccBurn
[
"current"
]
.
(
map
[
string
]
interface
{})[
"balance"
])
accPrev
:=
parseInt64
(
logAccBurn
[
"prev"
]
.
(
map
[
string
]
interface
{})[
"balance"
])
return
totalCurrent
+
amount
==
totalPrev
&&
accCurrent
+
amount
==
accPrev
}
func
parseInt64
(
s
interface
{})
int64
{
i
,
_
:=
strconv
.
ParseInt
(
s
.
(
string
),
10
,
64
)
return
i
}
plugin/dapp/token/commands/token.go
View file @
b7699804
...
...
@@ -42,6 +42,9 @@ func TokenCmd() *cobra.Command {
CreateRawTokenFinishTxCmd
(),
CreateRawTokenRevokeTxCmd
(),
CreateTokenTransferExecCmd
(),
CreateRawTokenMintTxCmd
(),
CreateRawTokenBurnTxCmd
(),
GetTokenLogsCmd
(),
)
return
cmd
...
...
@@ -465,3 +468,118 @@ func tokenRevoke(cmd *cobra.Command, args []string) {
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"token.CreateRawTokenRevokeTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
// CreateRawTokenMintTxCmd create raw token mintage transaction
func
CreateRawTokenMintTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"mint"
,
Short
:
"Create a mint token transaction"
,
Run
:
tokenMint
,
}
addTokenMintFlags
(
cmd
)
return
cmd
}
func
addTokenMintFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
""
,
"token symbol"
)
cmd
.
MarkFlagRequired
(
"symbol"
)
cmd
.
Flags
()
.
Float64P
(
"amount"
,
"a"
,
0
,
"amount of mintage"
)
cmd
.
MarkFlagRequired
(
"amount"
)
cmd
.
Flags
()
.
Float64P
(
"fee"
,
"f"
,
0
,
"token transaction fee"
)
}
func
tokenMint
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
amount
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"amount"
)
params
:=
&
tokenty
.
TokenMint
{
Symbol
:
symbol
,
Amount
:
int64
((
amount
+
0.000001
)
*
1e4
)
*
1e4
,
}
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"token.CreateRawTokenMintTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
// CreateRawTokenBurnTxCmd create raw token burn transaction
func
CreateRawTokenBurnTxCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"burn"
,
Short
:
"Create a burn token transaction"
,
Run
:
tokenBurn
,
}
addTokenBurnFlags
(
cmd
)
return
cmd
}
func
addTokenBurnFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
""
,
"token symbol"
)
cmd
.
MarkFlagRequired
(
"symbol"
)
cmd
.
Flags
()
.
Float64P
(
"amount"
,
"a"
,
0
,
"amount of burn"
)
cmd
.
MarkFlagRequired
(
"amount"
)
cmd
.
Flags
()
.
Float64P
(
"fee"
,
"f"
,
0
,
"token transaction fee"
)
}
func
tokenBurn
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
amount
,
_
:=
cmd
.
Flags
()
.
GetFloat64
(
"amount"
)
params
:=
&
tokenty
.
TokenBurn
{
Symbol
:
symbol
,
Amount
:
int64
((
amount
+
0.000001
)
*
1e4
)
*
1e4
,
}
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"token.CreateRawTokenBurnTx"
,
params
,
nil
)
ctx
.
RunWithoutMarshal
()
}
// GetTokenLogsCmd get logs of token
func
GetTokenLogsCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"get_token_logs"
,
Short
:
"Get logs of token"
,
Run
:
getTokenLogs
,
}
getTokenLogsFlags
(
cmd
)
return
cmd
}
func
getTokenLogs
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
paraName
,
_
:=
cmd
.
Flags
()
.
GetString
(
"paraName"
)
symbol
,
_
:=
cmd
.
Flags
()
.
GetString
(
"symbol"
)
var
params
rpctypes
.
Query4Jrpc
params
.
Execer
=
getRealExecName
(
paraName
,
"token"
)
params
.
FuncName
=
"GetTokenHistory"
params
.
Payload
=
types
.
MustPBToJSON
(
&
types
.
ReqString
{
Data
:
symbol
})
rpc
,
err
:=
jsonclient
.
NewJSONClient
(
rpcLaddr
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
var
res
tokenty
.
ReplyTokenLogs
err
=
rpc
.
Call
(
"Chain33.Query"
,
params
,
&
res
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
data
,
err
:=
json
.
MarshalIndent
(
res
,
""
,
" "
)
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
return
}
fmt
.
Println
(
string
(
data
))
}
func
getTokenLogsFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"symbol"
,
"s"
,
""
,
"token symbol"
)
cmd
.
MarkFlagRequired
(
"symbol"
)
}
plugin/dapp/token/executor/exec.go
View file @
b7699804
...
...
@@ -69,3 +69,13 @@ func (t *token) Exec_TransferToExec(payload *types.AssetsTransferToExec, tx *typ
}
return
t
.
ExecTransWithdraw
(
db
,
tx
,
&
tokenAction
,
index
)
}
func
(
t
*
token
)
Exec_TokenMint
(
payload
*
tokenty
.
TokenMint
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newTokenAction
(
t
,
""
,
tx
)
return
action
.
mint
(
payload
)
}
func
(
t
*
token
)
Exec_TokenBurn
(
payload
*
tokenty
.
TokenBurn
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newTokenAction
(
t
,
""
,
tx
)
return
action
.
burn
(
payload
)
}
plugin/dapp/token/executor/exec_del_local.go
View file @
b7699804
...
...
@@ -5,6 +5,7 @@
package
executor
import
(
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
tokenty
"github.com/33cn/plugin/plugin/dapp/token/types"
)
...
...
@@ -107,6 +108,19 @@ func (t *token) ExecDelLocal_TokenFinishCreate(payload *tokenty.TokenFinishCreat
var
set
[]
*
types
.
KeyValue
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
prepareKey
,
Value
:
types
.
Encode
(
localToken
)})
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
nil
})
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Del
([]
byte
(
txIndex
))
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
:=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
...
...
@@ -123,3 +137,53 @@ func (t *token) ExecDelLocal_TokenRevokeCreate(payload *tokenty.TokenRevokeCreat
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
prepareKey
,
Value
:
types
.
Encode
(
localToken
)})
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
func
(
t
*
token
)
ExecDelLocal_TokenMint
(
payload
*
tokenty
.
TokenMint
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
localToken
,
err
:=
loadLocalToken
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
,
t
.
GetLocalDB
())
if
err
!=
nil
{
return
nil
,
err
}
localToken
=
resetMint
(
localToken
,
t
.
GetHeight
(),
t
.
GetBlockTime
(),
payload
.
Amount
)
key
:=
calcTokenStatusKeyLocal
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
)
var
set
[]
*
types
.
KeyValue
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
types
.
Encode
(
localToken
)})
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Del
([]
byte
(
txIndex
))
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
:=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
func
(
t
*
token
)
ExecDelLocal_TokenBurn
(
payload
*
tokenty
.
TokenBurn
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
localToken
,
err
:=
loadLocalToken
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
,
t
.
GetLocalDB
())
if
err
!=
nil
{
return
nil
,
err
}
localToken
=
resetBurn
(
localToken
,
t
.
GetHeight
(),
t
.
GetBlockTime
(),
payload
.
Amount
)
key
:=
calcTokenStatusKeyLocal
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
)
var
set
[]
*
types
.
KeyValue
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
types
.
Encode
(
localToken
)})
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Del
([]
byte
(
txIndex
))
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
:=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
plugin/dapp/token/executor/exec_local.go
View file @
b7699804
...
...
@@ -5,7 +5,10 @@
package
executor
import
(
"encoding/hex"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
tokenty
"github.com/33cn/plugin/plugin/dapp/token/types"
)
...
...
@@ -107,6 +110,19 @@ func (t *token) ExecLocal_TokenFinishCreate(payload *tokenty.TokenFinishCreate,
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
types
.
Encode
(
localToken
)})
kv
:=
AddTokenToAssets
(
payload
.
Owner
,
t
.
GetLocalDB
(),
payload
.
Symbol
)
set
=
append
(
set
,
kv
...
)
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Add
(
&
tokenty
.
LocalLogs
{
Symbol
:
payload
.
Symbol
,
TxIndex
:
txIndex
,
ActionType
:
tokenty
.
TokenActionFinishCreate
,
TxHash
:
hex
.
EncodeToString
(
tx
.
Hash
())})
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
...
...
@@ -182,6 +198,16 @@ func setRevoked(t *tokenty.LocalToken, height, time int64) *tokenty.LocalToken {
return
t
}
func
setMint
(
t
*
tokenty
.
LocalToken
,
height
,
time
,
amount
int64
)
*
tokenty
.
LocalToken
{
t
.
Total
=
t
.
Total
+
amount
return
t
}
func
setBurn
(
t
*
tokenty
.
LocalToken
,
height
,
time
,
amount
int64
)
*
tokenty
.
LocalToken
{
t
.
Total
=
t
.
Total
-
amount
return
t
}
func
resetCreated
(
t
*
tokenty
.
LocalToken
)
*
tokenty
.
LocalToken
{
t
.
CreatedTime
=
0
t
.
CreatedHeight
=
0
...
...
@@ -195,3 +221,63 @@ func resetRevoked(t *tokenty.LocalToken) *tokenty.LocalToken {
t
.
Status
=
tokenty
.
TokenStatusPreCreated
return
t
}
func
resetMint
(
t
*
tokenty
.
LocalToken
,
height
,
time
,
amount
int64
)
*
tokenty
.
LocalToken
{
t
.
Total
=
t
.
Total
-
amount
return
t
}
func
resetBurn
(
t
*
tokenty
.
LocalToken
,
height
,
time
,
amount
int64
)
*
tokenty
.
LocalToken
{
t
.
Total
=
t
.
Total
+
amount
return
t
}
func
(
t
*
token
)
ExecLocal_TokenMint
(
payload
*
tokenty
.
TokenMint
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
localToken
,
err
:=
loadLocalToken
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
,
t
.
GetLocalDB
())
if
err
!=
nil
{
return
nil
,
err
}
localToken
=
setMint
(
localToken
,
t
.
GetHeight
(),
t
.
GetBlockTime
(),
payload
.
Amount
)
var
set
[]
*
types
.
KeyValue
key
:=
calcTokenStatusKeyLocal
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
)
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
types
.
Encode
(
localToken
)})
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Add
(
&
tokenty
.
LocalLogs
{
Symbol
:
payload
.
Symbol
,
TxIndex
:
txIndex
,
ActionType
:
tokenty
.
TokenActionMint
,
TxHash
:
"0x"
+
hex
.
EncodeToString
(
tx
.
Hash
())})
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
:=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
func
(
t
*
token
)
ExecLocal_TokenBurn
(
payload
*
tokenty
.
TokenBurn
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
localToken
,
err
:=
loadLocalToken
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
,
t
.
GetLocalDB
())
if
err
!=
nil
{
return
nil
,
err
}
localToken
=
setBurn
(
localToken
,
t
.
GetHeight
(),
t
.
GetBlockTime
(),
payload
.
Amount
)
var
set
[]
*
types
.
KeyValue
key
:=
calcTokenStatusKeyLocal
(
payload
.
Symbol
,
tx
.
From
(),
tokenty
.
TokenStatusCreated
)
set
=
append
(
set
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
types
.
Encode
(
localToken
)})
table
:=
NewLogsTable
(
t
.
GetLocalDB
())
txIndex
:=
dapp
.
HeightIndexStr
(
t
.
GetHeight
(),
int64
(
index
))
err
=
table
.
Add
(
&
tokenty
.
LocalLogs
{
Symbol
:
payload
.
Symbol
,
TxIndex
:
txIndex
,
ActionType
:
tokenty
.
TokenActionBurn
,
TxHash
:
"0x"
+
hex
.
EncodeToString
(
tx
.
Hash
())})
if
err
!=
nil
{
return
nil
,
err
}
kv
,
err
:=
table
.
Save
()
if
err
!=
nil
{
return
nil
,
err
}
set
=
append
(
set
,
kv
...
)
return
&
types
.
LocalDBSet
{
KV
:
set
},
nil
}
plugin/dapp/token/executor/logs.go
0 → 100644
View file @
b7699804
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
executor
// 记录token 的更改记录,
// 包含创建完成, 铸币, 以后可能包含燃烧等
import
(
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/types"
pty
"github.com/33cn/plugin/plugin/dapp/token/types"
)
var
opt_logs_table
=
&
table
.
Option
{
Prefix
:
"LODB-token"
,
Name
:
"logs"
,
Primary
:
"txIndex"
,
Index
:
[]
string
{
"symbol"
,
},
}
// LogsRow row
type
LogsRow
struct
{
*
pty
.
LocalLogs
}
// NewOrderRow create row
func
NewOrderRow
()
*
LogsRow
{
return
&
LogsRow
{
LocalLogs
:
nil
}
}
// CreateRow create row
func
(
r
*
LogsRow
)
CreateRow
()
*
table
.
Row
{
return
&
table
.
Row
{
Data
:
&
pty
.
LocalLogs
{}}
}
// SetPayload set payload
func
(
r
*
LogsRow
)
SetPayload
(
data
types
.
Message
)
error
{
if
d
,
ok
:=
data
.
(
*
pty
.
LocalLogs
);
ok
{
r
.
LocalLogs
=
d
return
nil
}
return
types
.
ErrTypeAsset
}
// Get get index key
func
(
r
*
LogsRow
)
Get
(
key
string
)
([]
byte
,
error
)
{
switch
key
{
case
"txIndex"
:
return
[]
byte
(
r
.
TxIndex
),
nil
case
"symbol"
:
return
[]
byte
(
r
.
Symbol
),
nil
default
:
return
nil
,
types
.
ErrNotFound
}
}
// NewLogsTable create table
func
NewLogsTable
(
kvdb
dbm
.
KV
)
*
table
.
Table
{
rowMeta
:=
NewOrderRow
()
err
:=
rowMeta
.
SetPayload
(
&
pty
.
LocalLogs
{})
if
err
!=
nil
{
panic
(
err
)
}
t
,
err
:=
table
.
NewTable
(
rowMeta
,
kvdb
,
opt_logs_table
)
if
err
!=
nil
{
panic
(
err
)
}
return
t
}
func
list
(
db
dbm
.
KVDB
,
indexName
string
,
data
*
pty
.
LocalLogs
,
count
,
direction
int32
)
([]
*
table
.
Row
,
error
)
{
query
:=
NewLogsTable
(
db
)
.
GetQuery
(
db
)
var
primary
[]
byte
if
len
(
data
.
TxIndex
)
>
0
{
primary
=
[]
byte
(
data
.
TxIndex
)
}
cur
:=
&
LogsRow
{
LocalLogs
:
data
}
index
,
err
:=
cur
.
Get
(
indexName
)
if
err
!=
nil
{
tokenlog
.
Error
(
"query List failed"
,
"key"
,
string
(
primary
),
"param"
,
data
,
"err"
,
err
)
return
nil
,
err
}
tokenlog
.
Debug
(
"query List dbg"
,
"indexName"
,
indexName
,
"index"
,
string
(
index
),
"primary"
,
primary
,
"count"
,
count
,
"direction"
,
direction
)
rows
,
err
:=
query
.
ListIndex
(
indexName
,
index
,
primary
,
count
,
direction
)
if
err
!=
nil
{
tokenlog
.
Error
(
"query List failed"
,
"key"
,
string
(
primary
),
"param"
,
data
,
"err"
,
err
)
return
nil
,
err
}
if
len
(
rows
)
==
0
{
return
nil
,
types
.
ErrNotFound
}
return
rows
,
nil
}
plugin/dapp/token/executor/query.go
View file @
b7699804
...
...
@@ -69,3 +69,25 @@ func (t *token) Query_GetTxByToken(in *tokenty.ReqTokenTx) (types.Message, error
}
return
t
.
getTxByToken
(
in
)
}
// Query_GetTokenHistory 获取token 的变更历史
func
(
t
*
token
)
Query_GetTokenHistory
(
in
*
types
.
ReqString
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
rows
,
err
:=
list
(
t
.
GetLocalDB
(),
"symbol"
,
&
tokenty
.
LocalLogs
{
Symbol
:
in
.
Data
},
-
1
,
0
)
if
err
!=
nil
{
tokenlog
.
Error
(
"Query_GetTokenHistory"
,
"err"
,
err
)
return
nil
,
err
}
var
replys
tokenty
.
ReplyTokenLogs
for
_
,
row
:=
range
rows
{
o
,
ok
:=
row
.
Data
.
(
*
tokenty
.
LocalLogs
)
if
!
ok
{
tokenlog
.
Error
(
"Query_GetTokenHistory"
,
"err"
,
"bad row type"
)
return
nil
,
types
.
ErrTypeAsset
}
replys
.
Logs
=
append
(
replys
.
Logs
,
o
)
}
return
&
replys
,
nil
}
plugin/dapp/token/executor/token_new_test.go
View file @
b7699804
...
...
@@ -157,6 +157,7 @@ func TestPrecreate(t *testing.T) {
Total
:
tokenAmount
,
Price
:
tokenPrice
,
Owner
:
addr
,
Category
:
pty
.
CategoryMintBurnSupport
,
}
precreate
:=
&
pty
.
TokenAction
{
Ty
:
pty
.
TokenActionPreCreate
,
...
...
@@ -312,6 +313,78 @@ func TestQueryAsset(t *testing.T) {
}
func
TestTokenMint
(
t
*
testing
.
T
)
{
if
!
isMainNetTest
{
return
}
fmt
.
Println
(
"TestTokenMint start"
)
defer
fmt
.
Println
(
"TestTokenMint end"
)
v
:=
&
pty
.
TokenAction_TokenMint
{
TokenMint
:
&
pty
.
TokenMint
{
Symbol
:
tokenSym
,
Amount
:
transAmount
}}
transfer
:=
&
pty
.
TokenAction
{
Value
:
v
,
Ty
:
pty
.
ActionTransfer
}
tx
:=
&
types
.
Transaction
{
Execer
:
[]
byte
(
execName
),
Payload
:
types
.
Encode
(
transfer
),
Fee
:
fee
,
To
:
addrexec
}
tx
.
Nonce
=
r
.
Int63
()
tx
.
Sign
(
types
.
SECP256K1
,
privkey
)
reply
,
err
:=
mainClient
.
SendTransaction
(
context
.
Background
(),
tx
)
if
err
!=
nil
{
fmt
.
Println
(
"err"
,
err
)
t
.
Error
(
err
)
return
}
if
!
reply
.
IsOk
{
fmt
.
Println
(
"err = "
,
reply
.
GetMsg
())
t
.
Error
(
ErrTest
)
return
}
if
!
waitTx
(
tx
.
Hash
())
{
t
.
Error
(
ErrTest
)
return
}
}
func
TestQueryTokenLogs
(
t
*
testing
.
T
)
{
if
!
isParaNetTest
{
return
}
fmt
.
Println
(
"TestQueryTokenLogs start"
)
defer
fmt
.
Println
(
"TestQueryTokenLogs end"
)
var
req
types
.
ChainExecutor
req
.
Driver
=
execName
req
.
FuncName
=
"GetTokenHistory"
req
.
Param
=
types
.
Encode
(
&
types
.
ReqString
{
Data
:
tokenSym
})
reply
,
err
:=
paraClient
.
QueryChain
(
context
.
Background
(),
&
req
)
if
err
!=
nil
{
fmt
.
Println
(
err
)
t
.
Error
(
err
)
return
}
if
!
reply
.
IsOk
{
fmt
.
Println
(
"Query reply err"
)
t
.
Error
(
ErrTest
)
return
}
var
res
pty
.
ReplyTokenLogs
err
=
types
.
Decode
(
reply
.
Msg
,
&
res
)
if
err
!=
nil
{
t
.
Error
(
err
)
return
}
assert
.
Equal
(
t
,
2
,
len
(
res
.
Logs
))
for
_
,
l
:=
range
res
.
Logs
{
fmt
.
Println
(
l
.
Symbol
)
fmt
.
Println
(
l
.
TxHash
)
fmt
.
Println
(
l
.
TxIndex
)
fmt
.
Println
(
l
.
ActionType
)
}
}
//***************************************************
//**************common actions for Test**************
//***************************************************
...
...
plugin/dapp/token/executor/token_test.go
0 → 100644
View file @
b7699804
package
executor
import
(
"testing"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm
"github.com/33cn/chain33/common/db"
pty
"github.com/33cn/plugin/plugin/dapp/token/types"
"github.com/stretchr/testify/assert"
//"github.com/33cn/chain33/types/jsonpb"
)
type
execEnv
struct
{
blockTime
int64
blockHeight
int64
difficulty
uint64
}
var
(
Symbol
=
"TEST"
AssetExecToken
=
"token"
AssetExecPara
=
"paracross"
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
PrivKeyB
=
"0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4"
// 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC
=
"0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115"
// 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD
=
"0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71"
// 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
Nodes
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
func
TestToken
(
t
*
testing
.
T
)
{
types
.
SetTitleOnlyForTest
(
"chain33"
)
tokenTotal
:=
int64
(
10000
*
1e8
)
tokenBurn
:=
int64
(
10
*
1e8
)
tokenMint
:=
int64
(
20
*
1e8
)
total
:=
int64
(
100000
)
accountA
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
0
]),
}
accountB
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
1
]),
}
execAddr
:=
address
.
ExecAddress
(
pty
.
TokenX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
100
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
AssetExecPara
,
Symbol
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB
,
_
:=
account
.
NewAccountDB
(
AssetExecPara
,
Symbol
,
stateDB
)
accB
.
SaveExecAccount
(
execAddr
,
&
accountB
)
env
:=
execEnv
{
10
,
types
.
GetDappFork
(
pty
.
TokenX
,
pty
.
ForkTokenSymbolWithNumberX
),
1539918074
,
}
// set config key
item
:=
&
types
.
ConfigItem
{
Key
:
"mavl-manage-token-blacklist"
,
Value
:
&
types
.
ConfigItem_Arr
{
Arr
:
&
types
.
ArrayConfig
{
Value
:
[]
string
{
"bty"
}},
},
}
stateDB
.
Set
([]
byte
(
item
.
Key
),
types
.
Encode
(
item
))
item2
:=
&
types
.
ConfigItem
{
Key
:
"mavl-manage-token-finisher"
,
Value
:
&
types
.
ConfigItem_Arr
{
Arr
:
&
types
.
ArrayConfig
{
Value
:
[]
string
{
string
(
Nodes
[
0
])}},
},
}
stateDB
.
Set
([]
byte
(
item2
.
Key
),
types
.
Encode
(
item2
))
// create token
// 创建
//ty := pty.TokenType{}
p1
:=
&
pty
.
TokenPreCreate
{
Name
:
Symbol
,
Symbol
:
Symbol
,
Introduction
:
Symbol
,
Total
:
tokenTotal
,
Price
:
0
,
Owner
:
string
(
Nodes
[
0
]),
Category
:
pty
.
CategoryMintBurnSupport
,
}
//v, _ := types.PBToJSON(p1)
createTx
,
err
:=
types
.
CallCreateTransaction
(
pty
.
TokenX
,
"TokenPreCreate"
,
p1
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx
,
err
=
signTx
(
createTx
,
PrivKeyA
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
:=
newToken
()
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
exec
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
receipt
,
err
:=
exec
.
Exec
(
createTx
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
t
.
Log
(
receipt
)
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
:=
exec
.
ExecLocal
(
createTx
,
receiptDate
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
p2
:=
&
pty
.
TokenFinishCreate
{
Symbol
:
Symbol
,
Owner
:
string
(
Nodes
[
0
]),
}
//v, _ := types.PBToJSON(p1)
createTx2
,
err
:=
types
.
CallCreateTransaction
(
pty
.
TokenX
,
"TokenFinishCreate"
,
p2
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx2
,
err
=
signTx
(
createTx2
,
PrivKeyA
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx2
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
//t.Log(receipt)
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
accDB
,
_
:=
account
.
NewAccountDB
(
pty
.
TokenX
,
Symbol
,
stateDB
)
accChcek
:=
accDB
.
LoadAccount
(
string
(
Nodes
[
0
]))
assert
.
Equal
(
t
,
tokenTotal
,
accChcek
.
Balance
)
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx2
,
receiptDate
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
// mint burn
p3
:=
&
pty
.
TokenMint
{
Symbol
:
Symbol
,
Amount
:
tokenMint
,
}
//v, _ := types.PBToJSON(p1)
createTx3
,
err
:=
types
.
CallCreateTransaction
(
pty
.
TokenX
,
"TokenMint"
,
p3
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx3
,
err
=
signTx
(
createTx3
,
PrivKeyA
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
2
,
env
.
blockTime
+
2
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx3
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
//t.Log(receipt)
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
accChcek
=
accDB
.
LoadAccount
(
string
(
Nodes
[
0
]))
assert
.
Equal
(
t
,
tokenTotal
+
tokenMint
,
accChcek
.
Balance
)
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx3
,
receiptDate
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
p4
:=
&
pty
.
TokenBurn
{
Symbol
:
Symbol
,
Amount
:
tokenBurn
,
}
//v, _ := types.PBToJSON(p1)
createTx4
,
err
:=
types
.
CallCreateTransaction
(
pty
.
TokenX
,
"TokenBurn"
,
p4
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process"
,
"err"
,
err
)
}
createTx4
,
err
=
signTx
(
createTx4
,
PrivKeyA
)
if
err
!=
nil
{
t
.
Error
(
"RPC_Default_Process sign"
,
"err"
,
err
)
}
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
1
,
env
.
difficulty
)
receipt
,
err
=
exec
.
Exec
(
createTx4
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
receipt
)
//t.Log(receipt)
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
accChcek
=
accDB
.
LoadAccount
(
string
(
Nodes
[
0
]))
assert
.
Equal
(
t
,
tokenTotal
+
tokenMint
-
tokenBurn
,
accChcek
.
Balance
)
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
createTx4
,
receiptDate
,
int
(
1
))
assert
.
Nil
(
t
,
err
)
assert
.
NotNil
(
t
,
set
)
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
pty
.
TokenX
,
signType
))
if
err
!=
nil
{
return
tx
,
err
}
bytes
,
err
:=
common
.
FromHex
(
hexPrivKey
[
:
])
if
err
!=
nil
{
return
tx
,
err
}
privKey
,
err
:=
c
.
PrivKeyFromBytes
(
bytes
)
if
err
!=
nil
{
return
tx
,
err
}
tx
.
Sign
(
int32
(
signType
),
privKey
)
return
tx
,
nil
}
plugin/dapp/token/executor/tokendb.go
View file @
b7699804
...
...
@@ -40,7 +40,10 @@ func newTokenDB(preCreate *pty.TokenPreCreate, creator string, height int64) *to
func
(
t
*
tokenDB
)
save
(
db
dbm
.
KV
,
key
[]
byte
)
{
set
:=
t
.
getKVSet
(
key
)
for
i
:=
0
;
i
<
len
(
set
);
i
++
{
db
.
Set
(
set
[
i
]
.
GetKey
(),
set
[
i
]
.
Value
)
err
:=
db
.
Set
(
set
[
i
]
.
GetKey
(),
set
[
i
]
.
Value
)
if
err
!=
nil
{
panic
(
err
)
}
}
}
...
...
@@ -59,6 +62,48 @@ func (t *tokenDB) getKVSet(key []byte) (kvset []*types.KeyValue) {
return
kvset
}
func
loadTokenDB
(
db
dbm
.
KV
,
symbol
string
)
(
*
tokenDB
,
error
)
{
token
,
err
:=
db
.
Get
(
calcTokenKey
(
symbol
))
if
err
!=
nil
{
tokenlog
.
Error
(
"tokendb load "
,
"Can't get token form db for token"
,
symbol
)
return
nil
,
pty
.
ErrTokenNotExist
}
var
t
pty
.
Token
err
=
types
.
Decode
(
token
,
&
t
)
if
err
!=
nil
{
tokenlog
.
Error
(
"tokendb load"
,
"Can't decode token info"
,
symbol
)
return
nil
,
err
}
return
&
tokenDB
{
t
},
nil
}
func
(
t
*
tokenDB
)
mint
(
db
dbm
.
KV
,
addr
string
,
amount
int64
)
([]
*
types
.
KeyValue
,
[]
*
types
.
ReceiptLog
,
error
)
{
if
t
.
token
.
Owner
!=
addr
{
return
nil
,
nil
,
types
.
ErrNotAllow
}
if
t
.
token
.
Total
+
amount
>
types
.
MaxTokenBalance
{
return
nil
,
nil
,
types
.
ErrAmount
}
prevToken
:=
t
.
token
t
.
token
.
Total
+=
amount
kvs
:=
append
(
t
.
getKVSet
(
calcTokenKey
(
t
.
token
.
Symbol
)),
t
.
getKVSet
(
calcTokenAddrNewKeyS
(
t
.
token
.
Symbol
,
t
.
token
.
Owner
))
...
)
logs
:=
[]
*
types
.
ReceiptLog
{{
Ty
:
pty
.
TyLogTokenMint
,
Log
:
types
.
Encode
(
&
pty
.
ReceiptTokenAmount
{
Prev
:
&
prevToken
,
Current
:
&
t
.
token
})}}
return
kvs
,
logs
,
nil
}
func
(
t
*
tokenDB
)
burn
(
db
dbm
.
KV
,
amount
int64
)
([]
*
types
.
KeyValue
,
[]
*
types
.
ReceiptLog
,
error
)
{
if
t
.
token
.
Total
<
amount
{
return
nil
,
nil
,
types
.
ErrNoBalance
}
prevToken
:=
t
.
token
t
.
token
.
Total
-=
amount
kvs
:=
append
(
t
.
getKVSet
(
calcTokenKey
(
t
.
token
.
Symbol
)),
t
.
getKVSet
(
calcTokenAddrNewKeyS
(
t
.
token
.
Symbol
,
t
.
token
.
Owner
))
...
)
logs
:=
[]
*
types
.
ReceiptLog
{{
Ty
:
pty
.
TyLogTokenBurn
,
Log
:
types
.
Encode
(
&
pty
.
ReceiptTokenAmount
{
Prev
:
&
prevToken
,
Current
:
&
t
.
token
})}}
return
kvs
,
logs
,
nil
}
func
getTokenFromDB
(
db
dbm
.
KV
,
symbol
string
,
owner
string
)
(
*
pty
.
Token
,
error
)
{
key
:=
calcTokenAddrKeyS
(
symbol
,
owner
)
value
,
err
:=
db
.
Get
(
key
)
...
...
@@ -468,3 +513,87 @@ func validSymbolWithHeight(cs []byte, height int64) bool {
}
return
validSymbolOriginal
(
cs
)
}
// 铸币不可控, 也是麻烦。 2选1
// 1. 谁可以发起
// 2. 是否需要审核 这个会增加管理的成本
// 现在实现选择 1
func
(
action
*
tokenAction
)
mint
(
mint
*
pty
.
TokenMint
)
(
*
types
.
Receipt
,
error
)
{
if
mint
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
if
mint
.
GetAmount
()
<
0
||
mint
.
GetAmount
()
>
types
.
MaxTokenBalance
||
mint
.
GetSymbol
()
==
""
{
return
nil
,
types
.
ErrInvalidParam
}
tokendb
,
err
:=
loadTokenDB
(
action
.
db
,
mint
.
GetSymbol
())
if
err
!=
nil
{
return
nil
,
err
}
if
tokendb
.
token
.
Category
&
pty
.
CategoryMintBurnSupport
==
0
{
tokenlog
.
Error
(
"Can't mint category"
,
"category"
,
tokendb
.
token
.
Category
,
"support"
,
pty
.
CategoryMintBurnSupport
)
return
nil
,
types
.
ErrNotSupport
}
kvs
,
logs
,
err
:=
tokendb
.
mint
(
action
.
db
,
action
.
fromaddr
,
mint
.
Amount
)
if
err
!=
nil
{
tokenlog
.
Error
(
"token mint "
,
"symbol"
,
mint
.
GetSymbol
(),
"error"
,
err
,
"from"
,
action
.
fromaddr
,
"owner"
,
tokendb
.
token
.
Owner
)
return
nil
,
err
}
tokenAccount
,
err
:=
account
.
NewAccountDB
(
"token"
,
mint
.
GetSymbol
(),
action
.
db
)
if
err
!=
nil
{
return
nil
,
err
}
tokenlog
.
Debug
(
"mint"
,
"token.Owner"
,
mint
.
Symbol
,
"token.GetTotal()"
,
mint
.
Amount
)
receipt
,
err
:=
tokenAccount
.
Mint
(
action
.
fromaddr
,
mint
.
Amount
)
if
err
!=
nil
{
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
return
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvs
,
Logs
:
logs
},
nil
}
func
(
action
*
tokenAction
)
burn
(
burn
*
pty
.
TokenBurn
)
(
*
types
.
Receipt
,
error
)
{
if
burn
==
nil
{
return
nil
,
types
.
ErrInvalidParam
}
if
burn
.
GetAmount
()
<
0
||
burn
.
GetAmount
()
>
types
.
MaxTokenBalance
||
burn
.
GetSymbol
()
==
""
{
return
nil
,
types
.
ErrInvalidParam
}
tokendb
,
err
:=
loadTokenDB
(
action
.
db
,
burn
.
GetSymbol
())
if
err
!=
nil
{
return
nil
,
err
}
if
tokendb
.
token
.
Category
&
pty
.
CategoryMintBurnSupport
==
0
{
tokenlog
.
Error
(
"Can't burn category"
,
"category"
,
tokendb
.
token
.
Category
,
"support"
,
pty
.
CategoryMintBurnSupport
)
return
nil
,
types
.
ErrNotSupport
}
kvs
,
logs
,
err
:=
tokendb
.
burn
(
action
.
db
,
burn
.
Amount
)
if
err
!=
nil
{
tokenlog
.
Error
(
"token burn "
,
"symbol"
,
burn
.
GetSymbol
(),
"error"
,
err
,
"from"
,
action
.
fromaddr
,
"owner"
,
tokendb
.
token
.
Owner
)
return
nil
,
err
}
tokenAccount
,
err
:=
account
.
NewAccountDB
(
"token"
,
burn
.
GetSymbol
(),
action
.
db
)
if
err
!=
nil
{
return
nil
,
err
}
tokenlog
.
Debug
(
"burn"
,
"token.Owner"
,
burn
.
Symbol
,
"token.GetTotal()"
,
burn
.
Amount
)
receipt
,
err
:=
tokenAccount
.
Burn
(
action
.
fromaddr
,
burn
.
Amount
)
if
err
!=
nil
{
return
nil
,
err
}
logs
=
append
(
logs
,
receipt
.
Logs
...
)
kvs
=
append
(
kvs
,
receipt
.
KV
...
)
return
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kvs
,
Logs
:
logs
},
nil
}
plugin/dapp/token/executor/transwithdraw.go
View file @
b7699804
...
...
@@ -172,7 +172,10 @@ func updateAddrReciver(cachedb dbm.KVDB, token string, addr string, amount int64
}
else
{
recv
-=
amount
}
setAddrReciver
(
cachedb
,
token
,
addr
,
recv
)
err
=
setAddrReciver
(
cachedb
,
token
,
addr
,
recv
)
if
err
!=
nil
{
return
nil
,
err
}
//keyvalue
return
getAddrReciverKV
(
token
,
addr
,
recv
),
nil
}
plugin/dapp/token/proto/token.proto
View file @
b7699804
...
...
@@ -15,6 +15,8 @@ message TokenAction {
AssetsWithdraw
withdraw
=
5
;
AssetsGenesis
genesis
=
6
;
AssetsTransferToExec
transferToExec
=
8
;
TokenMint
tokenMint
=
9
;
TokenBurn
tokenBurn
=
10
;
}
int32
Ty
=
7
;
}
...
...
@@ -40,6 +42,16 @@ message TokenRevokeCreate {
string
owner
=
2
;
}
message
TokenMint
{
string
symbol
=
1
;
int64
amount
=
2
;
}
message
TokenBurn
{
string
symbol
=
1
;
int64
amount
=
2
;
}
// state db
message
Token
{
string
name
=
1
;
...
...
@@ -60,6 +72,11 @@ message ReceiptToken {
int32
status
=
3
;
}
message
ReceiptTokenAmount
{
Token
prev
=
1
;
Token
current
=
2
;
}
// local
message
LocalToken
{
string
name
=
1
;
...
...
@@ -82,6 +99,13 @@ message LocalToken {
int32
category
=
17
;
}
message
LocalLogs
{
string
symbol
=
1
;
string
txIndex
=
2
;
int32
actionType
=
3
;
string
txHash
=
4
;
}
// query
message
ReqTokens
{
bool
queryAll
=
1
;
...
...
@@ -142,6 +166,10 @@ message ReqTokenTx {
string
addr
=
7
;
}
message
ReplyTokenLogs
{
repeated
LocalLogs
logs
=
1
;
}
service
token
{
// token 对外提供服务的接口
//区块链接口
...
...
plugin/dapp/token/rpc/rpc.go
View file @
b7699804
...
...
@@ -121,3 +121,29 @@ func (c *Jrpc) CreateRawTokenRevokeTx(param *tokenty.TokenRevokeCreate, result *
*
result
=
hex
.
EncodeToString
(
data
)
return
nil
}
// CreateRawTokenMintTx 创建未签名的mint Token交易
func
(
c
*
Jrpc
)
CreateRawTokenMintTx
(
param
*
tokenty
.
TokenMint
,
result
*
interface
{})
error
{
if
param
==
nil
||
param
.
Symbol
==
""
||
param
.
Amount
<=
0
{
return
types
.
ErrInvalidParam
}
data
,
err
:=
types
.
CallCreateTx
(
types
.
ExecName
(
tokenty
.
TokenX
),
"TokenMint"
,
param
)
if
err
!=
nil
{
return
err
}
*
result
=
hex
.
EncodeToString
(
data
)
return
nil
}
// CreateRawTokenBurnTx 创建未签名的 burn Token交易
func
(
c
*
Jrpc
)
CreateRawTokenBurnTx
(
param
*
tokenty
.
TokenBurn
,
result
*
interface
{})
error
{
if
param
==
nil
||
param
.
Symbol
==
""
||
param
.
Amount
<=
0
{
return
types
.
ErrInvalidParam
}
data
,
err
:=
types
.
CallCreateTx
(
types
.
ExecName
(
tokenty
.
TokenX
),
"TokenBurn"
,
param
)
if
err
!=
nil
{
return
err
}
*
result
=
hex
.
EncodeToString
(
data
)
return
nil
}
plugin/dapp/token/types/const.go
View file @
b7699804
...
...
@@ -19,6 +19,10 @@ const (
TokenActionRevokeCreate
=
9
// TokenActionTransferToExec for token transfer to exec
TokenActionTransferToExec
=
11
// TokenActionMint for token mint
TokenActionMint
=
12
// TokenActionBurn for token burn
TokenActionBurn
=
13
)
// token status
...
...
@@ -72,6 +76,10 @@ const (
TyLogTokenGenesisTransfer
=
321
// TyLogTokenGenesisDeposit log for token genesis deposit
TyLogTokenGenesisDeposit
=
322
// TyLogTokenMint log for token mint
TyLogTokenMint
=
323
// TyLogTokenBurn log for token burn
TyLogTokenBurn
=
324
)
const
(
...
...
@@ -82,3 +90,8 @@ const (
// TokenIntroLenLimit token introduction length limit
TokenIntroLenLimit
=
1024
)
const
(
// CategoryMintBurnSupport support mint & burn
CategoryMintBurnSupport
=
1
<<
iota
)
plugin/dapp/token/types/token.pb.go
View file @
b7699804
This diff is collapsed.
Click to expand it.
plugin/dapp/token/types/types.go
View file @
b7699804
...
...
@@ -57,6 +57,8 @@ func (t *TokenType) GetTypeMap() map[string]int32 {
"TokenFinishCreate"
:
TokenActionFinishCreate
,
"TokenRevokeCreate"
:
TokenActionRevokeCreate
,
"TransferToExec"
:
TokenActionTransferToExec
,
"TokenMint"
:
TokenActionMint
,
"TokenBurn"
:
TokenActionBurn
,
}
}
...
...
@@ -75,6 +77,8 @@ func (t *TokenType) GetLogMap() map[int64]*types.LogInfo {
TyLogPreCreateToken
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptToken
{}),
Name
:
"LogPreCreateToken"
},
TyLogFinishCreateToken
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptToken
{}),
Name
:
"LogFinishCreateToken"
},
TyLogRevokeCreateToken
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptToken
{}),
Name
:
"LogRevokeCreateToken"
},
TyLogTokenMint
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptTokenAmount
{}),
Name
:
"LogMintToken"
},
TyLogTokenBurn
:
{
Ty
:
reflect
.
TypeOf
(
ReceiptTokenAmount
{}),
Name
:
"LogBurnToken"
},
}
}
...
...
plugin/store/init/init.go
View file @
b7699804
package
init
import
(
_
"github.com/33cn/plugin/plugin/store/kvdb"
//auto gen
_
"github.com/33cn/plugin/plugin/store/kvmvcc"
//auto gen
_
"github.com/33cn/plugin/plugin/store/mpt"
//auto gen
_
"github.com/33cn/plugin/plugin/store/kvdb"
//auto gen
_
"github.com/33cn/plugin/plugin/store/kvmvcc"
//auto gen
_
"github.com/33cn/plugin/plugin/store/kvmvccmavl"
//auto gen
_
"github.com/33cn/plugin/plugin/store/mpt"
//auto gen
)
plugin/store/kvmvccmavl/kvmvcc_mavl.go
0 → 100644
View file @
b7699804
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package kvmvccmavl kvmvcc+mavl接口
package
kvmvccmavl
import
(
"bytes"
"errors"
"fmt"
"sync"
"sync/atomic"
"time"
dbm
"github.com/33cn/chain33/common/db"
clog
"github.com/33cn/chain33/common/log"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/queue"
drivers
"github.com/33cn/chain33/system/store"
"github.com/33cn/chain33/types"
"github.com/hashicorp/golang-lru"
)
var
(
kmlog
=
log
.
New
(
"module"
,
"kvmvccMavl"
)
// ErrStateHashLost ...
ErrStateHashLost
=
errors
.
New
(
"ErrStateHashLost"
)
kvmvccMavlFork
int64
=
200
*
10000
isDelMavlData
=
false
delMavlDataHeight
=
kvmvccMavlFork
+
10000
delMavlDataState
int32
wg
sync
.
WaitGroup
quit
bool
)
const
(
cacheSize
=
2048
//可以缓存2048个roothash, height对
batchDataSize
=
1024
*
1024
*
1
delMavlStateStart
=
1
delMavlStateEnd
=
0
)
// SetLogLevel set log level
func
SetLogLevel
(
level
string
)
{
clog
.
SetLogLevel
(
level
)
}
// DisableLog disable log output
func
DisableLog
()
{
kmlog
.
SetHandler
(
log
.
DiscardHandler
())
}
func
init
()
{
drivers
.
Reg
(
"kvmvccmavl"
,
New
)
}
// KVmMavlStore provide kvmvcc and mavl store interface implementation
type
KVmMavlStore
struct
{
*
drivers
.
BaseStore
*
KVMVCCStore
*
MavlStore
cache
*
lru
.
Cache
}
type
subKVMVCCConfig
struct
{
EnableMVCCIter
bool
`json:"enableMVCCIter"`
EnableMavlPrune
bool
`json:"enableMavlPrune"`
PruneHeight
int32
`json:"pruneHeight"`
}
type
subMavlConfig
struct
{
EnableMavlPrefix
bool
`json:"enableMavlPrefix"`
EnableMVCC
bool
`json:"enableMVCC"`
EnableMavlPrune
bool
`json:"enableMavlPrune"`
PruneHeight
int32
`json:"pruneHeight"`
}
type
subConfig
struct
{
EnableMVCCIter
bool
`json:"enableMVCCIter"`
EnableMavlPrefix
bool
`json:"enableMavlPrefix"`
EnableMVCC
bool
`json:"enableMVCC"`
EnableMavlPrune
bool
`json:"enableMavlPrune"`
PruneHeight
int32
`json:"pruneHeight"`
}
// New construct KVMVCCStore module
func
New
(
cfg
*
types
.
Store
,
sub
[]
byte
)
queue
.
Module
{
bs
:=
drivers
.
NewBaseStore
(
cfg
)
var
kvms
*
KVmMavlStore
var
subcfg
subConfig
var
subKVMVCCcfg
subKVMVCCConfig
var
subMavlcfg
subMavlConfig
if
sub
!=
nil
{
types
.
MustDecode
(
sub
,
&
subcfg
)
subKVMVCCcfg
.
EnableMVCCIter
=
subcfg
.
EnableMVCCIter
subKVMVCCcfg
.
EnableMavlPrune
=
subcfg
.
EnableMavlPrune
subKVMVCCcfg
.
PruneHeight
=
subcfg
.
PruneHeight
subMavlcfg
.
EnableMavlPrefix
=
subcfg
.
EnableMavlPrefix
subMavlcfg
.
EnableMVCC
=
subcfg
.
EnableMVCC
subMavlcfg
.
EnableMavlPrune
=
subcfg
.
EnableMavlPrune
subMavlcfg
.
PruneHeight
=
subcfg
.
PruneHeight
}
cache
,
err
:=
lru
.
New
(
cacheSize
)
if
err
!=
nil
{
panic
(
"new KVmMavlStore fail"
)
}
kvms
=
&
KVmMavlStore
{
bs
,
NewKVMVCC
(
&
subKVMVCCcfg
,
bs
.
GetDB
()),
NewMavl
(
&
subMavlcfg
,
bs
.
GetDB
()),
cache
}
// 查询是否已经删除mavl
_
,
err
=
bs
.
GetDB
()
.
Get
(
genDelMavlKey
(
mvccPrefix
))
if
err
==
nil
{
isDelMavlData
=
true
}
bs
.
SetChild
(
kvms
)
return
kvms
}
// Close the KVmMavlStore module
func
(
kvmMavls
*
KVmMavlStore
)
Close
()
{
quit
=
true
wg
.
Wait
()
kvmMavls
.
KVMVCCStore
.
Close
()
kvmMavls
.
MavlStore
.
Close
()
kvmMavls
.
BaseStore
.
Close
()
kmlog
.
Info
(
"store kvmMavls closed"
)
}
// Set kvs with statehash to KVmMavlStore
func
(
kvmMavls
*
KVmMavlStore
)
Set
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
if
datas
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
MavlStore
.
Set
(
datas
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
_
,
err
=
kvmMavls
.
KVMVCCStore
.
Set
(
datas
,
hash
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
if
err
==
nil
{
kvmMavls
.
cache
.
Add
(
string
(
hash
),
datas
.
Height
)
}
return
hash
,
err
}
// 仅仅做kvmvcc
hash
,
err
:=
kvmMavls
.
KVMVCCStore
.
Set
(
datas
,
nil
,
sync
)
if
err
==
nil
{
kvmMavls
.
cache
.
Add
(
string
(
hash
),
datas
.
Height
)
}
// 删除Mavl数据
if
datas
.
Height
>
delMavlDataHeight
&&
!
isDelMavlData
&&
!
isDelMavling
()
{
wg
.
Add
(
1
)
go
DelMavl
(
kvmMavls
.
GetDB
())
}
return
hash
,
err
}
// Get kvs with statehash from KVmMavlStore
func
(
kvmMavls
*
KVmMavlStore
)
Get
(
datas
*
types
.
StoreGet
)
[][]
byte
{
return
kvmMavls
.
KVMVCCStore
.
Get
(
datas
)
}
// MemSet set kvs to the mem of KVmMavlStore module and return the StateHash
func
(
kvmMavls
*
KVmMavlStore
)
MemSet
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
if
datas
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
MavlStore
.
MemSet
(
datas
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
_
,
err
=
kvmMavls
.
KVMVCCStore
.
MemSet
(
datas
,
hash
,
sync
)
if
err
!=
nil
{
return
hash
,
err
}
if
err
==
nil
{
kvmMavls
.
cache
.
Add
(
string
(
hash
),
datas
.
Height
)
}
return
hash
,
err
}
// 仅仅做kvmvcc
hash
,
err
:=
kvmMavls
.
KVMVCCStore
.
MemSet
(
datas
,
nil
,
sync
)
if
err
==
nil
{
kvmMavls
.
cache
.
Add
(
string
(
hash
),
datas
.
Height
)
}
// 删除Mavl数据
if
datas
.
Height
>
delMavlDataHeight
&&
!
isDelMavlData
&&
!
isDelMavling
()
{
wg
.
Add
(
1
)
go
DelMavl
(
kvmMavls
.
GetDB
())
}
return
hash
,
err
}
// Commit kvs in the mem of KVmMavlStore module to state db and return the StateHash
func
(
kvmMavls
*
KVmMavlStore
)
Commit
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
if
value
,
ok
:=
kvmMavls
.
cache
.
Get
(
string
(
req
.
Hash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
MavlStore
.
Commit
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
_
,
err
=
kvmMavls
.
KVMVCCStore
.
Commit
(
req
)
return
hash
,
err
}
return
kvmMavls
.
KVMVCCStore
.
Commit
(
req
)
}
return
kvmMavls
.
KVMVCCStore
.
Commit
(
req
)
}
// Rollback kvs in the mem of KVmMavlStore module and return the StateHash
func
(
kvmMavls
*
KVmMavlStore
)
Rollback
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
if
value
,
ok
:=
kvmMavls
.
cache
.
Get
(
string
(
req
.
Hash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
MavlStore
.
Rollback
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
_
,
err
=
kvmMavls
.
KVMVCCStore
.
Rollback
(
req
)
return
hash
,
err
}
return
kvmMavls
.
KVMVCCStore
.
Rollback
(
req
)
}
return
kvmMavls
.
KVMVCCStore
.
Rollback
(
req
)
}
// IterateRangeByStateHash travel with Prefix by StateHash to get the latest version kvs.
func
(
kvmMavls
*
KVmMavlStore
)
IterateRangeByStateHash
(
statehash
[]
byte
,
start
[]
byte
,
end
[]
byte
,
ascending
bool
,
fn
func
(
key
,
value
[]
byte
)
bool
)
{
if
value
,
ok
:=
kvmMavls
.
cache
.
Get
(
string
(
statehash
));
ok
{
if
value
.
(
int64
)
<
kvmvccMavlFork
{
kvmMavls
.
MavlStore
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
return
}
kvmMavls
.
KVMVCCStore
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
return
}
kvmMavls
.
KVMVCCStore
.
IterateRangeByStateHash
(
statehash
,
start
,
end
,
ascending
,
fn
)
}
// ProcEvent handles supported events
func
(
kvmMavls
*
KVmMavlStore
)
ProcEvent
(
msg
*
queue
.
Message
)
{
msg
.
ReplyErr
(
"KVmMavlStore"
,
types
.
ErrActionNotSupport
)
}
// Del set kvs to nil with StateHash
func
(
kvmMavls
*
KVmMavlStore
)
Del
(
req
*
types
.
StoreDel
)
([]
byte
,
error
)
{
if
req
.
Height
<
kvmvccMavlFork
{
hash
,
err
:=
kvmMavls
.
MavlStore
.
Del
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
_
,
err
=
kvmMavls
.
KVMVCCStore
.
Del
(
req
)
if
err
!=
nil
{
return
hash
,
err
}
if
err
==
nil
{
kvmMavls
.
cache
.
Remove
(
string
(
req
.
StateHash
))
}
return
hash
,
err
}
// 仅仅做kvmvcc
hash
,
err
:=
kvmMavls
.
KVMVCCStore
.
Del
(
req
)
if
err
==
nil
{
kvmMavls
.
cache
.
Remove
(
string
(
req
.
StateHash
))
}
return
hash
,
err
}
// DelMavl 数据库中mavl数据清除
// 达到kvmvccMavlFork + 100000 后触发清除
func
DelMavl
(
db
dbm
.
DB
)
{
defer
wg
.
Done
()
setDelMavl
(
delMavlStateStart
)
defer
setDelMavl
(
delMavlStateEnd
)
isDel
:=
delMavlData
(
db
)
if
isDel
{
isDelMavlData
=
true
kmlog
.
Info
(
"DelMavl success"
)
}
}
func
delMavlData
(
db
dbm
.
DB
)
bool
{
it
:=
db
.
Iterator
(
nil
,
nil
,
true
)
defer
it
.
Close
()
batch
:=
db
.
NewBatch
(
true
)
for
it
.
Rewind
();
it
.
Valid
();
it
.
Next
()
{
if
quit
{
return
false
}
if
!
bytes
.
HasPrefix
(
it
.
Key
(),
mvccPrefix
)
{
// 将非mvcc的mavl数据全部删除
batch
.
Delete
(
it
.
Key
())
if
batch
.
ValueSize
()
>
batchDataSize
{
batch
.
Write
()
batch
.
Reset
()
time
.
Sleep
(
time
.
Millisecond
*
100
)
}
}
}
batch
.
Set
(
genDelMavlKey
(
mvccPrefix
),
[]
byte
(
""
))
batch
.
Write
()
return
true
}
func
genDelMavlKey
(
prefix
[]
byte
)
[]
byte
{
delMavl
:=
"--delMavlData--"
return
[]
byte
(
fmt
.
Sprintf
(
"%s%s"
,
string
(
prefix
),
delMavl
))
}
func
isDelMavling
()
bool
{
return
atomic
.
LoadInt32
(
&
delMavlDataState
)
==
1
}
func
setDelMavl
(
state
int32
)
{
atomic
.
StoreInt32
(
&
delMavlDataState
,
state
)
}
plugin/store/kvmvccmavl/kvmvcc_mavl_test.go
0 → 100644
View file @
b7699804
This diff is collapsed.
Click to expand it.
plugin/store/kvmvccmavl/kvmvccdb.go
0 → 100644
View file @
b7699804
This diff is collapsed.
Click to expand it.
plugin/store/kvmvccmavl/mavl.go
0 → 100644
View file @
b7699804
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
kvmvccmavl
import
(
"sync"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/system/store/mavl/db"
"github.com/33cn/chain33/types"
)
// MavlStore mavl store struct
type
MavlStore
struct
{
db
dbm
.
DB
trees
*
sync
.
Map
enableMavlPrefix
bool
enableMVCC
bool
enableMavlPrune
bool
pruneHeight
int32
}
// NewMavl new mavl store module
func
NewMavl
(
sub
*
subMavlConfig
,
db
dbm
.
DB
)
*
MavlStore
{
var
subcfg
subMavlConfig
if
sub
!=
nil
{
subcfg
.
EnableMavlPrefix
=
sub
.
EnableMavlPrefix
subcfg
.
EnableMVCC
=
sub
.
EnableMVCC
subcfg
.
EnableMavlPrune
=
sub
.
EnableMavlPrune
subcfg
.
PruneHeight
=
sub
.
PruneHeight
}
mavls
:=
&
MavlStore
{
db
,
&
sync
.
Map
{},
subcfg
.
EnableMavlPrefix
,
subcfg
.
EnableMVCC
,
subcfg
.
EnableMavlPrune
,
subcfg
.
PruneHeight
}
mavl
.
EnableMavlPrefix
(
subcfg
.
EnableMavlPrefix
)
mavl
.
EnableMVCC
(
subcfg
.
EnableMVCC
)
mavl
.
EnablePrune
(
subcfg
.
EnableMavlPrune
)
mavl
.
SetPruneHeight
(
int
(
subcfg
.
PruneHeight
))
return
mavls
}
// Close close mavl store
func
(
mavls
*
MavlStore
)
Close
()
{
mavl
.
ClosePrune
()
kmlog
.
Info
(
"store mavl closed"
)
}
// Set set k v to mavl store db; sync is true represent write sync
func
(
mavls
*
MavlStore
)
Set
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
return
mavl
.
SetKVPair
(
mavls
.
db
,
datas
,
sync
)
}
// Get get values by keys
func
(
mavls
*
MavlStore
)
Get
(
datas
*
types
.
StoreGet
)
[][]
byte
{
var
tree
*
mavl
.
Tree
var
err
error
values
:=
make
([][]
byte
,
len
(
datas
.
Keys
))
search
:=
string
(
datas
.
StateHash
)
if
data
,
ok
:=
mavls
.
trees
.
Load
(
search
);
ok
{
tree
=
data
.
(
*
mavl
.
Tree
)
}
else
{
tree
=
mavl
.
NewTree
(
mavls
.
db
,
true
)
//get接口也应该传入高度
//tree.SetBlockHeight(datas.Height)
err
=
tree
.
Load
(
datas
.
StateHash
)
kmlog
.
Debug
(
"store mavl get tree"
,
"err"
,
err
,
"StateHash"
,
common
.
ToHex
(
datas
.
StateHash
))
}
if
err
==
nil
{
for
i
:=
0
;
i
<
len
(
datas
.
Keys
);
i
++
{
_
,
value
,
exit
:=
tree
.
Get
(
datas
.
Keys
[
i
])
if
exit
{
values
[
i
]
=
value
}
}
}
return
values
}
// MemSet set keys values to memcory mavl, return root hash and error
func
(
mavls
*
MavlStore
)
MemSet
(
datas
*
types
.
StoreSet
,
sync
bool
)
([]
byte
,
error
)
{
beg
:=
types
.
Now
()
defer
func
()
{
kmlog
.
Info
(
"MemSet"
,
"cost"
,
types
.
Since
(
beg
))
}()
if
len
(
datas
.
KV
)
==
0
{
kmlog
.
Info
(
"store mavl memset,use preStateHash as stateHash for kvset is null"
)
mavls
.
trees
.
Store
(
string
(
datas
.
StateHash
),
nil
)
return
datas
.
StateHash
,
nil
}
tree
:=
mavl
.
NewTree
(
mavls
.
db
,
sync
)
tree
.
SetBlockHeight
(
datas
.
Height
)
err
:=
tree
.
Load
(
datas
.
StateHash
)
if
err
!=
nil
{
return
nil
,
err
}
for
i
:=
0
;
i
<
len
(
datas
.
KV
);
i
++
{
tree
.
Set
(
datas
.
KV
[
i
]
.
Key
,
datas
.
KV
[
i
]
.
Value
)
}
hash
:=
tree
.
Hash
()
mavls
.
trees
.
Store
(
string
(
hash
),
tree
)
return
hash
,
nil
}
// Commit convert memcory mavl to storage db
func
(
mavls
*
MavlStore
)
Commit
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
beg
:=
types
.
Now
()
defer
func
()
{
kmlog
.
Info
(
"Commit"
,
"cost"
,
types
.
Since
(
beg
))
}()
tree
,
ok
:=
mavls
.
trees
.
Load
(
string
(
req
.
Hash
))
if
!
ok
{
kmlog
.
Error
(
"store mavl commit"
,
"err"
,
types
.
ErrHashNotFound
)
return
nil
,
types
.
ErrHashNotFound
}
if
tree
==
nil
{
kmlog
.
Info
(
"store mavl commit,do nothing for kvset is null"
)
mavls
.
trees
.
Delete
(
string
(
req
.
Hash
))
return
req
.
Hash
,
nil
}
hash
:=
tree
.
(
*
mavl
.
Tree
)
.
Save
()
if
hash
==
nil
{
kmlog
.
Error
(
"store mavl commit"
,
"err"
,
types
.
ErrHashNotFound
)
return
nil
,
types
.
ErrDataBaseDamage
}
mavls
.
trees
.
Delete
(
string
(
req
.
Hash
))
return
req
.
Hash
,
nil
}
// Rollback 回退将缓存的mavl树删除掉
func
(
mavls
*
MavlStore
)
Rollback
(
req
*
types
.
ReqHash
)
([]
byte
,
error
)
{
beg
:=
types
.
Now
()
defer
func
()
{
kmlog
.
Info
(
"Rollback"
,
"cost"
,
types
.
Since
(
beg
))
}()
_
,
ok
:=
mavls
.
trees
.
Load
(
string
(
req
.
Hash
))
if
!
ok
{
kmlog
.
Error
(
"store mavl rollback"
,
"err"
,
types
.
ErrHashNotFound
)
return
nil
,
types
.
ErrHashNotFound
}
mavls
.
trees
.
Delete
(
string
(
req
.
Hash
))
return
req
.
Hash
,
nil
}
// IterateRangeByStateHash 迭代实现功能; statehash:当前状态hash, start:开始查找的key, end: 结束的key, ascending:升序,降序, fn 迭代回调函数
func
(
mavls
*
MavlStore
)
IterateRangeByStateHash
(
statehash
[]
byte
,
start
[]
byte
,
end
[]
byte
,
ascending
bool
,
fn
func
(
key
,
value
[]
byte
)
bool
)
{
mavl
.
IterateRangeByStateHash
(
mavls
.
db
,
statehash
,
start
,
end
,
ascending
,
fn
)
}
// ProcEvent not support message
func
(
mavls
*
MavlStore
)
ProcEvent
(
msg
queue
.
Message
)
{
msg
.
ReplyErr
(
"Store"
,
types
.
ErrActionNotSupport
)
}
// Del ...
func
(
mavls
*
MavlStore
)
Del
(
req
*
types
.
StoreDel
)
([]
byte
,
error
)
{
//not support
return
nil
,
nil
}
vendor/github.com/33cn/chain33/.travis.yml
View file @
b7699804
...
...
@@ -11,7 +11,7 @@ matrix:
-
name
:
check_fmt
sudo
:
require
go
:
-
"
1.
9
"
-
"
1.
11.x
"
-
master
install
:
-
go get -u golang.org/x/tools/cmd/goimports
...
...
vendor/github.com/33cn/chain33/account/account.go
View file @
b7699804
...
...
@@ -472,3 +472,40 @@ func (acc *DB) mintReceipt(kv []*types.KeyValue, receipt proto.Message) *types.R
Logs
:
[]
*
types
.
ReceiptLog
{
log1
},
}
}
// Burn 然收
func
(
acc
*
DB
)
Burn
(
addr
string
,
amount
int64
)
(
*
types
.
Receipt
,
error
)
{
if
!
types
.
CheckAmount
(
amount
)
{
return
nil
,
types
.
ErrAmount
}
accTo
:=
acc
.
LoadAccount
(
addr
)
if
accTo
.
Balance
<
amount
{
return
nil
,
types
.
ErrNoBalance
}
copyAcc
:=
*
accTo
accTo
.
Balance
=
accTo
.
Balance
-
amount
receipt
:=
&
types
.
ReceiptAccountBurn
{
Prev
:
&
copyAcc
,
Current
:
accTo
,
}
kv
:=
acc
.
GetKVSet
(
accTo
)
acc
.
SaveKVSet
(
kv
)
return
acc
.
burnReceipt
(
kv
,
receipt
),
nil
}
func
(
acc
*
DB
)
burnReceipt
(
kv
[]
*
types
.
KeyValue
,
receipt
proto
.
Message
)
*
types
.
Receipt
{
ty
:=
int32
(
types
.
TyLogBurn
)
log1
:=
&
types
.
ReceiptLog
{
Ty
:
ty
,
Log
:
types
.
Encode
(
receipt
),
}
return
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
[]
*
types
.
ReceiptLog
{
log1
},
}
}
vendor/github.com/33cn/chain33/account/account_test.go
View file @
b7699804
...
...
@@ -591,3 +591,13 @@ func TestDB_Mint(t *testing.T) {
t
.
Logf
(
"Token mint addr balance [%d]"
,
tokenCoin
.
LoadAccount
(
addr1
)
.
Balance
)
require
.
Equal
(
t
,
int64
(
1000
*
1e8
+
10
*
1e8
),
tokenCoin
.
LoadAccount
(
addr1
)
.
Balance
)
}
func
TestDB_Burn
(
t
*
testing
.
T
)
{
_
,
tokenCoin
:=
GenerAccDb
()
tokenCoin
.
GenerAccData
()
_
,
err
:=
tokenCoin
.
Burn
(
addr1
,
10
*
1e8
)
require
.
NoError
(
t
,
err
)
t
.
Logf
(
"Token mint addr balance [%d]"
,
tokenCoin
.
LoadAccount
(
addr1
)
.
Balance
)
require
.
Equal
(
t
,
int64
(
1000
*
1e8
-
10
*
1e8
),
tokenCoin
.
LoadAccount
(
addr1
)
.
Balance
)
}
vendor/github.com/33cn/chain33/cmd/chain33/bityuan.toml
View file @
b7699804
...
...
@@ -90,6 +90,10 @@ enableMVCC=false
enableMavlPrune
=
false
# 裁剪高度间隔
pruneHeight
=
10000
# 是否使能mavl数据载入内存
enableMemTree
=
false
# 是否使能mavl叶子节点数据载入内存
enableMemVal
=
false
[wallet]
# walletdb路径
...
...
vendor/github.com/33cn/chain33/cmd/chain33/chain33.test.toml
View file @
b7699804
...
...
@@ -144,6 +144,10 @@ enableMavlPrefix=false
enableMVCC
=
false
enableMavlPrune
=
false
pruneHeight
=
10000
# 是否使能mavl数据载入内存
enableMemTree
=
false
# 是否使能mavl叶子节点数据载入内存
enableMemVal
=
false
[wallet]
minFee
=
1000000
...
...
vendor/github.com/33cn/chain33/cmd/chain33/chain33.toml
View file @
b7699804
...
...
@@ -210,6 +210,10 @@ enableMVCC=false
enableMavlPrune
=
false
# 裁剪高度间隔
pruneHeight
=
10000
# 是否使能mavl数据载入内存
enableMemTree
=
false
# 是否使能mavl叶子节点数据载入内存
enableMemVal
=
false
[wallet]
# 交易发送最低手续费,单位0.00000001BTY(1e-8),默认100000,即0.001BTY
...
...
vendor/github.com/33cn/chain33/executor/execenv.go
View file @
b7699804
...
...
@@ -203,11 +203,24 @@ func (e *executor) Exec(tx *types.Transaction, index int) (*types.Receipt, error
if
err
:=
drivers
.
CheckAddress
(
tx
.
GetRealToAddr
(),
e
.
height
);
err
!=
nil
{
return
nil
,
err
}
if
e
.
localDB
!=
nil
{
e
.
localDB
.
(
*
LocalDB
)
.
DisableWrite
()
if
exec
.
ExecutorOrder
()
!=
drivers
.
ExecLocalSameTime
{
e
.
localDB
.
(
*
LocalDB
)
.
DisableRead
()
}
defer
func
()
{
e
.
localDB
.
(
*
LocalDB
)
.
EnableWrite
()
if
exec
.
ExecutorOrder
()
!=
drivers
.
ExecLocalSameTime
{
e
.
localDB
.
(
*
LocalDB
)
.
EnableRead
()
}
}()
}
//第一步先检查 CheckTx
if
err
:=
exec
.
CheckTx
(
tx
,
index
);
err
!=
nil
{
return
nil
,
err
}
return
exec
.
Exec
(
tx
,
index
)
r
,
err
:=
exec
.
Exec
(
tx
,
index
)
return
r
,
err
}
func
(
e
*
executor
)
execLocal
(
tx
*
types
.
Transaction
,
r
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
...
...
vendor/github.com/33cn/chain33/executor/executor_real_test.go
View file @
b7699804
...
...
@@ -312,7 +312,10 @@ func (demo *demoApp) Exec(tx *types.Transaction, index int) (receipt *types.Rece
}
if
seterrkey
{
println
(
"set err key value"
)
demo
.
GetLocalDB
()
.
Set
([]
byte
(
"key1"
),
[]
byte
(
"value1"
))
err
=
demo
.
GetLocalDB
()
.
Set
([]
byte
(
"key1"
),
[]
byte
(
"value1"
))
if
err
!=
nil
{
return
nil
,
err
}
}
receipt
=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
}
receipt
.
KV
=
append
(
receipt
.
KV
,
&
types
.
KeyValue
{
...
...
@@ -401,11 +404,14 @@ func TestExecLocalSameTime0(t *testing.T) {
return
}
for
i
,
receipt
:=
range
detail
.
Receipts
{
assert
.
Equal
(
t
,
receipt
.
GetTy
(),
int32
(
2
),
fmt
.
Sprint
(
i
))
if
i
==
0
{
assert
.
Equal
(
t
,
receipt
.
GetTy
(),
int32
(
2
),
fmt
.
Sprint
(
i
))
}
if
i
>=
1
{
assert
.
Equal
(
t
,
receipt
.
GetTy
(),
int32
(
1
),
fmt
.
Sprint
(
i
))
fmt
.
Println
(
receipt
)
assert
.
Equal
(
t
,
len
(
receipt
.
Logs
),
2
)
assert
.
Equal
(
t
,
receipt
.
Logs
[
1
]
.
Ty
,
int32
(
0
))
assert
.
Equal
(
t
,
receipt
.
Logs
[
1
]
.
Ty
,
int32
(
1
))
}
}
}
...
...
vendor/github.com/33cn/chain33/executor/executor_test.go
View file @
b7699804
...
...
@@ -5,6 +5,7 @@
package
executor
import
(
"fmt"
"testing"
"time"
...
...
@@ -198,5 +199,6 @@ func TestExecutorErrAPIEnv(t *testing.T) {
msg
:=
queue
.
NewMessage
(
0
,
""
,
1
,
txlist
)
exec
.
procExecTxList
(
msg
)
_
,
err
:=
exec
.
client
.
WaitTimeout
(
msg
,
100
*
time
.
Second
)
fmt
.
Println
(
err
)
assert
.
Equal
(
t
,
true
,
api
.
IsAPIEnvError
(
err
))
}
vendor/github.com/33cn/chain33/executor/localdb.go
View file @
b7699804
...
...
@@ -12,15 +12,17 @@ import (
//数据的get set 主要经过 cache
//如果需要进行list, 那么把get set 的内容加入到 后端数据库
type
LocalDB
struct
{
cache
map
[
string
][]
byte
txcache
map
[
string
][]
byte
keys
[]
string
intx
bool
hasbegin
bool
kvs
[]
*
types
.
KeyValue
txid
*
types
.
Int64
client
queue
.
Client
api
client
.
QueueProtocolAPI
cache
map
[
string
][]
byte
txcache
map
[
string
][]
byte
keys
[]
string
intx
bool
hasbegin
bool
kvs
[]
*
types
.
KeyValue
txid
*
types
.
Int64
client
queue
.
Client
api
client
.
QueueProtocolAPI
disableread
bool
disablewrite
bool
}
//NewLocalDB 创建一个新的LocalDB
...
...
@@ -41,6 +43,26 @@ func NewLocalDB(cli queue.Client) db.KVDB {
}
}
//DisableRead 禁止读取LocalDB数据库
func
(
l
*
LocalDB
)
DisableRead
()
{
l
.
disableread
=
true
}
//DisableWrite 禁止写LocalDB数据库
func
(
l
*
LocalDB
)
DisableWrite
()
{
l
.
disablewrite
=
true
}
//EnableRead 启动读取LocalDB数据库
func
(
l
*
LocalDB
)
EnableRead
()
{
l
.
disableread
=
false
}
//EnableWrite 启动写LocalDB数据库
func
(
l
*
LocalDB
)
EnableWrite
()
{
l
.
disablewrite
=
false
}
func
(
l
*
LocalDB
)
resetTx
()
{
l
.
intx
=
false
l
.
txcache
=
nil
...
...
@@ -128,6 +150,9 @@ func (l *LocalDB) Rollback() {
//Get 获取key
func
(
l
*
LocalDB
)
Get
(
key
[]
byte
)
([]
byte
,
error
)
{
if
l
.
disableread
{
return
nil
,
types
.
ErrDisableRead
}
skey
:=
string
(
key
)
if
l
.
intx
&&
l
.
txcache
!=
nil
{
if
value
,
ok
:=
l
.
txcache
[
skey
];
ok
{
...
...
@@ -160,6 +185,9 @@ func (l *LocalDB) Get(key []byte) ([]byte, error) {
//Set 获取key
func
(
l
*
LocalDB
)
Set
(
key
[]
byte
,
value
[]
byte
)
error
{
if
l
.
disablewrite
{
return
types
.
ErrDisableWrite
}
skey
:=
string
(
key
)
if
l
.
intx
{
if
l
.
txcache
==
nil
{
...
...
@@ -176,6 +204,9 @@ func (l *LocalDB) Set(key []byte, value []byte) error {
// List 从数据库中查询数据列表
func
(
l
*
LocalDB
)
List
(
prefix
,
key
[]
byte
,
count
,
direction
int32
)
([][]
byte
,
error
)
{
if
l
.
disableread
{
return
nil
,
types
.
ErrDisableRead
}
err
:=
l
.
save
()
if
err
!=
nil
{
return
nil
,
err
...
...
vendor/github.com/33cn/chain33/executor/localdb_test.go
View file @
b7699804
...
...
@@ -18,6 +18,34 @@ func TestLocalDBGet(t *testing.T) {
testDBGet
(
t
,
db
)
}
func
TestLocalDBEnable
(
t
*
testing
.
T
)
{
mock33
:=
testnode
.
New
(
""
,
nil
)
defer
mock33
.
Close
()
db
:=
executor
.
NewLocalDB
(
mock33
.
GetClient
())
ldb
:=
db
.
(
*
executor
.
LocalDB
)
defer
ldb
.
Close
()
_
,
err
:=
ldb
.
Get
([]
byte
(
"hello"
))
assert
.
Equal
(
t
,
err
,
types
.
ErrNotFound
)
ldb
.
DisableRead
()
_
,
err
=
ldb
.
Get
([]
byte
(
"hello"
))
assert
.
Equal
(
t
,
err
,
types
.
ErrDisableRead
)
_
,
err
=
ldb
.
List
(
nil
,
nil
,
0
,
0
)
assert
.
Equal
(
t
,
err
,
types
.
ErrDisableRead
)
ldb
.
EnableRead
()
_
,
err
=
ldb
.
Get
([]
byte
(
"hello"
))
assert
.
Equal
(
t
,
err
,
types
.
ErrNotFound
)
_
,
err
=
ldb
.
List
(
nil
,
nil
,
0
,
0
)
assert
.
Equal
(
t
,
err
,
nil
)
ldb
.
DisableWrite
()
err
=
ldb
.
Set
([]
byte
(
"hello"
),
nil
)
assert
.
Equal
(
t
,
err
,
types
.
ErrDisableWrite
)
ldb
.
EnableWrite
()
err
=
ldb
.
Set
([]
byte
(
"hello"
),
nil
)
assert
.
Equal
(
t
,
err
,
nil
)
}
func
BenchmarkLocalDBGet
(
b
*
testing
.
B
)
{
mock33
:=
testnode
.
New
(
""
,
nil
)
defer
mock33
.
Close
()
...
...
vendor/github.com/33cn/chain33/system/dapp/manage/types/types.go
View file @
b7699804
...
...
@@ -20,7 +20,7 @@ var (
}
logmap
=
map
[
int64
]
*
types
.
LogInfo
{
// 这里reflect.TypeOf类型必须是proto.Message类型,且是交易的回持结构
TyLogModifyConfig
:
{
reflect
.
TypeOf
(
types
.
ReceiptConfig
{}),
"LogModifyConfig"
},
TyLogModifyConfig
:
{
Ty
:
reflect
.
TypeOf
(
types
.
ReceiptConfig
{}),
Name
:
"LogModifyConfig"
},
}
)
...
...
vendor/github.com/33cn/chain33/system/store/mavl/db/memmavl.go
0 → 100644
View file @
b7699804
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package
mavl
import
(
"fmt"
"time"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
farm
"github.com/dgryski/go-farm"
"github.com/hashicorp/golang-lru"
)
// MemTreeOpera memtree操作接口
type
MemTreeOpera
interface
{
Add
(
key
,
value
interface
{})
Get
(
key
interface
{})
(
value
interface
{},
ok
bool
)
Delete
(
key
interface
{})
Contains
(
key
interface
{})
bool
Len
()
int
}
// TreeMap map形式memtree
type
TreeMap
struct
{
mpCache
map
[
interface
{}]
interface
{}
}
// NewTreeMap new mem tree
func
NewTreeMap
(
size
int
)
*
TreeMap
{
mp
:=
&
TreeMap
{}
mp
.
mpCache
=
make
(
map
[
interface
{}]
interface
{},
size
)
return
mp
}
// Add 添加元素
func
(
tm
*
TreeMap
)
Add
(
key
,
value
interface
{})
{
if
_
,
ok
:=
tm
.
mpCache
[
key
];
ok
{
delete
(
tm
.
mpCache
,
key
)
return
}
tm
.
mpCache
[
key
]
=
value
}
// Get 获取元素
func
(
tm
*
TreeMap
)
Get
(
key
interface
{})
(
value
interface
{},
ok
bool
)
{
if
value
,
ok
:=
tm
.
mpCache
[
key
];
ok
{
return
value
,
ok
}
return
nil
,
false
}
// Delete 删除元素
func
(
tm
*
TreeMap
)
Delete
(
key
interface
{})
{
if
_
,
ok
:=
tm
.
mpCache
[
key
];
ok
{
delete
(
tm
.
mpCache
,
key
)
}
}
// Contains 查看是否包含元素
func
(
tm
*
TreeMap
)
Contains
(
key
interface
{})
bool
{
if
_
,
ok
:=
tm
.
mpCache
[
key
];
ok
{
return
true
}
return
false
}
// Len 元素长度
func
(
tm
*
TreeMap
)
Len
()
int
{
return
len
(
tm
.
mpCache
)
}
// TreeARC lru的mem tree
type
TreeARC
struct
{
arcCache
*
lru
.
ARCCache
}
// NewTreeARC new lru mem tree
func
NewTreeARC
(
size
int
)
*
TreeARC
{
ma
:=
&
TreeARC
{}
ma
.
arcCache
,
_
=
lru
.
NewARC
(
size
)
return
ma
}
// Add 添加元素
func
(
ta
*
TreeARC
)
Add
(
key
,
value
interface
{})
{
if
ta
.
arcCache
.
Contains
(
key
)
{
ta
.
arcCache
.
Remove
(
key
)
return
}
ta
.
arcCache
.
Add
(
key
,
value
)
}
// Get 获取元素
func
(
ta
*
TreeARC
)
Get
(
key
interface
{})
(
value
interface
{},
ok
bool
)
{
return
ta
.
arcCache
.
Get
(
key
)
}
// Delete 删除元素
func
(
ta
*
TreeARC
)
Delete
(
key
interface
{})
{
ta
.
arcCache
.
Remove
(
key
)
}
// Contains 查看是否包含元素
func
(
ta
*
TreeARC
)
Contains
(
key
interface
{})
bool
{
return
ta
.
arcCache
.
Contains
(
key
)
}
// Len 元素长度
func
(
ta
*
TreeARC
)
Len
()
int
{
return
ta
.
arcCache
.
Len
()
}
// LoadTree2MemDb 从数据库中载入mem tree
func
LoadTree2MemDb
(
db
dbm
.
DB
,
hash
[]
byte
,
mp
map
[
uint64
]
struct
{})
{
nDb
:=
newNodeDB
(
db
,
true
)
node
,
err
:=
nDb
.
getLightNode
(
nil
,
hash
)
if
err
!=
nil
{
fmt
.
Println
(
"err"
,
err
)
return
}
pri
:=
""
if
len
(
node
.
hash
)
>
32
{
pri
=
string
(
node
.
hash
[
:
16
])
}
treelog
.
Info
(
"hash node"
,
"hash pri"
,
pri
,
"hash"
,
common
.
ToHex
(
node
.
hash
),
"height"
,
node
.
height
)
start
:=
time
.
Now
()
leftHash
:=
make
([]
byte
,
len
(
node
.
leftHash
))
copy
(
leftHash
,
node
.
leftHash
)
rightHash
:=
make
([]
byte
,
len
(
node
.
rightHash
))
copy
(
rightHash
,
node
.
rightHash
)
mp
[
farm
.
Hash64
(
node
.
hash
)]
=
struct
{}{}
node
.
loadNodeInfo
(
nDb
,
mp
)
end
:=
time
.
Now
()
treelog
.
Info
(
"hash node"
,
"cost time"
,
end
.
Sub
(
start
),
"node count"
,
len
(
mp
))
PrintMemStats
(
1
)
}
func
(
node
*
Node
)
loadNodeInfo
(
db
*
nodeDB
,
mp
map
[
uint64
]
struct
{})
{
if
node
.
height
==
0
{
//trMem.Add(Hash64(node.hash), &hashNode{leftHash: node.leftHash, rightHash: node.rightHash})
leftHash
:=
make
([]
byte
,
len
(
node
.
leftHash
))
copy
(
leftHash
,
node
.
leftHash
)
rightHash
:=
make
([]
byte
,
len
(
node
.
rightHash
))
copy
(
rightHash
,
node
.
rightHash
)
mp
[
farm
.
Hash64
(
node
.
hash
)]
=
struct
{}{}
return
}
if
node
.
leftHash
!=
nil
{
left
,
err
:=
db
.
getLightNode
(
nil
,
node
.
leftHash
)
if
err
!=
nil
{
return
}
//trMem.Add(Hash64(left.hash), &hashNode{leftHash: left.leftHash, rightHash: left.rightHash})
leftHash
:=
make
([]
byte
,
len
(
left
.
leftHash
))
copy
(
leftHash
,
left
.
leftHash
)
rightHash
:=
make
([]
byte
,
len
(
left
.
rightHash
))
copy
(
rightHash
,
left
.
rightHash
)
mp
[
farm
.
Hash64
(
left
.
hash
)]
=
struct
{}{}
left
.
loadNodeInfo
(
db
,
mp
)
}
if
node
.
rightHash
!=
nil
{
right
,
err
:=
db
.
getLightNode
(
nil
,
node
.
rightHash
)
if
err
!=
nil
{
return
}
//trMem.Add(Hash64(right.hash), &hashNode{leftHash: right.leftHash, rightHash: right.rightHash})
leftHash
:=
make
([]
byte
,
len
(
right
.
leftHash
))
copy
(
leftHash
,
right
.
leftHash
)
rightHash
:=
make
([]
byte
,
len
(
right
.
rightHash
))
copy
(
rightHash
,
right
.
rightHash
)
mp
[
farm
.
Hash64
(
right
.
hash
)]
=
struct
{}{}
right
.
loadNodeInfo
(
db
,
mp
)
}
}
func
(
ndb
*
nodeDB
)
getLightNode
(
t
*
Tree
,
hash
[]
byte
)
(
*
Node
,
error
)
{
// Doesn't exist, load from db.
var
buf
[]
byte
buf
,
err
:=
ndb
.
db
.
Get
(
hash
)
if
len
(
buf
)
==
0
||
err
!=
nil
{
return
nil
,
ErrNodeNotExist
}
node
,
err
:=
MakeNode
(
buf
,
t
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"Error reading IAVLNode. bytes: %X error: %v"
,
buf
,
err
))
}
node
.
hash
=
hash
node
.
key
=
nil
node
.
value
=
nil
return
node
,
nil
}
func
copyBytes
(
b
[]
byte
)
(
copiedBytes
[]
byte
)
{
if
b
==
nil
{
return
nil
}
copiedBytes
=
make
([]
byte
,
len
(
b
))
copy
(
copiedBytes
,
b
)
return
copiedBytes
}
vendor/github.com/33cn/chain33/system/store/mavl/db/node.go
View file @
b7699804
...
...
@@ -11,6 +11,7 @@ import (
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
farm
"github.com/dgryski/go-farm"
"github.com/golang/protobuf/proto"
)
...
...
@@ -499,6 +500,9 @@ func removeOrphan(t *Tree, node *Node) {
if
t
.
ndb
==
nil
{
return
}
if
enableMemTree
&&
t
!=
nil
{
t
.
obsoleteNode
[
uintkey
(
farm
.
Hash64
(
node
.
hash
))]
=
struct
{}{}
}
t
.
ndb
.
RemoveNode
(
t
,
node
)
}
...
...
vendor/github.com/33cn/chain33/system/store/mavl/db/tree.go
View file @
b7699804
...
...
@@ -15,6 +15,7 @@ import (
dbm
"github.com/33cn/chain33/common/db"
log
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/types"
farm
"github.com/dgryski/go-farm"
"github.com/golang/protobuf/proto"
"github.com/hashicorp/golang-lru"
)
...
...
@@ -37,6 +38,10 @@ var (
// 当前树的最大高度
maxBlockHeight
int64
heightMtx
sync
.
Mutex
//
enableMemTree
bool
memTree
MemTreeOpera
enableMemVal
bool
)
// EnableMavlPrefix 使能mavl加前缀
...
...
@@ -49,23 +54,53 @@ func EnableMVCC(enable bool) {
enableMvcc
=
enable
}
// EnableMemTree 使能mavl数据载入内存
func
EnableMemTree
(
enable
bool
)
{
enableMemTree
=
enable
}
// EnableMemVal 使能mavl叶子节点数据载入内存
func
EnableMemVal
(
enable
bool
)
{
enableMemVal
=
enable
}
type
memNode
struct
{
data
[][]
byte
//顺序为lefthash, righthash, key, value
Height
int32
Size
int32
}
type
uintkey
uint64
// Tree merkle avl tree
type
Tree
struct
{
root
*
Node
ndb
*
nodeDB
blockHeight
int64
// 树更新之后,废弃的节点(更新缓存中节点先对旧节点进行删除然后再更新)
obsoleteNode
map
[
uintkey
]
struct
{}
updateNode
map
[
uintkey
]
*
memNode
}
// NewTree 新建一个merkle avl 树
func
NewTree
(
db
dbm
.
DB
,
sync
bool
)
*
Tree
{
if
db
==
nil
{
// In-memory IAVLTree
return
&
Tree
{}
return
&
Tree
{
obsoleteNode
:
make
(
map
[
uintkey
]
struct
{}),
updateNode
:
make
(
map
[
uintkey
]
*
memNode
),
}
}
// Persistent IAVLTree
ndb
:=
newNodeDB
(
db
,
sync
)
// 使能情况下非空创建当前整tree的缓存
if
enableMemTree
&&
memTree
==
nil
{
memTree
=
NewTreeMap
(
50
*
10000
)
}
return
&
Tree
{
ndb
:
ndb
,
ndb
:
ndb
,
obsoleteNode
:
make
(
map
[
uintkey
]
struct
{}),
updateNode
:
make
(
map
[
uintkey
]
*
memNode
),
}
}
...
...
@@ -116,13 +151,17 @@ func (t *Tree) Has(key []byte) bool {
func
(
t
*
Tree
)
Set
(
key
[]
byte
,
value
[]
byte
)
(
updated
bool
)
{
//treelog.Info("IAVLTree.Set", "key", key, "value",value)
if
t
.
root
==
nil
{
t
.
root
=
NewNode
(
key
,
value
)
t
.
root
=
NewNode
(
copyBytes
(
key
),
copyBytes
(
value
)
)
return
false
}
t
.
root
,
updated
=
t
.
root
.
set
(
t
,
key
,
value
)
t
.
root
,
updated
=
t
.
root
.
set
(
t
,
copyBytes
(
key
),
copyBytes
(
value
)
)
return
updated
}
func
(
t
*
Tree
)
getObsoleteNode
()
map
[
uintkey
]
struct
{}
{
return
t
.
obsoleteNode
}
// Hash 计算tree 的roothash
func
(
t
*
Tree
)
Hash
()
[]
byte
{
if
t
.
root
==
nil
{
...
...
@@ -148,6 +187,17 @@ func (t *Tree) Save() []byte {
if
enablePrune
{
t
.
root
.
saveRootHash
(
t
)
}
// 更新memTree
if
enableMemTree
&&
memTree
!=
nil
{
for
k
:=
range
t
.
obsoleteNode
{
memTree
.
Delete
(
k
)
}
for
k
,
v
:=
range
t
.
updateNode
{
memTree
.
Add
(
k
,
v
)
}
treelog
.
Debug
(
"Tree.Save"
,
"memTree len"
,
memTree
.
Len
(),
"tree height"
,
t
.
blockHeight
)
}
beg
:=
types
.
Now
()
err
:=
t
.
ndb
.
Commit
()
treelog
.
Info
(
"tree.commit"
,
"cost"
,
types
.
Since
(
beg
))
...
...
@@ -395,6 +445,13 @@ func (ndb *nodeDB) GetNode(t *Tree, hash []byte) (*Node, error) {
return
elem
.
(
*
Node
),
nil
}
}
//从memtree中获取
if
enableMemTree
{
node
,
err
:=
getNode4MemTree
(
hash
)
if
err
==
nil
{
return
node
,
nil
}
}
// Doesn't exist, load from db.
var
buf
[]
byte
buf
,
err
:=
ndb
.
db
.
Get
(
hash
)
...
...
@@ -409,6 +466,10 @@ func (ndb *nodeDB) GetNode(t *Tree, hash []byte) (*Node, error) {
node
.
hash
=
hash
node
.
persisted
=
true
ndb
.
cacheNode
(
node
)
// Save node hashInt64 to memTree
if
enableMemTree
{
updateGlobalMemTree
(
node
)
}
return
node
,
nil
}
...
...
@@ -459,6 +520,85 @@ func (ndb *nodeDB) SaveNode(t *Tree, node *Node) {
ndb
.
cacheNode
(
node
)
delete
(
ndb
.
orphans
,
string
(
node
.
hash
))
//treelog.Debug("SaveNode", "hash", node.hash, "height", node.height, "value", node.value)
// Save node hashInt64 to localmem
if
enableMemTree
{
updateLocalMemTree
(
t
,
node
)
}
}
func
getNode4MemTree
(
hash
[]
byte
)
(
*
Node
,
error
)
{
if
memTree
==
nil
{
return
nil
,
ErrNodeNotExist
}
elem
,
ok
:=
memTree
.
Get
(
uintkey
(
farm
.
Hash64
(
hash
)))
if
ok
{
sn
:=
elem
.
(
*
memNode
)
node
:=
&
Node
{
height
:
sn
.
Height
,
size
:
sn
.
Size
,
hash
:
hash
,
persisted
:
true
,
}
node
.
leftHash
=
sn
.
data
[
0
]
node
.
rightHash
=
sn
.
data
[
1
]
node
.
key
=
sn
.
data
[
2
]
if
len
(
sn
.
data
)
==
4
{
node
.
value
=
sn
.
data
[
3
]
}
return
node
,
nil
}
return
nil
,
ErrNodeNotExist
}
// Save node hashInt64 to memTree
func
updateGlobalMemTree
(
node
*
Node
)
{
if
node
==
nil
||
memTree
==
nil
{
return
}
if
!
enableMemVal
&&
node
.
height
==
0
{
return
}
memN
:=
&
memNode
{
Height
:
node
.
height
,
Size
:
node
.
size
,
}
if
node
.
height
==
0
{
memN
.
data
=
make
([][]
byte
,
4
)
memN
.
data
[
3
]
=
node
.
value
}
else
{
memN
.
data
=
make
([][]
byte
,
3
)
}
memN
.
data
[
0
]
=
node
.
leftHash
memN
.
data
[
1
]
=
node
.
rightHash
memN
.
data
[
2
]
=
node
.
key
memTree
.
Add
(
uintkey
(
farm
.
Hash64
(
node
.
hash
)),
memN
)
}
// Save node hashInt64 to localmem
func
updateLocalMemTree
(
t
*
Tree
,
node
*
Node
)
{
if
t
==
nil
||
node
==
nil
{
return
}
if
!
enableMemVal
&&
node
.
height
==
0
{
return
}
if
t
.
updateNode
!=
nil
{
memN
:=
&
memNode
{
Height
:
node
.
height
,
Size
:
node
.
size
,
}
if
node
.
height
==
0
{
memN
.
data
=
make
([][]
byte
,
4
)
memN
.
data
[
3
]
=
node
.
value
}
else
{
memN
.
data
=
make
([][]
byte
,
3
)
}
memN
.
data
[
0
]
=
node
.
leftHash
memN
.
data
[
1
]
=
node
.
rightHash
memN
.
data
[
2
]
=
node
.
key
t
.
updateNode
[
uintkey
(
farm
.
Hash64
(
node
.
hash
))]
=
memN
//treelog.Debug("Tree.SaveNode", "store struct size", unsafe.Sizeof(store), "byte size", len(storenode), "height", node.height)
}
}
//cache缓存节点
...
...
vendor/github.com/33cn/chain33/system/store/mavl/db/tree_test.go
View file @
b7699804
...
...
@@ -15,6 +15,8 @@ import (
"sync"
"testing"
"unsafe"
.
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/log"
...
...
@@ -1255,6 +1257,89 @@ func TestDelLeafCountKV(t *testing.T) {
}
}
func
TestGetObsoleteNode
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"datastore"
)
require
.
NoError
(
t
,
err
)
t
.
Log
(
dir
)
defer
os
.
Remove
(
dir
)
EnableMemTree
(
true
)
EnableMemVal
(
true
)
defer
EnableMemTree
(
false
)
defer
EnableMemVal
(
false
)
db
:=
db
.
NewDB
(
"mavltree"
,
"leveldb"
,
dir
,
100
)
tree
:=
NewTree
(
db
,
true
)
type
record
struct
{
key
string
value
string
}
records
:=
[]
record
{
{
"abc"
,
"abc"
},
{
"low"
,
"low"
},
{
"fan"
,
"fan"
},
}
for
_
,
r
:=
range
records
{
updated
:=
tree
.
Set
([]
byte
(
r
.
key
),
[]
byte
(
r
.
value
))
if
updated
{
t
.
Error
(
"should have not been updated"
)
}
}
hash
:=
tree
.
Save
()
obs
:=
tree
.
getObsoleteNode
()
require
.
Equal
(
t
,
0
,
len
(
obs
))
mp
:=
make
(
map
[
uint64
]
struct
{})
LoadTree2MemDb
(
db
,
hash
,
mp
)
tree1
:=
NewTree
(
db
,
true
)
tree1
.
Load
(
hash
)
records1
:=
[]
record
{
{
"abc"
,
"abc1"
},
{
"low"
,
"low1"
},
{
"fan"
,
"fan1"
},
}
for
_
,
r
:=
range
records1
{
tree1
.
Set
([]
byte
(
r
.
key
),
[]
byte
(
r
.
value
))
}
hash1
:=
tree1
.
Save
()
obs
=
tree1
.
getObsoleteNode
()
mp1
:=
make
(
map
[
uint64
]
struct
{})
LoadTree2MemDb
(
db
,
hash1
,
mp1
)
require
.
Equal
(
t
,
len
(
mp
),
len
(
obs
))
//做了全部更新,因此旧节点全部删除
for
ob
:=
range
obs
{
_
,
ok
:=
mp
[
uint64
(
ob
)]
if
!
ok
{
require
.
Error
(
t
,
fmt
.
Errorf
(
"should exist"
))
}
}
tree2
:=
NewTree
(
db
,
true
)
tree2
.
Load
(
hash
)
records2
:=
[]
record
{
{
"fan"
,
"fan1"
},
{
"foo"
,
"foo"
},
{
"foobaz"
,
"foobaz"
},
{
"good"
,
"good"
},
}
for
_
,
r
:=
range
records2
{
tree2
.
Set
([]
byte
(
r
.
key
),
[]
byte
(
r
.
value
))
}
hash2
:=
tree2
.
Save
()
obs
=
tree2
.
getObsoleteNode
()
mp2
:=
make
(
map
[
uint64
]
struct
{})
LoadTree2MemDb
(
db
,
hash2
,
mp2
)
//require.Equal(t, 0, len(obs))
for
ob
:=
range
obs
{
_
,
ok
:=
mp
[
uint64
(
ob
)]
if
!
ok
{
require
.
Error
(
t
,
fmt
.
Errorf
(
"should exist"
))
}
}
}
func
TestPruningFirstLevelNode
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"datastore"
)
require
.
NoError
(
t
,
err
)
...
...
@@ -1899,3 +1984,64 @@ func saveBlock(dbm db.DB, height int64, hash []byte, txN int64, mvcc bool) (newH
}
return
newHash
,
nil
}
func
TestSize1
(
t
*
testing
.
T
)
{
type
storeNode
struct
{
Key
[]
byte
Value
[]
byte
LeftHash
[]
byte
RightHash
[]
byte
Height
int32
Size
int32
}
type
storeNode1
struct
{
Key
[][]
byte
Height
int32
Size
int32
}
a
:=
types
.
StoreNode
{}
b
:=
storeNode
{}
var
c
[]
byte
d
:=
storeNode1
{}
//arcmp := NewTreeMap(350 * 10000)
//if arcmp == nil {
// return
//}
//for i := 0; i < 300*10000; i++ {
// data := &storeNode{
// Key: []byte("12345678901234567890123456789012"),
// Value: []byte("12345678901234567890123456789012"),
// LeftHash: []byte("12345678901234567890123456789012"),
// RightHash: []byte("12345678901234567890123456789012"),
// //Key: copyBytes([]byte("12345678901234567890123456789012")),
// //Value: copyBytes([]byte("12345678901234567890123456789012")),
// //LeftHash: copyBytes([]byte("12345678901234567890123456789012")),
// //RightHash: copyBytes([]byte("12345678901234567890123456789012")),
// Height: 123,
// Size: 123,
// }
// arcmp.Add(int64(i), data)
//}
//for i := 0; i < 100*10000; i++ {
// data := &storeNode1{}
// data.Height = 123
// data.Size = 123
// d.Key = make([][]byte, 4)
// //d.Key[0] = []byte("12345678901234567890123456789012")
// //d.Key[1] = []byte("12345678901234567890123456789012")
// //d.Key[2] = []byte("12345678901234567890123456789012")
// //d.Key[3] = []byte("12345678901234567890123456789012")
//
// d.Key[0] = copyBytes([]byte("12345678901234567890123456789012"))
// d.Key[1] = copyBytes([]byte("12345678901234567890123456789012"))
// d.Key[2] = copyBytes([]byte("12345678901234567890123456789012"))
// d.Key[3] = copyBytes([]byte("12345678901234567890123456789012"))
// arcmp.Add(int64(i), data)
//}
PrintMemStats
(
1
)
fmt
.
Println
(
unsafe
.
Sizeof
(
a
),
unsafe
.
Sizeof
(
b
),
unsafe
.
Sizeof
(
c
),
unsafe
.
Sizeof
(
d
),
len
(
d
.
Key
),
cap
(
d
.
Key
))
}
vendor/github.com/33cn/chain33/system/store/mavl/mavl.go
View file @
b7699804
...
...
@@ -37,6 +37,8 @@ type Store struct {
enableMVCC
bool
enableMavlPrune
bool
pruneHeight
int32
enableMemTree
bool
enableMemVal
bool
}
func
init
()
{
...
...
@@ -51,6 +53,10 @@ type subConfig struct {
EnableMavlPrune
bool
`json:"enableMavlPrune"`
// 裁剪高度间隔
PruneHeight
int32
`json:"pruneHeight"`
// 是否使能内存树
EnableMemTree
bool
`json:"enableMemTree"`
// 是否使能内存树中叶子节点
EnableMemVal
bool
`json:"enableMemVal"`
}
// New new mavl store module
...
...
@@ -60,15 +66,20 @@ func New(cfg *types.Store, sub []byte) queue.Module {
if
sub
!=
nil
{
types
.
MustDecode
(
sub
,
&
subcfg
)
}
mavls
:=
&
Store
{
bs
,
&
sync
.
Map
{},
subcfg
.
EnableMavlPrefix
,
subcfg
.
EnableMVCC
,
subcfg
.
EnableMavlPrune
,
subcfg
.
PruneHeight
}
mavls
:=
&
Store
{
bs
,
&
sync
.
Map
{},
subcfg
.
EnableMavlPrefix
,
subcfg
.
EnableMVCC
,
subcfg
.
EnableMavlPrune
,
subcfg
.
PruneHeight
,
subcfg
.
EnableMemTree
,
subcfg
.
EnableMemVal
}
mavls
.
enableMavlPrefix
=
subcfg
.
EnableMavlPrefix
mavls
.
enableMVCC
=
subcfg
.
EnableMVCC
mavls
.
enableMavlPrune
=
subcfg
.
EnableMavlPrune
mavls
.
pruneHeight
=
subcfg
.
PruneHeight
mavls
.
enableMemTree
=
subcfg
.
EnableMemTree
mavls
.
enableMemVal
=
subcfg
.
EnableMemVal
mavl
.
EnableMavlPrefix
(
mavls
.
enableMavlPrefix
)
mavl
.
EnableMVCC
(
mavls
.
enableMVCC
)
mavl
.
EnablePrune
(
mavls
.
enableMavlPrune
)
mavl
.
SetPruneHeight
(
int
(
mavls
.
pruneHeight
))
mavl
.
EnableMemTree
(
mavls
.
enableMemTree
)
mavl
.
EnableMemVal
(
mavls
.
enableMemVal
)
bs
.
SetChild
(
mavls
)
return
mavls
}
...
...
vendor/github.com/33cn/chain33/types/account.pb.go
View file @
b7699804
...
...
@@ -248,6 +248,53 @@ func (m *ReceiptAccountMint) GetCurrent() *Account {
return
nil
}
type
ReceiptAccountBurn
struct
{
Prev
*
Account
`protobuf:"bytes,1,opt,name=prev,proto3" json:"prev,omitempty"`
Current
*
Account
`protobuf:"bytes,2,opt,name=current,proto3" json:"current,omitempty"`
XXX_NoUnkeyedLiteral
struct
{}
`json:"-"`
XXX_unrecognized
[]
byte
`json:"-"`
XXX_sizecache
int32
`json:"-"`
}
func
(
m
*
ReceiptAccountBurn
)
Reset
()
{
*
m
=
ReceiptAccountBurn
{}
}
func
(
m
*
ReceiptAccountBurn
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReceiptAccountBurn
)
ProtoMessage
()
{}
func
(
*
ReceiptAccountBurn
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
4
}
}
func
(
m
*
ReceiptAccountBurn
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
return
xxx_messageInfo_ReceiptAccountBurn
.
Unmarshal
(
m
,
b
)
}
func
(
m
*
ReceiptAccountBurn
)
XXX_Marshal
(
b
[]
byte
,
deterministic
bool
)
([]
byte
,
error
)
{
return
xxx_messageInfo_ReceiptAccountBurn
.
Marshal
(
b
,
m
,
deterministic
)
}
func
(
m
*
ReceiptAccountBurn
)
XXX_Merge
(
src
proto
.
Message
)
{
xxx_messageInfo_ReceiptAccountBurn
.
Merge
(
m
,
src
)
}
func
(
m
*
ReceiptAccountBurn
)
XXX_Size
()
int
{
return
xxx_messageInfo_ReceiptAccountBurn
.
Size
(
m
)
}
func
(
m
*
ReceiptAccountBurn
)
XXX_DiscardUnknown
()
{
xxx_messageInfo_ReceiptAccountBurn
.
DiscardUnknown
(
m
)
}
var
xxx_messageInfo_ReceiptAccountBurn
proto
.
InternalMessageInfo
func
(
m
*
ReceiptAccountBurn
)
GetPrev
()
*
Account
{
if
m
!=
nil
{
return
m
.
Prev
}
return
nil
}
func
(
m
*
ReceiptAccountBurn
)
GetCurrent
()
*
Account
{
if
m
!=
nil
{
return
m
.
Current
}
return
nil
}
//查询一个地址列表在某个执行器中余额
type
ReqBalance
struct
{
//地址列表
...
...
@@ -266,7 +313,7 @@ func (m *ReqBalance) Reset() { *m = ReqBalance{} }
func
(
m
*
ReqBalance
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqBalance
)
ProtoMessage
()
{}
func
(
*
ReqBalance
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
4
}
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
5
}
}
func
(
m
*
ReqBalance
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
...
...
@@ -334,7 +381,7 @@ func (m *Accounts) Reset() { *m = Accounts{} }
func
(
m
*
Accounts
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
Accounts
)
ProtoMessage
()
{}
func
(
*
Accounts
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
5
}
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
6
}
}
func
(
m
*
Accounts
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
...
...
@@ -374,7 +421,7 @@ func (m *ExecAccount) Reset() { *m = ExecAccount{} }
func
(
m
*
ExecAccount
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ExecAccount
)
ProtoMessage
()
{}
func
(
*
ExecAccount
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
6
}
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
7
}
}
func
(
m
*
ExecAccount
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
...
...
@@ -421,7 +468,7 @@ func (m *AllExecBalance) Reset() { *m = AllExecBalance{} }
func
(
m
*
AllExecBalance
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
AllExecBalance
)
ProtoMessage
()
{}
func
(
*
AllExecBalance
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
7
}
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
8
}
}
func
(
m
*
AllExecBalance
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
...
...
@@ -473,7 +520,7 @@ func (m *ReqAllExecBalance) Reset() { *m = ReqAllExecBalance{} }
func
(
m
*
ReqAllExecBalance
)
String
()
string
{
return
proto
.
CompactTextString
(
m
)
}
func
(
*
ReqAllExecBalance
)
ProtoMessage
()
{}
func
(
*
ReqAllExecBalance
)
Descriptor
()
([]
byte
,
[]
int
)
{
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
8
}
return
fileDescriptor_8e28828dcb8d24f0
,
[]
int
{
9
}
}
func
(
m
*
ReqAllExecBalance
)
XXX_Unmarshal
(
b
[]
byte
)
error
{
...
...
@@ -534,6 +581,7 @@ func init() {
proto
.
RegisterType
((
*
ReceiptExecAccountTransfer
)(
nil
),
"types.ReceiptExecAccountTransfer"
)
proto
.
RegisterType
((
*
ReceiptAccountTransfer
)(
nil
),
"types.ReceiptAccountTransfer"
)
proto
.
RegisterType
((
*
ReceiptAccountMint
)(
nil
),
"types.ReceiptAccountMint"
)
proto
.
RegisterType
((
*
ReceiptAccountBurn
)(
nil
),
"types.ReceiptAccountBurn"
)
proto
.
RegisterType
((
*
ReqBalance
)(
nil
),
"types.ReqBalance"
)
proto
.
RegisterType
((
*
Accounts
)(
nil
),
"types.Accounts"
)
proto
.
RegisterType
((
*
ExecAccount
)(
nil
),
"types.ExecAccount"
)
...
...
@@ -544,32 +592,33 @@ func init() {
func
init
()
{
proto
.
RegisterFile
(
"account.proto"
,
fileDescriptor_8e28828dcb8d24f0
)
}
var
fileDescriptor_8e28828dcb8d24f0
=
[]
byte
{
// 427 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xc4
,
0x54
,
0xcd
,
0x6a
,
0x14
,
0x41
,
0x10
,
0xa6
,
0xf7
,
0x27
,
0x9b
,
0xa9
,
0xd5
,
0x80
,
0x7d
,
0x08
,
0x4d
,
0x30
,
0x38
,
0xf6
,
0x69
,
0x0e
,
0xb2
,
0x0b
,
0x8e
,
0x2f
,
0x90
,
0x80
,
0xe0
,
0x45
,
0x84
,
0xd6
,
0x53
,
0x2e
,
0xd2
,
0xd3
,
0xa9
,
0x75
,
0x07
,
0x27
,
0x3d
,
0x93
,
0xee
,
0x5e
,
0x71
,
0x7d
,
0x00
,
0x5f
,
0x43
,
0xf0
,
0x49
,
0xa5
,
0x6b
,
0x7b
,
0xb2
,
0xb3
,
0x06
,
0x25
,
0x07
,
0xc1
,
0xdb
,
0xd4
,
0xf7
,
0x55
,
0xd5
,
0xf7
,
0x75
,
0x55
,
0x31
,
0xf0
,
0x58
,
0x1b
,
0xd3
,
0x6e
,
0x6c
,
0x58
,
0x74
,
0xae
,
0x0d
,
0x2d
,
0x9f
,
0x86
,
0x6d
,
0x87
,
0x5e
,
0x7e
,
0x86
,
0xd9
,
0xc5
,
0x0e
,
0xe7
,
0x67
,
0x70
,
0x6c
,
0x36
,
0xce
,
0xa1
,
0x35
,
0x5b
,
0xc1
,
0x72
,
0x56
,
0x4c
,
0xd5
,
0x5d
,
0xcc
,
0x05
,
0xcc
,
0x2a
,
0xdd
,
0x68
,
0x6b
,
0x50
,
0x8c
,
0x72
,
0x56
,
0x8c
,
0x55
,
0x1f
,
0xf2
,
0x53
,
0x38
,
0x5a
,
0xb9
,
0xf6
,
0x1b
,
0x5a
,
0x31
,
0x26
,
0x22
,
0x45
,
0x9c
,
0xc3
,
0x44
,
0x5f
,
0x5f
,
0x3b
,
0x31
,
0xc9
,
0x59
,
0x91
,
0x29
,
0xfa
,
0x96
,
0xdf
,
0x19
,
0x9c
,
0x29
,
0x34
,
0x58
,
0x77
,
0xe1
,
0xf5
,
0x57
,
0x34
,
0x49
,
0xf8
,
0x83
,
0xd3
,
0xd6
,
0xaf
,
0xd0
,
0x45
,
0x03
,
0x18
,
0xe1
,
0x58
,
0xc6
,
0xa8
,
0xec
,
0x2e
,
0xe6
,
0x12
,
0x26
,
0x9d
,
0xc3
,
0x2f
,
0xa4
,
0x3e
,
0x7f
,
0x79
,
0xb2
,
0x20
,
0xf7
,
0x8b
,
0xd4
,
0x41
,
0x11
,
0xc7
,
0x0b
,
0x98
,
0xed
,
0x0c
,
0x07
,
0xf2
,
0x72
,
0x3f
,
0xad
,
0xa7
,
0xe5
,
0x0a
,
0x4e
,
0x93
,
0x8f
,
0xdf
,
0x3d
,
0xf4
,
0x3a
,
0xec
,
0x61
,
0x3a
,
0xa3
,
0xbf
,
0xeb
,
0x54
,
0xc0
,
0x0f
,
0x75
,
0xde
,
0xd6
,
0x36
,
0xfc
,
0x63
,
0x8d
,
0x9f
,
0x0c
,
0x40
,
0xe1
,
0xed
,
0x65
,
0xda
,
0xc7
,
0x53
,
0xc8
,
0xe2
,
0xac
,
0xd1
,
0x7b
,
0xf4
,
0x82
,
0xe5
,
0xe3
,
0x22
,
0x53
,
0x7b
,
0x20
,
0x6e
,
0x2b
,
0x8e
,
0x14
,
0x1d
,
0x75
,
0xcd
,
0x54
,
0x8a
,
0x62
,
0x95
,
0x0f
,
0x3a
,
0xe0
,
0x1b
,
0xed
,
0xd7
,
0x34
,
0xbc
,
0x4c
,
0xed
,
0x01
,
0x7e
,
0x0e
,
0xa0
,
0xbd
,
0xc7
,
0xf0
,
0x31
,
0x66
,
0xa7
,
0x8d
,
0x66
,
0x84
,
0xc4
,
0x35
,
0xf2
,
0xe7
,
0xf0
,
0x68
,
0x47
,
0xfb
,
0xed
,
0x4d
,
0xd5
,
0x36
,
0x62
,
0x4a
,
0x09
,
0x73
,
0xc2
,
0xde
,
0x13
,
0x24
,
0x5f
,
0xc0
,
0x71
,
0x32
,
0xee
,
0x79
,
0x0e
,
0x63
,
0x6d
,
0x0c
,
0x79
,
0xbb
,
0xff
,
0xac
,
0x48
,
0xc9
,
0x77
,
0x30
,
0x1f
,
0xdc
,
0xc7
,
0xc0
,
0x34
,
0x3b
,
0x30
,
0x5d
,
0xc0
,
0x2c
,
0xdd
,
0xf4
,
0x9f
,
0x66
,
0x94
,
0x68
,
0x79
,
0x05
,
0x27
,
0x17
,
0x4d
,
0x13
,
0x7b
,
0xf6
,
0x63
,
0xea
,
0xcf
,
0x93
,
0xed
,
0xcf
,
0x93
,
0xbf
,
0x3a
,
0x90
,
0x15
,
0x23
,
0x32
,
0xc8
,
0x53
,
0xcf
,
0x01
,
0xa3
,
0x86
,
0x69
,
0xf2
,
0x07
,
0x83
,
0x27
,
0x0a
,
0x6f
,
0x1f
,
0xd0
,
0xff
,
0x3f
,
0x0d
,
0xff
,
0xf2
,
0xd9
,
0xd5
,
0xf9
,
0xa7
,
0x3a
,
0xac
,
0x37
,
0xd5
,
0xc2
,
0xb4
,
0x37
,
0xcb
,
0xb2
,
0x34
,
0x76
,
0x69
,
0xd6
,
0xba
,
0xb6
,
0x65
,
0xb9
,
0xa4
,
0xb7
,
0x55
,
0x47
,
0xf4
,
0x4b
,
0x28
,
0x7f
,
0x05
,
0x00
,
0x00
,
0xff
,
0xff
,
0x1b
,
0xce
,
0xc2
,
0x14
,
0x23
,
0x04
,
0x00
,
0x00
,
// 434 bytes of a gzipped FileDescriptorProto
0x1f
,
0x8b
,
0x08
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0xff
,
0xc4
,
0x54
,
0xcd
,
0x6e
,
0x13
,
0x31
,
0x10
,
0x96
,
0xf3
,
0xd3
,
0x74
,
0x27
,
0x50
,
0x09
,
0x1f
,
0x2a
,
0xab
,
0xa2
,
0x62
,
0xf1
,
0x69
,
0x0f
,
0x28
,
0x91
,
0x58
,
0x5e
,
0xa0
,
0x91
,
0x90
,
0xb8
,
0x20
,
0x24
,
0xc3
,
0xa9
,
0x17
,
0xe4
,
0x75
,
0x27
,
0x24
,
0x22
,
0xf5
,
0x6e
,
0x6d
,
0x2f
,
0x22
,
0x3c
,
0x00
,
0xaf
,
0x81
,
0xc4
,
0x93
,
0x22
,
0x4f
,
0xbc
,
0xcd
,
0x86
,
0x0a
,
0xd4
,
0x03
,
0xa8
,
0xb7
,
0x9d
,
0xef
,
0x1b
,
0xcf
,
0xf7
,
0xd9
,
0x33
,
0xb3
,
0xf0
,
0x58
,
0x1b
,
0x53
,
0xb7
,
0x36
,
0xcc
,
0x1a
,
0x57
,
0x87
,
0x9a
,
0x8f
,
0xc3
,
0xb6
,
0x41
,
0x2f
,
0x3f
,
0xc3
,
0xe4
,
0x62
,
0x87
,
0xf3
,
0x33
,
0x38
,
0x36
,
0xad
,
0x73
,
0x68
,
0xcd
,
0x56
,
0xb0
,
0x9c
,
0x15
,
0x63
,
0x75
,
0x1b
,
0x73
,
0x01
,
0x93
,
0x4a
,
0x6f
,
0xb4
,
0x35
,
0x28
,
0x06
,
0x39
,
0x2b
,
0x86
,
0xaa
,
0x0b
,
0xf9
,
0x29
,
0x1c
,
0x2d
,
0x5d
,
0xfd
,
0x0d
,
0xad
,
0x18
,
0x12
,
0x91
,
0x22
,
0xce
,
0x61
,
0xa4
,
0xaf
,
0xae
,
0x9c
,
0x18
,
0xe5
,
0xac
,
0xc8
,
0x14
,
0x7d
,
0xcb
,
0xef
,
0x0c
,
0xce
,
0x14
,
0x1a
,
0x5c
,
0x37
,
0xe1
,
0xf5
,
0x57
,
0x34
,
0x49
,
0xf8
,
0x83
,
0xd3
,
0xd6
,
0x2f
,
0xd1
,
0x45
,
0x03
,
0x18
,
0xe1
,
0x78
,
0x8c
,
0xd1
,
0xb1
,
0xdb
,
0x98
,
0x4b
,
0x18
,
0x35
,
0x0e
,
0xbf
,
0x90
,
0xfa
,
0xf4
,
0xe5
,
0xc9
,
0x8c
,
0xdc
,
0xcf
,
0x52
,
0x05
,
0x45
,
0x1c
,
0x2f
,
0x60
,
0xb2
,
0x33
,
0x1c
,
0xc8
,
0xcb
,
0xdd
,
0xb4
,
0x8e
,
0x96
,
0x4b
,
0x38
,
0x4d
,
0x3e
,
0x7e
,
0xf7
,
0xd0
,
0xe9
,
0xb0
,
0xfb
,
0xe9
,
0x0c
,
0xfe
,
0xae
,
0x53
,
0x01
,
0x3f
,
0xd4
,
0x79
,
0xbb
,
0xb6
,
0xe1
,
0x7f
,
0x6b
,
0x2c
,
0x5a
,
0x67
,
0xff
,
0xb1
,
0xc6
,
0x4f
,
0x06
,
0xa0
,
0xf0
,
0x66
,
0x91
,
0x7a
,
0xfe
,
0x14
,
0xb2
,
0xd8
,
0x4f
,
0xf4
,
0x1e
,
0xbd
,
0x60
,
0xf9
,
0xb0
,
0xc8
,
0xd4
,
0x1e
,
0x88
,
0x13
,
0x11
,
0xdb
,
0x86
,
0x8e
,
0xaa
,
0x66
,
0x2a
,
0x45
,
0xf1
,
0x94
,
0x0f
,
0x3a
,
0xe0
,
0x1b
,
0xed
,
0x57
,
0xd4
,
0xa0
,
0x4c
,
0xed
,
0x01
,
0x7e
,
0x0e
,
0xa0
,
0xbd
,
0xc7
,
0xf0
,
0x31
,
0x66
,
0xa7
,
0xa9
,
0xc9
,
0x08
,
0x89
,
0xa3
,
0xc2
,
0x9f
,
0xc3
,
0xa3
,
0x1d
,
0xed
,
0xb7
,
0xd7
,
0x55
,
0xbd
,
0x11
,
0x63
,
0x4a
,
0x98
,
0x12
,
0xf6
,
0x9e
,
0x20
,
0xf9
,
0x02
,
0x8e
,
0x93
,
0x71
,
0xcf
,
0x73
,
0x18
,
0x6a
,
0x63
,
0xc8
,
0xdb
,
0xdd
,
0x6b
,
0x45
,
0x4a
,
0xbe
,
0x83
,
0x69
,
0x6f
,
0x06
,
0x7b
,
0xa6
,
0xd9
,
0x81
,
0xe9
,
0x02
,
0x26
,
0x69
,
0x6f
,
0xfe
,
0xf4
,
0x46
,
0x89
,
0x96
,
0x97
,
0x70
,
0x72
,
0xb1
,
0xd9
,
0xc4
,
0x9a
,
0xdd
,
0x33
,
0x75
,
0x2b
,
0xc0
,
0xf6
,
0x2b
,
0xc0
,
0x5f
,
0x1d
,
0xc8
,
0x8a
,
0x01
,
0x19
,
0xe4
,
0xa9
,
0x66
,
0x8f
,
0x51
,
0xfd
,
0x34
,
0xf9
,
0x83
,
0xc1
,
0x13
,
0x85
,
0x37
,
0xf7
,
0xa8
,
0xff
,
0x40
,
0x8f
,
0xbf
,
0x78
,
0x76
,
0x79
,
0xfe
,
0x69
,
0x1d
,
0x56
,
0x6d
,
0x35
,
0x33
,
0xf5
,
0xf5
,
0xbc
,
0x2c
,
0x8d
,
0x9d
,
0x9b
,
0x95
,
0x5e
,
0xdb
,
0xb2
,
0x9c
,
0xd3
,
0xdd
,
0xaa
,
0x23
,
0xfa
,
0xed
,
0x94
,
0xbf
,
0x02
,
0x00
,
0x00
,
0xff
,
0xff
,
0x57
,
0xdf
,
0x86
,
0xd3
,
0x87
,
0x04
,
0x00
,
0x00
,
}
vendor/github.com/33cn/chain33/types/const.go
View file @
b7699804
...
...
@@ -104,6 +104,7 @@ const (
TyLogGenesisDeposit
=
12
TyLogRollback
=
13
TyLogMint
=
14
TyLogBurn
=
15
)
//SystemLog 系统log日志
...
...
@@ -121,6 +122,8 @@ var SystemLog = map[int64]*LogInfo{
TyLogGenesisTransfer
:
{
reflect
.
TypeOf
(
ReceiptAccountTransfer
{}),
"LogGenesisTransfer"
},
TyLogGenesisDeposit
:
{
reflect
.
TypeOf
(
ReceiptAccountTransfer
{}),
"LogGenesisDeposit"
},
TyLogRollback
:
{
reflect
.
TypeOf
(
LocalDBSet
{}),
"LogRollback"
},
TyLogMint
:
{
reflect
.
TypeOf
(
ReceiptAccountMint
{}),
"LogMint"
},
TyLogBurn
:
{
reflect
.
TypeOf
(
ReceiptAccountBurn
{}),
"LogBurn"
},
}
//exec type
...
...
vendor/github.com/33cn/chain33/types/error.go
View file @
b7699804
...
...
@@ -181,4 +181,7 @@ var (
ErrHeightOverflow
=
errors
.
New
(
"ErrHeightOverflow"
)
ErrRecordBlockSequence
=
errors
.
New
(
"ErrRecordBlockSequence"
)
ErrExecPanic
=
errors
.
New
(
"ErrExecPanic"
)
ErrDisableWrite
=
errors
.
New
(
"ErrDisableWrite"
)
ErrDisableRead
=
errors
.
New
(
"ErrDisableRead"
)
)
vendor/github.com/33cn/chain33/types/proto/account.proto
View file @
b7699804
...
...
@@ -41,6 +41,11 @@ message ReceiptAccountMint {
Account
current
=
2
;
}
message
ReceiptAccountBurn
{
Account
prev
=
1
;
Account
current
=
2
;
}
//查询一个地址列表在某个执行器中余额
message
ReqBalance
{
//地址列表
...
...
vendor/github.com/33cn/chain33/util/exec.go
View file @
b7699804
...
...
@@ -205,25 +205,17 @@ func ReportErrEventToFront(logger log.Logger, client queue.Client, frommodule st
//DelDupKey 删除重复的key
func
DelDupKey
(
kvs
[]
*
types
.
KeyValue
)
[]
*
types
.
KeyValue
{
dupindex
:=
make
(
map
[
string
]
int
)
hasdup
:=
false
for
i
,
kv
:=
range
kvs
{
n
:=
0
for
_
,
kv
:=
range
kvs
{
skey
:=
string
(
kv
.
Key
)
if
index
,
ok
:=
dupindex
[
skey
];
ok
{
hasdup
=
true
kvs
[
index
]
=
nil
}
dupindex
[
skey
]
=
i
}
//没有重复的情况下,不需要重新处理
if
!
hasdup
{
return
kvs
}
index
:=
0
for
_
,
kv
:=
range
kvs
{
if
kv
!=
nil
{
//重复的key 替换老的key
kvs
[
index
]
=
kv
index
++
}
else
{
dupindex
[
skey
]
=
n
kvs
[
n
]
=
kv
n
++
}
}
return
kvs
[
0
:
index
]
return
kvs
[
0
:
n
]
}
vendor/github.com/33cn/chain33/util/util.go
View file @
b7699804
...
...
@@ -225,8 +225,9 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
//通过consensus module 再次检查
ulog
.
Debug
(
"ExecBlock"
,
"height------->"
,
block
.
Height
,
"ntx"
,
len
(
block
.
Txs
))
beg
:=
types
.
Now
()
beg2
:=
beg
defer
func
()
{
ulog
.
Info
(
"ExecBlock"
,
"height"
,
block
.
Height
,
"ntx"
,
len
(
block
.
Txs
),
"writebatchsync"
,
sync
,
"cost"
,
types
.
Since
(
beg
))
ulog
.
Info
(
"ExecBlock"
,
"height"
,
block
.
Height
,
"ntx"
,
len
(
block
.
Txs
),
"writebatchsync"
,
sync
,
"cost"
,
types
.
Since
(
beg
2
))
}()
if
errReturn
&&
block
.
Height
>
0
&&
!
block
.
CheckSign
()
{
...
...
@@ -330,7 +331,6 @@ func ExecBlock(client queue.Client, prevStateRoot []byte, block *types.Block, er
}
}
ulog
.
Info
(
"ExecBlock"
,
"CheckBlock"
,
types
.
Since
(
beg
))
beg
=
types
.
Now
()
// 写数据库失败时需要及时返回错误,防止错误数据被写入localdb中CHAIN33-567
err
=
ExecKVSetCommit
(
client
,
block
.
StateHash
)
if
err
!=
nil
{
...
...
vendor/github.com/33cn/chain33/util/util_test.go
View file @
b7699804
...
...
@@ -144,8 +144,8 @@ func TestDelDupKey(t *testing.T) {
{
Key
:
[]
byte
(
"hello"
),
Value
:
[]
byte
(
"world2"
)},
}
result
:=
[]
*
types
.
KeyValue
{
{
Key
:
[]
byte
(
"hello1"
),
Value
:
[]
byte
(
"world"
)},
{
Key
:
[]
byte
(
"hello"
),
Value
:
[]
byte
(
"world2"
)},
{
Key
:
[]
byte
(
"hello1"
),
Value
:
[]
byte
(
"world"
)},
}
kvs
=
DelDupKey
(
kvs
)
assert
.
Equal
(
t
,
kvs
,
result
)
...
...
@@ -173,6 +173,7 @@ func BenchmarkDelDupKey(b *testing.B) {
kvs
=
append
(
kvs
,
&
types
.
KeyValue
{
Key
:
key
,
Value
:
value
})
}
}
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
testkv
:=
make
([]
*
types
.
KeyValue
,
len
(
kvs
))
copy
(
testkv
,
kvs
)
...
...
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