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
c22e26c7
Unverified
Commit
c22e26c7
authored
Dec 11, 2019
by
lyh169
Committed by
GitHub
Dec 11, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into compact_del_store
parents
974114fb
88e98f0f
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
57 changed files
with
1954 additions
and
75 deletions
+1954
-75
dapp-test-common.sh
build/dapp-test-common.sh
+5
-1
dapp-test-rpc.sh
build/dapp-test-rpc.sh
+6
-5
chain33.para.toml
chain33.para.toml
+1
-0
go.mod
go.mod
+1
-1
go.sum
go.sum
+2
-2
init.go
plugin/dapp/init/init.go
+1
-0
oracle_test.go
plugin/dapp/oracle/executor/oracle_test.go
+0
-0
Dockerfile
plugin/dapp/paracross/cmd/scripts/autodeploy/Dockerfile
+10
-0
Makefile
plugin/dapp/paracross/cmd/scripts/autodeploy/Makefile
+17
-0
config
plugin/dapp/paracross/cmd/scripts/autodeploy/config
+40
-0
docker-compose.sh
...n/dapp/paracross/cmd/scripts/autodeploy/docker-compose.sh
+267
-0
docker-compose.yml
.../dapp/paracross/cmd/scripts/autodeploy/docker-compose.yml
+4
-0
entrypoint.sh
plugin/dapp/paracross/cmd/scripts/autodeploy/entrypoint.sh
+2
-0
test-rpc.sh
plugin/dapp/paracross/cmd/test/test-rpc.sh
+0
-0
paracross.go
plugin/dapp/paracross/commands/paracross.go
+30
-0
action.go
plugin/dapp/paracross/executor/action.go
+70
-25
asset.go
plugin/dapp/paracross/executor/asset.go
+18
-0
exec_local.go
plugin/dapp/paracross/executor/exec_local.go
+1
-0
query.go
plugin/dapp/paracross/executor/query.go
+32
-7
paracross.proto
plugin/dapp/paracross/proto/paracross.proto
+19
-1
rpc.go
plugin/dapp/paracross/rpc/rpc.go
+3
-3
rpc_test.go
plugin/dapp/paracross/rpc/rpc_test.go
+4
-4
paracross.pb.go
plugin/dapp/paracross/types/paracross.pb.go
+0
-0
type.go
plugin/dapp/paracross/types/type.go
+4
-0
Makefile
plugin/dapp/storage/cmd/Makefile
+3
-0
build.sh
plugin/dapp/storage/cmd/build.sh
+11
-0
commands.go
plugin/dapp/storage/commands/commands.go
+23
-0
aes.go
plugin/dapp/storage/crypto/aes.go
+47
-0
aes_test.go
plugin/dapp/storage/crypto/aes_test.go
+23
-0
crypto.go
plugin/dapp/storage/crypto/crypto.go
+33
-0
des.go
plugin/dapp/storage/crypto/des.go
+84
-0
des_test.go
plugin/dapp/storage/crypto/des_test.go
+59
-0
exec.go
plugin/dapp/storage/executor/exec.go
+36
-0
exec_del_local.go
plugin/dapp/storage/executor/exec_del_local.go
+20
-0
exec_local.go
plugin/dapp/storage/executor/exec_local.go
+49
-0
kv.go
plugin/dapp/storage/executor/kv.go
+21
-0
query.go
plugin/dapp/storage/executor/query.go
+16
-0
storage.go
plugin/dapp/storage/executor/storage.go
+58
-0
storage_test.go
plugin/dapp/storage/executor/storage_test.go
+326
-0
storagedb.go
plugin/dapp/storage/executor/storagedb.go
+108
-0
plugin.go
plugin/dapp/storage/plugin.go
+23
-0
Makefile
plugin/dapp/storage/proto/Makefile
+2
-0
create_protobuf.sh
plugin/dapp/storage/proto/create_protobuf.sh
+4
-0
storage.proto
plugin/dapp/storage/proto/storage.proto
+94
-0
rpc.go
plugin/dapp/storage/rpc/rpc.go
+7
-0
types.go
plugin/dapp/storage/rpc/types.go
+34
-0
storage.go
plugin/dapp/storage/types/storage.go
+102
-0
storage.pb.go
plugin/dapp/storage/types/storage.pb.go
+0
-0
ticket.go
plugin/dapp/ticket/commands/ticket.go
+36
-0
exec_test.go
plugin/dapp/ticket/executor/exec_test.go
+119
-0
ticket_test.go
plugin/dapp/ticket/executor/ticket_test.go
+3
-1
ticketdb.go
plugin/dapp/ticket/executor/ticketdb.go
+11
-11
rpc.go
plugin/dapp/ticket/rpc/rpc.go
+28
-4
rpc_test.go
plugin/dapp/ticket/rpc/rpc_test.go
+9
-0
ticket.go
plugin/dapp/ticket/types/ticket.go
+12
-0
ticket.go
plugin/dapp/ticket/wallet/ticket.go
+3
-3
ticket_test.go
plugin/dapp/ticket/wallet/ticket_test.go
+13
-7
No files found.
build/dapp-test-common.sh
View file @
c22e26c7
...
@@ -116,8 +116,12 @@ chain33_SignRawTx() {
...
@@ -116,8 +116,12 @@ chain33_SignRawTx() {
local
txHex
=
"
$1
"
local
txHex
=
"
$1
"
local
priKey
=
"
$2
"
local
priKey
=
"
$2
"
local
MAIN_HTTP
=
$3
local
MAIN_HTTP
=
$3
local
expire
=
"120s"
if
[
-n
"
$4
"
]
;
then
expire
=
$4
fi
local
req
=
'"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$priKey
"
'","txHex":"'
"
$txHex
"
'","expire":"
120s
"}]'
local
req
=
'"method":"Chain33.SignRawTx","params":[{"privkey":"'
"
$priKey
"
'","txHex":"'
"
$txHex
"
'","expire":"
'
"
$expire
"
'
"}]'
signedTx
=
$(
curl
-ksd
"{
$req
}"
"
${
MAIN_HTTP
}
"
| jq
-r
".result"
)
signedTx
=
$(
curl
-ksd
"{
$req
}"
"
${
MAIN_HTTP
}
"
| jq
-r
".result"
)
if
[
"
$signedTx
"
!=
null
]
;
then
if
[
"
$signedTx
"
!=
null
]
;
then
...
...
build/dapp-test-rpc.sh
View file @
c22e26c7
...
@@ -10,17 +10,18 @@ function dapp_test_rpc() {
...
@@ -10,17 +10,18 @@ function dapp_test_rpc() {
if
[
-d
dapptest
]
;
then
if
[
-d
dapptest
]
;
then
cp
"
$DAPP_TEST_COMMON
"
dapptest/
cp
"
$DAPP_TEST_COMMON
"
dapptest/
cd
dapptest
||
return
cd
dapptest
||
return
rm
-f
"retries.log"
rm
-f
"jobs.log"
rm
-f
"jobs.log"
rm
-rf
"outdir"
dapps
=
$(
find
.
-maxdepth
1
-type
d
!
-name
dapptest
!
-name
.
|
sed
's/^\.\///'
|
sort
)
dapps
=
$(
find
.
-maxdepth
1
-type
d
!
-name
dapptest
!
-name
.
|
sed
's/^\.\///'
|
sort
)
echo
"dapps list:
$dapps
"
echo
"dapps list:
$dapps
"
set
+e
set
+e
parallel
-k
--
joblog
./jobs.log
'echo tried {} >>./retries.log; ./{}/"'
"
${
RPC_TESTFILE
}
"
'" "'
"
$ip
"
'"'
:::
"
$dapps
"
parallel
-k
--
results
outdir
--joblog
./jobs.log ./
{}
/
"
${
RPC_TESTFILE
}
"
"
$ip
"
:::
"
$dapps
"
local
ret
=
$?
local
ret
=
$?
# retries 3 times if one dapp fail
if
[
$ret
-ne
0
]
;
then
echo
"============ # retried dapps log: ============="
wrongdapps
=
$(
awk
'{print $7,$9 }'
jobs.log |
grep
-a
1 |
awk
-F
'/'
'{print $2}'
)
cat
./retries.log
parallel
-k
'cat ./outdir/1/{}/stderr; cat ./outdir/1/{}/stdout'
:::
"
$wrongdapps
"
fi
echo
"============ # check dapps test log: ============="
echo
"============ # check dapps test log: ============="
cat
./jobs.log
cat
./jobs.log
set
-e
set
-e
...
...
chain33.para.toml
View file @
c22e26c7
...
@@ -255,6 +255,7 @@ ForkParacrossCommitTx=0
...
@@ -255,6 +255,7 @@ ForkParacrossCommitTx=0
ForkLoopCheckCommitTxDone
=
0
ForkLoopCheckCommitTxDone
=
0
#平行链分阶段自共识支持合约配置,缺省是0
#平行链分阶段自共识支持合约配置,缺省是0
ForkParaSelfConsStages
=
0
ForkParaSelfConsStages
=
0
ForkParaAssetTransferRbk
=
0
[fork.sub.evm]
[fork.sub.evm]
Enable
=
0
Enable
=
0
...
...
go.mod
View file @
c22e26c7
...
@@ -3,7 +3,7 @@ module github.com/33cn/plugin
...
@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
go 1.12
require (
require (
github.com/33cn/chain33 v0.0.0-20191
126060956-6354775a8a5d
github.com/33cn/chain33 v0.0.0-20191
206075140-7c09cb251660
github.com/BurntSushi/toml v0.3.1
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/Sia v1.3.7
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac
...
...
go.sum
View file @
c22e26c7
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/33cn/chain33 v0.0.0-20191
126060956-6354775a8a5d h1:O23Rws82Z7xtnMMEXWh96tmfGcH3z7Ec+3X1ltzAYeM
=
github.com/33cn/chain33 v0.0.0-20191
206075140-7c09cb251660 h1:m8T+ouTlPXP1e/SUPldWXSwFimfvmj/uo2hontTCts8
=
github.com/33cn/chain33 v0.0.0-20191
126060956-6354775a8a5d
/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/33cn/chain33 v0.0.0-20191
206075140-7c09cb251660
/go.mod h1:4I8n+Zyf3t0UKM5jjpqJY627Tub62oXkLsdzIv4r6rQ=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7 h1:PqzgE6kAMi81xWQA2QIVxjWkFHptGgC547vchpUbtFo=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
...
...
plugin/dapp/init/init.go
View file @
c22e26c7
...
@@ -20,6 +20,7 @@ import (
...
@@ -20,6 +20,7 @@ import (
_
"github.com/33cn/plugin/plugin/dapp/privacy"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/privacy"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/relay"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/relay"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/retrieve"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/retrieve"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/storage"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/ticket"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/ticket"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/token"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/token"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/trade"
//auto gen
_
"github.com/33cn/plugin/plugin/dapp/trade"
//auto gen
...
...
plugin/dapp/oracle/executor/oracle_test.go
0 → 100644
View file @
c22e26c7
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/cmd/scripts/autodeploy/Dockerfile
0 → 100644
View file @
c22e26c7
FROM
ubuntu:16.04
WORKDIR
/root
COPY
chain33 chain33
COPY
chain33-cli chain33-cli
COPY
entrypoint.sh entrypoint.sh
COPY
chain33.toml chain33*.toml ./
CMD
["/root/chain33", "-f", "/root/chain33.toml"]
plugin/dapp/paracross/cmd/scripts/autodeploy/Makefile
0 → 100644
View file @
c22e26c7
op
:=
"start"
.PHONY
:
docker-compose help
docker-compose
:
##
build docker-compose for chain33 run
@
./docker-compose.sh
$(op)
docker-compose-down
:
##
build docker-compose for chain33 run
@
cd
temp
;
docker-compose down
;
cd
..
help
:
##
Display this help screen
@
printf
"Help doc:
\n
Usage: make docker-compose op=[command]
\n
"
@
printf
"[command]
\n
"
@
printf
"[nodegroup]: create super node group if not create
\n
"
@
printf
"[wallet]: set node wallet private key if not set
\n
"
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/config
0 → 100755
View file @
c22e26c7
paraName="test"
#genesisAccount=""
#genesisAmount=100000000
#mainStartHeight=4800000
#authAccount=()
#authPrikey=()
##docker8901端口暴露到宿主机的端口
#authPort=("18901" "18902" "18903" "18904")
#
##需要和chain33 主链保持一致
#superManager="['1JmFaA6unrCFYEWPGRi7uuXY1KthTJxJEP']"
#
##nodegroup create
##申请超级账户需要在主链冻结币数量
#authFrozenCoins=0
#nodeGroupApplier=""
#applierPrikey=""
#superManagerPrikey=""
#### 测试链配置,主链配置需要把如下测试链配置屏蔽 ##########
genesisAccount="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
genesisAmount=100000000
mainStartHeight=4000000
authAccount=( "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4" "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR" "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k" "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs")
authPrikey=("0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71")
authPort=("18901" "18902" "18903" "18904")
#需要和chain33 主链保持一致
superManager="['12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv']"
tokenApprs="['12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv']"
#nodegroup create
authFrozenCoins=0
nodeGroupApplier="1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
applierPrikey="0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
superManagerPrikey="4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/docker-compose.sh
0 → 100755
View file @
c22e26c7
#!/usr/bin/env bash
# shellcheck disable=SC2154
set
-e
PWD
=
$(
cd
"
$(
dirname
"
$0
"
)
"
&&
pwd
)
export
PATH
=
"
$PWD
:
$PATH
"
buildpath
=
"temp"
NODE1
=
"
$buildpath
""_parachain1_1"
CLI
=
"docker exec
${
NODE1
}
/root/chain33-cli"
NODE2
=
"
$buildpath
""_parachain2_1"
NODE3
=
"
$buildpath
""_parachain3_1"
NODE4
=
"
$buildpath
""_parachain4_1"
CHAIN33_CLI
=
"chain33-cli"
containers
=(
"
${
NODE1
}
"
"
${
NODE2
}
"
"
${
NODE3
}
"
"
${
NODE4
}
"
)
## global config ###
sedfix
=
""
if
[
"
$(
uname
)
"
==
"Darwin"
]
;
then
sedfix
=
".bak"
fi
# shellcheck source=/dev/null
source
config
####################
function
para_init
()
{
local
index
=
1
for
auth
in
"
${
authAccount
[@]
}
"
;
do
tomlfile
=
"chain33.para.
$index
.toml"
para_set_toml
"
$tomlfile
"
sed
-i
$sedfix
's/^authAccount=.*/authAccount="'''
"
$auth
"
'''"/g'
"
$tomlfile
"
((
index++
))
done
}
function
para_set_toml
()
{
cp
chain33.para.toml
"
${
1
}
"
sed
-i
$sedfix
's/^Title.*/Title="user.p.'''
"
$paraName
"
'''."/g'
"
${
1
}
"
sed
-i
$sedfix
's/^startHeight=.*/startHeight='''
"
$mainStartHeight
"
'''/g'
"
${
1
}
"
# rpc
sed
-i
$sedfix
's/^jrpcBindAddr=.*/jrpcBindAddr="0.0.0.0:8901"/g'
"
${
1
}
"
sed
-i
$sedfix
's/^grpcBindAddr=.*/grpcBindAddr="0.0.0.0:8902"/g'
"
${
1
}
"
sed
-i
$sedfix
's/^whitelist=.*/whitelist=["localhost","127.0.0.1","0.0.0.0"]/g'
"
${
1
}
"
if
[
-n
"
$superManager
"
]
;
then
# shellcheck disable=SC1004
sed
-i
$sedfix
's/^superManager=.*/superManager='''
"
$superManager
"
'''/g'
"
${
1
}
"
fi
if
[
-n
"
$tokenApprs
"
]
;
then
# shellcheck disable=SC1004
sed
-i
$sedfix
's/^tokenApprs=.*/tokenApprs='''
"
$tokenApprs
"
'''/g'
"
${
1
}
"
fi
}
function
para_set_wallet
()
{
echo
"=========== # para set wallet ============="
for
((
i
=
0
;
i <
${#
authAccount
[@]
}
;
i++
))
;
do
para_import_wallet
"
${
authPort
[
$i
]
}
"
"
${
authPrikey
[
$i
]
}
"
done
}
function
para_import_wallet
()
{
local
key
=
$2
local
port
=
$1
echo
"=========== # save seed to wallet ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
seed save
-p
1314fuzamei
-s
"tortoise main civil member grace happy century convince father cage beach hip maid merry rib"
echo
"=========== # unlock wallet ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet unlock
-p
1314fuzamei
-t
0
echo
"=========== # import private key ============="
echo
"key:
${
key
}
"
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
account import_key
-k
"
${
key
}
"
-l
"paraAuthAccount"
echo
"=========== # close auto mining ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet auto_mine
-f
0
echo
"=========== # wallet status ============="
./
$CHAIN33_CLI
--rpc_laddr
"http://localhost:
$port
"
wallet status
}
function
start
()
{
echo
"=========== # docker-compose ps ============="
docker-compose ps
docker-compose down
# create and run docker-compose container
docker-compose up
--build
-d
local
SLEEP
=
10
echo
"=========== sleep
${
SLEEP
}
s ============="
sleep
${
SLEEP
}
docker-compose ps
# query node run status
echo
"status"
check_docker_status
# ./chain33-cli --rpc_laddr http://localhost:18901 block last_header
$CLI
--rpc_laddr
http://localhost:8901 block last_header
}
function
check_docker_status
()
{
status
=
$(
docker-compose ps |
grep
parachain1_1 |
awk
'{print $6}'
)
statusPara
=
$(
docker-compose ps |
grep
parachain1_1 |
awk
'{print $3}'
)
if
[
"
${
status
}
"
==
"Exit"
]
||
[
"
${
statusPara
}
"
==
"Exit"
]
;
then
echo
"=========== chain33 service Exit logs ========== "
docker-compose logs parachain1
echo
"=========== chain33 service Exit logs End========== "
fi
}
function
check_docker_container
()
{
echo
"============== check_docker_container ==============================="
for
con
in
"
${
containers
[@]
}
"
;
do
runing
=
$(
docker inspect
"
${
con
}
"
| jq
'.[0].State.Running'
)
if
[
!
"
${
runing
}
"
]
;
then
docker inspect
"
${
con
}
"
echo
"check
${
con
}
not actived!"
exit
1
fi
done
}
function
query_tx
()
{
sleep
5
local times
=
100
while
true
;
do
ret
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901 tx query
-s
"
${
1
}
"
| jq
-r
".tx.hash"
)
echo
"query hash is
${
1
}
, return
${
ret
}
"
if
[
"
${
ret
}
"
!=
"
${
1
}
"
]
;
then
sleep
5
times
=
$((
times
-
1
))
if
[
$times
-le
0
]
;
then
echo
"query tx=
$1
failed"
exit
1
fi
else
echo
"query tx=
$1
success"
break
fi
done
}
function
create_yml
()
{
touch
docker-compose.yml
cat
>>
docker-compose.yml
<<
EOF
version: '3'
services:
EOF
for
((
i
=
1
;
i <
=
${#
authAccount
[@]
}
;
i++
))
;
do
cat
>>
docker-compose.yml
<<
EOF
parachain
$i
:
build:
context: .
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para.
$i
.toml"
ports:
- "1890
$i
:8901"
volumes:
- "../storage/parachain
$i
/paradatadir:/root/paradatadir"
- "../storage/parachain
$i
/logs:/root/logs"
EOF
done
}
function
create_storage
()
{
mkdir
-p
storage
cd
storage
for
((
i
=
0
;
i <
${#
authAccount
[@]
}
;
i++
))
;
do
dirfile
=
"parachain
$i
"
mkdir
-p
"
$dirfile
"
done
cd
..
}
function
create_build
()
{
rm
-rf
$buildpath
mkdir
-p
$buildpath
cp
chain33
*
Dockerfile ./
*
.sh
"
$buildpath
"
/
cd
$buildpath
create_yml
}
function
para_create_nodegroup
()
{
echo
"=========== # para chain create node group ============="
local
auths
=
""
for
auth
in
"
${
authAccount
[@]
}
"
;
do
if
[
-z
$auths
]
;
then
auths
=
"
$auth
"
else
auths
=
"
$auths
,
$auth
"
fi
done
echo
"auths=
$auths
"
##apply
txhash
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
send para nodegroup apply
-a
"
$auths
"
-c
"
${
authFrozenCoins
}
"
-k
"
$applierPrikey
"
)
echo
"tx=
$txhash
"
query_tx
"
${
txhash
}
"
id
=
$txhash
echo
"need super manager approve id=
$txhash
"
if
[
-n
"
$superManagerPrikey
"
]
;
then
echo
"=========== # para chain approve node group ============="
##approve
txhash
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
send para nodegroup approve
-i
"
$id
"
-c
"
${
authFrozenCoins
}
"
-k
"
$superManagerPrikey
"
)
echo
"tx=
$txhash
"
query_tx
"
${
CLI
}
"
"
${
txhash
}
"
status
=
$(${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
para nodegroup status | jq
-r
".status"
)
if
[
"
$status
"
!=
2
]
;
then
echo
"status not approve status=
$status
"
exit
1
fi
${
CLI
}
--rpc_laddr
http://localhost:8901
--paraName
"user.p.
$paraName
."
para nodegroup addrs
fi
echo
"======== super node group config end ==================="
}
function
main
()
{
echo
"==============================parachain startup op=
$1
========================================================"
### init para ####
if
[
"
$1
"
==
"start"
]
;
then
create_storage
create_build
para_init
### start docker ####
start
### finish ###
check_docker_container
fi
if
[
"
$1
"
==
"nodegroup"
]
;
then
para_create_nodegroup
fi
if
[
"
$1
"
==
"wallet"
]
;
then
para_set_wallet
fi
echo
"===============================parachain startup end========================================================="
}
# run script
main
"
$1
"
plugin/dapp/paracross/cmd/scripts/autodeploy/docker-compose.yml
0 → 100644
View file @
c22e26c7
version
:
'
3'
services
:
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/entrypoint.sh
0 → 100755
View file @
c22e26c7
#!/usr/bin/env bash
/root/chain33
-f
"
$PARAFILE
"
plugin/dapp/paracross/cmd/test/test-rpc.sh
View file @
c22e26c7
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/commands/paracross.go
View file @
c22e26c7
...
@@ -37,6 +37,7 @@ func ParcCmd() *cobra.Command {
...
@@ -37,6 +37,7 @@ func ParcCmd() *cobra.Command {
paraConfigCmd
(),
paraConfigCmd
(),
GetParaInfoCmd
(),
GetParaInfoCmd
(),
GetParaListCmd
(),
GetParaListCmd
(),
GetParaAssetTransCmd
(),
IsSyncCmd
(),
IsSyncCmd
(),
GetHeightCmd
(),
GetHeightCmd
(),
GetBlockInfoCmd
(),
GetBlockInfoCmd
(),
...
@@ -936,6 +937,35 @@ func getNodeGroupAddrsCmd() *cobra.Command {
...
@@ -936,6 +937,35 @@ func getNodeGroupAddrsCmd() *cobra.Command {
return
cmd
return
cmd
}
}
func
addParaAssetTranCmdFlags
(
cmd
*
cobra
.
Command
)
{
cmd
.
Flags
()
.
StringP
(
"hash"
,
"s"
,
""
,
"asset transfer tx hash"
)
cmd
.
MarkFlagRequired
(
"hash"
)
}
func
paraAssetTransfer
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
hash
,
_
:=
cmd
.
Flags
()
.
GetString
(
"hash"
)
params
:=
types
.
ReqString
{
Data
:
hash
,
}
var
res
pt
.
ParacrossAssetRsp
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"paracross.GetAssetTxResult"
,
params
,
&
res
)
ctx
.
Run
()
}
// GetParaAssetTransCmd get para chain asset transfer info
func
GetParaAssetTransCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"asset_tranfer"
,
Short
:
"Get para chain cross asset transfer info"
,
Run
:
paraAssetTransfer
,
}
addParaAssetTranCmdFlags
(
cmd
)
return
cmd
}
func
nodeGroup
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
func
nodeGroup
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
paraName
,
_
:=
cmd
.
Flags
()
.
GetString
(
"paraName"
)
paraName
,
_
:=
cmd
.
Flags
()
.
GetString
(
"paraName"
)
...
...
plugin/dapp/paracross/executor/action.go
View file @
c22e26c7
...
@@ -318,10 +318,10 @@ func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}
...
@@ -318,10 +318,10 @@ func updateCommitAddrs(stat *pt.ParacrossHeightStatus, nodes map[string]struct{}
func
(
a
*
action
)
Commit
(
commit
*
pt
.
ParacrossCommitAction
)
(
*
types
.
Receipt
,
error
)
{
func
(
a
*
action
)
Commit
(
commit
*
pt
.
ParacrossCommitAction
)
(
*
types
.
Receipt
,
error
)
{
cfg
:=
a
.
api
.
GetConfig
()
cfg
:=
a
.
api
.
GetConfig
()
if
cfg
.
IsPara
()
&&
cfg
.
IsDappFork
(
a
.
h
eight
,
pt
.
ParaX
,
pt
.
ForkParaSelfConsStages
)
{
if
cfg
.
IsPara
()
&&
cfg
.
IsDappFork
(
commit
.
Status
.
H
eight
,
pt
.
ParaX
,
pt
.
ForkParaSelfConsStages
)
{
//分叉之后,key不存在,自共识没配置也认为不支持自共识
//分叉之后,key不存在,自共识没配置也认为不支持自共识
isSelfConsOn
,
err
:=
isSelfConsOn
(
a
.
db
,
commit
.
Status
.
Height
)
isSelfConsOn
,
err
:=
isSelfConsOn
(
a
.
db
,
commit
.
Status
.
Height
)
if
err
!=
nil
{
if
err
!=
nil
&&
errors
.
Cause
(
err
)
!=
pt
.
ErrKeyNotExist
{
return
nil
,
err
return
nil
,
err
}
}
if
!
isSelfConsOn
{
if
!
isSelfConsOn
{
...
@@ -748,7 +748,7 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossCommitAction, titleStatu
...
@@ -748,7 +748,7 @@ func (a *action) isAllowConsensJump(commit *pt.ParacrossCommitAction, titleStatu
}
}
func
(
a
*
action
)
execCrossTx
(
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
func
execCrossTx
(
a
*
action
,
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
if
!
bytes
.
HasSuffix
(
tx
.
Tx
.
Execer
,
[]
byte
(
pt
.
ParaX
))
{
if
!
bytes
.
HasSuffix
(
tx
.
Tx
.
Execer
,
[]
byte
(
pt
.
ParaX
))
{
return
nil
,
nil
return
nil
,
nil
}
}
...
@@ -762,7 +762,7 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
...
@@ -762,7 +762,7 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
if
payload
.
Ty
==
pt
.
ParacrossActionAssetWithdraw
{
if
payload
.
Ty
==
pt
.
ParacrossActionAssetWithdraw
{
receiptWithdraw
,
err
:=
a
.
assetWithdraw
(
payload
.
GetAssetWithdraw
(),
tx
.
Tx
)
receiptWithdraw
,
err
:=
a
.
assetWithdraw
(
payload
.
GetAssetWithdraw
(),
tx
.
Tx
)
if
err
!=
nil
{
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit
Decode
Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
clog
.
Crit
(
"paracross.Commit
withdraw
Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
errors
.
Cause
(
err
)
return
nil
,
errors
.
Cause
(
err
)
}
}
...
@@ -773,6 +773,31 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
...
@@ -773,6 +773,31 @@ func (a *action) execCrossTx(tx *types.TransactionDetail, crossTxHash []byte) (*
}
}
func
rollbackCrossTx
(
a
*
action
,
tx
*
types
.
TransactionDetail
,
crossTxHash
[]
byte
)
(
*
types
.
Receipt
,
error
)
{
if
!
bytes
.
HasSuffix
(
tx
.
Tx
.
Execer
,
[]
byte
(
pt
.
ParaX
))
{
return
nil
,
nil
}
var
payload
pt
.
ParacrossAction
err
:=
types
.
Decode
(
tx
.
Tx
.
Payload
,
&
payload
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit.rollbackCrossTx Decode Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
err
}
if
payload
.
Ty
==
pt
.
ParacrossActionAssetTransfer
{
receipt
,
err
:=
a
.
assetTransferRollback
(
payload
.
GetAssetTransfer
(),
tx
.
Tx
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit rbk Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
))
return
nil
,
errors
.
Cause
(
err
)
}
clog
.
Debug
(
"paracross.Commit rollbackCrossTx"
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHash
),
"mainHeight"
,
a
.
height
)
return
receipt
,
nil
}
return
nil
,
nil
}
func
getCrossTxHashsByRst
(
api
client
.
QueueProtocolAPI
,
status
*
pt
.
ParacrossNodeStatus
)
([][]
byte
,
[]
byte
,
error
)
{
func
getCrossTxHashsByRst
(
api
client
.
QueueProtocolAPI
,
status
*
pt
.
ParacrossNodeStatus
)
([][]
byte
,
[]
byte
,
error
)
{
//只获取跨链tx
//只获取跨链tx
cfg
:=
api
.
GetConfig
()
cfg
:=
api
.
GetConfig
()
...
@@ -781,10 +806,12 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
...
@@ -781,10 +806,12 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
clog
.
Error
(
"getCrossTxHashs decode rst"
,
"CrossTxResult"
,
string
(
status
.
TxResult
),
"paraHeight"
,
status
.
Height
)
clog
.
Error
(
"getCrossTxHashs decode rst"
,
"CrossTxResult"
,
string
(
status
.
TxResult
),
"paraHeight"
,
status
.
Height
)
return
nil
,
nil
,
types
.
ErrInvalidParam
return
nil
,
nil
,
types
.
ErrInvalidParam
}
}
clog
.
Debug
(
"getCrossTxHashsByRst"
,
"height"
,
status
.
Height
,
"txResult"
,
string
(
status
.
TxResult
))
//空块
if
!
cfg
.
IsDappFork
(
status
.
MainBlockHeight
,
pt
.
ParaX
,
pt
.
ForkParaAssetTransferRbk
)
{
if
len
(
rst
)
==
0
{
if
len
(
rst
)
==
0
{
return
nil
,
nil
,
nil
return
nil
,
nil
,
nil
}
}
}
blockDetail
,
err
:=
GetBlock
(
api
,
status
.
MainBlockHash
)
blockDetail
,
err
:=
GetBlock
(
api
,
status
.
MainBlockHash
)
...
@@ -800,6 +827,7 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
...
@@ -800,6 +827,7 @@ func getCrossTxHashsByRst(api client.QueueProtocolAPI, status *pt.ParacrossNodeS
}
}
paraCrossHashs
:=
FilterParaCrossTxHashes
(
paraAllTxs
)
paraCrossHashs
:=
FilterParaCrossTxHashes
(
paraAllTxs
)
crossRst
:=
util
.
CalcBitMapByBitMap
(
paraCrossHashs
,
baseHashs
,
rst
)
crossRst
:=
util
.
CalcBitMapByBitMap
(
paraCrossHashs
,
baseHashs
,
rst
)
clog
.
Debug
(
"getCrossTxHashsByRst.crossRst"
,
"height"
,
status
.
Height
,
"txResult"
,
hex
.
EncodeToString
(
crossRst
),
"len"
,
len
(
paraCrossHashs
))
return
paraCrossHashs
,
crossRst
,
nil
return
paraCrossHashs
,
crossRst
,
nil
...
@@ -858,6 +886,24 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
...
@@ -858,6 +886,24 @@ func getCrossTxHashs(api client.QueueProtocolAPI, status *pt.ParacrossNodeStatus
}
}
func
crossTxProc
(
a
*
action
,
txHash
[]
byte
,
fn
func
(
*
action
,
*
types
.
TransactionDetail
,
[]
byte
)
(
*
types
.
Receipt
,
error
))
(
*
types
.
Receipt
,
error
)
{
tx
,
err
:=
GetTx
(
a
.
api
,
txHash
)
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit Load Tx failed"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
txHash
))
return
nil
,
err
}
if
tx
==
nil
{
clog
.
Error
(
"paracross.Commit Load Tx nil"
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
txHash
))
return
nil
,
types
.
ErrHashNotExist
}
receiptCross
,
err
:=
fn
(
a
,
tx
,
txHash
)
if
err
!=
nil
{
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"error"
,
err
)
return
nil
,
errors
.
Cause
(
err
)
}
return
receiptCross
,
nil
}
func
(
a
*
action
)
execCrossTxs
(
status
*
pt
.
ParacrossNodeStatus
)
(
*
types
.
Receipt
,
error
)
{
func
(
a
*
action
)
execCrossTxs
(
status
*
pt
.
ParacrossNodeStatus
)
(
*
types
.
Receipt
,
error
)
{
var
receipt
types
.
Receipt
var
receipt
types
.
Receipt
...
@@ -866,28 +912,14 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
...
@@ -866,28 +912,14 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
clog
.
Error
(
"paracross.Commit getCrossTxHashs"
,
"err"
,
err
.
Error
())
clog
.
Error
(
"paracross.Commit getCrossTxHashs"
,
"err"
,
err
.
Error
())
return
nil
,
err
return
nil
,
err
}
}
if
len
(
crossTxHashs
)
==
0
{
return
&
receipt
,
nil
}
for
i
:=
0
;
i
<
len
(
crossTxHashs
);
i
++
{
for
i
:=
0
;
i
<
len
(
crossTxHashs
);
i
++
{
clog
.
Debug
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
clog
.
Debug
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
"res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
"res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
if
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
))
{
if
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
))
{
tx
,
err
:=
GetTx
(
a
.
api
,
crossTxHashs
[
i
]
)
receiptCross
,
err
:=
crossTxProc
(
a
,
crossTxHashs
[
i
],
execCrossTx
)
if
err
!=
nil
{
if
err
!=
nil
{
clog
.
Crit
(
"paracross.Commit Load Tx failed"
,
"para title"
,
title
,
"para height"
,
status
.
Height
,
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"para title"
,
status
.
Title
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]))
return
nil
,
err
}
if
tx
==
nil
{
clog
.
Error
(
"paracross.Commit Load Tx failed"
,
"para title"
,
title
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
,
"txHash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]))
return
nil
,
types
.
ErrHashNotExist
}
receiptCross
,
err
:=
a
.
execCrossTx
(
tx
,
crossTxHashs
[
i
])
if
err
!=
nil
{
clog
.
Error
(
"paracross.Commit execCrossTx"
,
"para title"
,
title
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
)
"para tx index"
,
i
,
"error"
,
err
)
return
nil
,
errors
.
Cause
(
err
)
return
nil
,
errors
.
Cause
(
err
)
}
}
...
@@ -898,8 +930,21 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
...
@@ -898,8 +930,21 @@ func (a *action) execCrossTxs(status *pt.ParacrossNodeStatus) (*types.Receipt, e
receipt
.
Logs
=
append
(
receipt
.
Logs
,
receiptCross
.
Logs
...
)
receipt
.
Logs
=
append
(
receipt
.
Logs
,
receiptCross
.
Logs
...
)
}
else
{
}
else
{
clog
.
Error
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
clog
.
Error
(
"paracross.Commit commitDone"
,
"do cross number"
,
i
,
"hash"
,
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
hex
.
EncodeToString
(
crossTxHashs
[
i
]),
"para res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
"para res"
,
util
.
BitMapBit
(
crossTxResult
,
uint32
(
i
)))
cfg
:=
a
.
api
.
GetConfig
()
if
cfg
.
IsDappFork
(
a
.
height
,
pt
.
ParaX
,
pt
.
ForkParaAssetTransferRbk
)
{
receiptCross
,
err
:=
crossTxProc
(
a
,
crossTxHashs
[
i
],
rollbackCrossTx
)
if
err
!=
nil
{
clog
.
Error
(
"paracross.Commit rollbackCrossTx"
,
"para title"
,
status
.
Title
,
"para height"
,
status
.
Height
,
"para tx index"
,
i
,
"error"
,
err
)
return
nil
,
errors
.
Cause
(
err
)
}
if
receiptCross
==
nil
{
continue
}
receipt
.
KV
=
append
(
receipt
.
KV
,
receiptCross
.
KV
...
)
receipt
.
Logs
=
append
(
receipt
.
Logs
,
receiptCross
.
Logs
...
)
}
}
}
}
}
...
...
plugin/dapp/paracross/executor/asset.go
View file @
c22e26c7
...
@@ -87,6 +87,24 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types
...
@@ -87,6 +87,24 @@ func (a *action) assetWithdraw(withdraw *types.AssetsWithdraw, withdrawTx *types
return
assetWithdrawBalance
(
paraAcc
,
a
.
fromaddr
,
withdraw
.
Amount
)
return
assetWithdrawBalance
(
paraAcc
,
a
.
fromaddr
,
withdraw
.
Amount
)
}
}
func
(
a
*
action
)
assetTransferRollback
(
transfer
*
types
.
AssetsTransfer
,
transferTx
*
types
.
Transaction
)
(
*
types
.
Receipt
,
error
)
{
cfg
:=
a
.
api
.
GetConfig
()
isPara
:=
cfg
.
IsPara
()
//主链处理分支
if
!
isPara
{
accDB
,
err
:=
createAccount
(
cfg
,
a
.
db
,
transfer
.
Cointoken
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"assetTransferToken call account.NewAccountDB failed"
)
}
execAddr
:=
address
.
ExecAddress
(
pt
.
ParaX
)
fromAcc
:=
address
.
ExecAddress
(
string
(
transferTx
.
Execer
))
clog
.
Debug
(
"paracross.AssetTransferRbk "
,
"execer"
,
string
(
transferTx
.
Execer
),
"transfer.txHash"
,
hex
.
EncodeToString
(
transferTx
.
Hash
()),
"curTx"
,
hex
.
EncodeToString
(
a
.
tx
.
Hash
()))
return
accDB
.
ExecTransfer
(
fromAcc
,
transferTx
.
From
(),
execAddr
,
transfer
.
Amount
)
}
return
nil
,
nil
}
func
createAccount
(
cfg
*
types
.
Chain33Config
,
db
db
.
KV
,
symbol
string
)
(
*
account
.
DB
,
error
)
{
func
createAccount
(
cfg
*
types
.
Chain33Config
,
db
db
.
KV
,
symbol
string
)
(
*
account
.
DB
,
error
)
{
var
accDB
*
account
.
DB
var
accDB
*
account
.
DB
var
err
error
var
err
error
...
...
plugin/dapp/paracross/executor/exec_local.go
View file @
c22e26c7
...
@@ -228,6 +228,7 @@ func setMinerTxResultFork(cfg *types.Chain33Config, status *pt.ParacrossNodeStat
...
@@ -228,6 +228,7 @@ func setMinerTxResultFork(cfg *types.Chain33Config, status *pt.ParacrossNodeStat
//主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map
//主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map
//全部平行链tx结果
//全部平行链tx结果
status
.
TxResult
=
[]
byte
(
hex
.
EncodeToString
(
util
.
CalcSingleBitMap
(
curTxHashs
,
receipts
)))
status
.
TxResult
=
[]
byte
(
hex
.
EncodeToString
(
util
.
CalcSingleBitMap
(
curTxHashs
,
receipts
)))
clog
.
Debug
(
"setMinerTxResultFork"
,
"height"
,
status
.
Height
,
"txResult"
,
string
(
status
.
TxResult
))
//ForkLoopCheckCommitTxDone 后只保留全部txreseult 结果
//ForkLoopCheckCommitTxDone 后只保留全部txreseult 结果
if
!
pt
.
IsParaForkHeight
(
cfg
,
status
.
MainBlockHeight
,
pt
.
ForkLoopCheckCommitTxDone
)
{
if
!
pt
.
IsParaForkHeight
(
cfg
,
status
.
MainBlockHeight
,
pt
.
ForkLoopCheckCommitTxDone
)
{
...
...
plugin/dapp/paracross/executor/query.go
View file @
c22e26c7
...
@@ -218,11 +218,15 @@ func (p *Paracross) Query_GetDoneTitleHeight(in *pt.ReqParacrossTitleHeight) (ty
...
@@ -218,11 +218,15 @@ func (p *Paracross) Query_GetDoneTitleHeight(in *pt.ReqParacrossTitleHeight) (ty
}
}
// Query_GetAssetTxResult query get asset tx reseult
// Query_GetAssetTxResult query get asset tx reseult
func
(
p
*
Paracross
)
Query_GetAssetTxResult
(
in
*
types
.
Req
Hash
)
(
types
.
Message
,
error
)
{
func
(
p
*
Paracross
)
Query_GetAssetTxResult
(
in
*
types
.
Req
String
)
(
types
.
Message
,
error
)
{
if
in
==
nil
{
if
in
==
nil
||
in
.
Data
==
""
{
return
nil
,
types
.
ErrInvalidParam
return
nil
,
types
.
ErrInvalidParam
}
}
return
p
.
paracrossGetAssetTxResult
(
in
.
Hash
)
hash
,
err
:=
common
.
FromHex
(
in
.
Data
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"fromHex"
)
}
return
p
.
paracrossGetAssetTxResult
(
hash
)
}
}
// Query_GetMainBlockHash query get mainblockHash by tx
// Query_GetMainBlockHash query get mainblockHash by tx
...
@@ -296,7 +300,7 @@ func listLocalTitles(db dbm.KVDB) (types.Message, error) {
...
@@ -296,7 +300,7 @@ func listLocalTitles(db dbm.KVDB) (types.Message, error) {
MostSameCommit
:
st
.
MostSameCommit
,
MostSameCommit
:
st
.
MostSameCommit
,
Title
:
st
.
Title
,
Title
:
st
.
Title
,
Height
:
st
.
Height
,
Height
:
st
.
Height
,
TxResult
:
hex
.
EncodeToS
tring
(
st
.
TxResult
),
TxResult
:
s
tring
(
st
.
TxResult
),
}
}
resp
.
Titles
=
append
(
resp
.
Titles
,
rst
)
resp
.
Titles
=
append
(
resp
.
Titles
,
rst
)
...
@@ -400,13 +404,34 @@ func (p *Paracross) paracrossGetAssetTxResult(hash []byte) (types.Message, error
...
@@ -400,13 +404,34 @@ func (p *Paracross) paracrossGetAssetTxResult(hash []byte) (types.Message, error
return
nil
,
err
return
nil
,
err
}
}
var
r
esul
t
pt
.
ParacrossAsset
var
r
s
t
pt
.
ParacrossAsset
err
=
types
.
Decode
(
value
,
&
r
esul
t
)
err
=
types
.
Decode
(
value
,
&
r
s
t
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
&
result
,
nil
rsp
:=
&
pt
.
ParacrossAssetRsp
{
From
:
rst
.
From
,
To
:
rst
.
To
,
Amount
:
rst
.
Amount
,
Exec
:
rst
.
Exec
,
Symbol
:
rst
.
Symbol
,
Height
:
rst
.
Height
,
CommitDoneHeight
:
rst
.
CommitDoneHeight
,
ParaHeight
:
rst
.
ParaHeight
,
}
rsp
.
TxHash
=
common
.
ToHex
(
rst
.
TxHash
)
rsp
.
IsWithdraw
=
"false"
if
rst
.
IsWithdraw
{
rsp
.
IsWithdraw
=
"true"
}
rsp
.
Success
=
"false"
if
rst
.
Success
{
rsp
.
Success
=
"true"
}
return
rsp
,
nil
}
}
//Query_GetSelfConsStages get self consensus stages configed
//Query_GetSelfConsStages get self consensus stages configed
...
...
plugin/dapp/paracross/proto/paracross.proto
View file @
c22e26c7
...
@@ -385,6 +385,23 @@ message ParacrossAsset {
...
@@ -385,6 +385,23 @@ message ParacrossAsset {
bool
success
=
23
;
bool
success
=
23
;
}
}
message
ParacrossAssetRsp
{
// input
string
from
=
1
;
string
to
=
2
;
string
isWithdraw
=
3
;
string
txHash
=
4
;
int64
amount
=
5
;
string
exec
=
6
;
string
symbol
=
7
;
// 主链部分
int64
height
=
10
;
// 平行链部分
int64
commitDoneHeight
=
21
;
int64
paraHeight
=
22
;
string
success
=
23
;
}
message
ParaLocalDbBlock
{
message
ParaLocalDbBlock
{
int64
height
=
1
;
int64
height
=
1
;
bytes
mainHash
=
2
;
bytes
mainHash
=
2
;
...
@@ -408,6 +425,6 @@ service paracross {
...
@@ -408,6 +425,6 @@ service paracross {
rpc
ListTitles
(
ReqNil
)
returns
(
RespParacrossTitles
)
{}
rpc
ListTitles
(
ReqNil
)
returns
(
RespParacrossTitles
)
{}
rpc
GetDoneTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
RespParacrossDone
)
{}
rpc
GetDoneTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
RespParacrossDone
)
{}
rpc
GetTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
ParacrossHeightStatusRsp
)
{}
rpc
GetTitleHeight
(
ReqParacrossTitleHeight
)
returns
(
ParacrossHeightStatusRsp
)
{}
rpc
GetAssetTxResult
(
Req
Hash
)
returns
(
ParacrossAsset
)
{}
rpc
GetAssetTxResult
(
Req
String
)
returns
(
ParacrossAssetRsp
)
{}
rpc
IsSync
(
ReqNil
)
returns
(
IsCaughtUp
)
{}
rpc
IsSync
(
ReqNil
)
returns
(
IsCaughtUp
)
{}
}
}
\ No newline at end of file
plugin/dapp/paracross/rpc/rpc.go
View file @
c22e26c7
...
@@ -118,20 +118,20 @@ func (c *channelClient) GetDoneTitleHeight(ctx context.Context, req *pt.ReqParac
...
@@ -118,20 +118,20 @@ func (c *channelClient) GetDoneTitleHeight(ctx context.Context, req *pt.ReqParac
return
nil
,
types
.
ErrDecode
return
nil
,
types
.
ErrDecode
}
}
func
(
c
*
channelClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
req
*
types
.
Req
Hash
)
(
*
pt
.
ParacrossAsset
,
error
)
{
func
(
c
*
channelClient
)
GetAssetTxResult
(
ctx
context
.
Context
,
req
*
types
.
Req
String
)
(
*
pt
.
ParacrossAssetRsp
,
error
)
{
cfg
:=
c
.
GetConfig
()
cfg
:=
c
.
GetConfig
()
data
,
err
:=
c
.
Query
(
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
data
,
err
:=
c
.
Query
(
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
resp
,
ok
:=
data
.
(
*
pt
.
ParacrossAsset
);
ok
{
if
resp
,
ok
:=
data
.
(
*
pt
.
ParacrossAsset
Rsp
);
ok
{
return
resp
,
nil
return
resp
,
nil
}
}
return
nil
,
types
.
ErrDecode
return
nil
,
types
.
ErrDecode
}
}
// GetAssetTxResult get asset tx result
// GetAssetTxResult get asset tx result
func
(
c
*
Jrpc
)
GetAssetTxResult
(
req
*
types
.
Req
Hash
,
result
*
interface
{})
error
{
func
(
c
*
Jrpc
)
GetAssetTxResult
(
req
*
types
.
Req
String
,
result
*
interface
{})
error
{
if
req
==
nil
{
if
req
==
nil
{
return
types
.
ErrInvalidParam
return
types
.
ErrInvalidParam
}
}
...
...
plugin/dapp/paracross/rpc/rpc_test.go
View file @
c22e26c7
...
@@ -124,8 +124,8 @@ func TestChannelClient_GetAssetTxResult(t *testing.T) {
...
@@ -124,8 +124,8 @@ func TestChannelClient_GetAssetTxResult(t *testing.T) {
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
client
:=
newGrpc
(
api
)
client
:=
newGrpc
(
api
)
client
.
Init
(
"paracross"
,
nil
,
nil
,
nil
)
client
.
Init
(
"paracross"
,
nil
,
nil
,
nil
)
req
:=
&
types
.
Req
Hash
{}
req
:=
&
types
.
Req
String
{}
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
{},
nil
)
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
Rsp
{},
nil
)
_
,
err
:=
client
.
GetAssetTxResult
(
context
.
Background
(),
req
)
_
,
err
:=
client
.
GetAssetTxResult
(
context
.
Background
(),
req
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
}
}
...
@@ -135,9 +135,9 @@ func TestJrpc_GetAssetTxResult(t *testing.T) {
...
@@ -135,9 +135,9 @@ func TestJrpc_GetAssetTxResult(t *testing.T) {
api
:=
new
(
mocks
.
QueueProtocolAPI
)
api
:=
new
(
mocks
.
QueueProtocolAPI
)
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
cfg
,
nil
)
j
:=
newJrpc
(
api
)
j
:=
newJrpc
(
api
)
req
:=
&
types
.
Req
Hash
{}
req
:=
&
types
.
Req
String
{}
var
result
interface
{}
var
result
interface
{}
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
{},
nil
)
api
.
On
(
"Query"
,
pt
.
GetExecName
(
cfg
),
"GetAssetTxResult"
,
req
)
.
Return
(
&
pt
.
ParacrossAsset
Rsp
{},
nil
)
err
:=
j
.
GetAssetTxResult
(
req
,
&
result
)
err
:=
j
.
GetAssetTxResult
(
req
,
&
result
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
}
}
...
...
plugin/dapp/paracross/types/paracross.pb.go
View file @
c22e26c7
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/types/type.go
View file @
c22e26c7
...
@@ -26,6 +26,8 @@ var (
...
@@ -26,6 +26,8 @@ var (
MainLoopCheckCommitTxDoneForkHeight
=
"mainLoopCheckCommitTxDoneForkHeight"
MainLoopCheckCommitTxDoneForkHeight
=
"mainLoopCheckCommitTxDoneForkHeight"
// ForkParaSelfConsStages 平行链自共识分阶段共识
// ForkParaSelfConsStages 平行链自共识分阶段共识
ForkParaSelfConsStages
=
"ForkParaSelfConsStages"
ForkParaSelfConsStages
=
"ForkParaSelfConsStages"
// ForkParaAssetTransferRbk 平行链资产转移平行链失败主链回滚
ForkParaAssetTransferRbk
=
"ForkParaAssetTransferRbk"
// ParaConsSubConf sub
// ParaConsSubConf sub
ParaConsSubConf
=
"consensus.sub.para"
ParaConsSubConf
=
"consensus.sub.para"
...
@@ -52,6 +54,8 @@ func InitFork(cfg *types.Chain33Config) {
...
@@ -52,6 +54,8 @@ func InitFork(cfg *types.Chain33Config) {
cfg
.
RegisterDappFork
(
ParaX
,
"ForkParacrossWithdrawFromParachain"
,
1298600
)
cfg
.
RegisterDappFork
(
ParaX
,
"ForkParacrossWithdrawFromParachain"
,
1298600
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkCommitTx
,
1850000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkCommitTx
,
1850000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkLoopCheckCommitTxDone
,
3230000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkLoopCheckCommitTxDone
,
3230000
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkParaAssetTransferRbk
,
4500000
)
//只在平行链启用
//只在平行链启用
cfg
.
RegisterDappFork
(
ParaX
,
ForkParaSelfConsStages
,
types
.
MaxHeight
)
cfg
.
RegisterDappFork
(
ParaX
,
ForkParaSelfConsStages
,
types
.
MaxHeight
)
}
}
...
...
plugin/dapp/storage/cmd/Makefile
0 → 100644
View file @
c22e26c7
all
:
chmod
+x ./build.sh
./build.sh
$(OUT)
$(FLAG)
plugin/dapp/storage/cmd/build.sh
0 → 100755
View file @
c22e26c7
#!/bin/sh
# 官方ci集成脚本
strpwd
=
$(
pwd
)
strcmd
=
${
strpwd
##*dapp/
}
strapp
=
${
strcmd
%/cmd*
}
OUT_DIR
=
"
${
1
}
/
$strapp
"
#FLAG=$2
mkdir
-p
"
${
OUT_DIR
}
"
cp
./build/
*
"
${
OUT_DIR
}
"
plugin/dapp/storage/commands/commands.go
0 → 100644
View file @
c22e26c7
/*Package commands implement dapp client commands*/
package
commands
import
(
"github.com/spf13/cobra"
)
/*
* 实现合约对应客户端
*/
// Cmd storage client command
func
Cmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"storage"
,
Short
:
"storage command"
,
Args
:
cobra
.
MinimumNArgs
(
1
),
}
cmd
.
AddCommand
(
//add sub command
)
return
cmd
}
plugin/dapp/storage/crypto/aes.go
0 → 100644
View file @
c22e26c7
package
crypto
import
(
"crypto/aes"
"crypto/cipher"
)
type
AES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小,这里是16字节,固定
iv
[]
byte
}
//AES 密钥长度为 16,24,32 字节,三种
func
NewAES
(
key
,
iv
[]
byte
)
*
AES
{
return
&
AES
{
key
:
key
,
iv
:
iv
}
}
func
(
a
*
AES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
aes
.
NewCipher
(
a
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockSize
:=
block
.
BlockSize
()
origData
=
PKCS5Padding
(
origData
,
blockSize
)
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
a
.
iv
[
:
blockSize
])
crypted
:=
make
([]
byte
,
len
(
origData
))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
func
(
a
*
AES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
aes
.
NewCipher
(
a
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockSize
:=
block
.
BlockSize
()
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
a
.
iv
[
:
blockSize
])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
plugin/dapp/storage/crypto/aes_test.go
0 → 100644
View file @
c22e26c7
package
crypto
import
(
"encoding/base64"
"testing"
"github.com/stretchr/testify/assert"
)
//DES 加解密测试
func
TestAes
(
t
*
testing
.
T
)
{
aes
:=
NewAES
(
keys
[
2
],
ivs
[
0
])
result
,
err
:=
aes
.
Encrypt
(
contents
[
1
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
aes
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
1
],
origData
)
}
plugin/dapp/storage/crypto/crypto.go
0 → 100644
View file @
c22e26c7
package
crypto
import
"bytes"
type
Crypto
interface
{
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
}
func
ZeroPadding
(
ciphertext
[]
byte
,
blockSize
int
)
[]
byte
{
padding
:=
blockSize
-
len
(
ciphertext
)
%
blockSize
padtext
:=
bytes
.
Repeat
([]
byte
{
0
},
padding
)
return
append
(
ciphertext
,
padtext
...
)
}
func
ZeroUnPadding
(
origData
[]
byte
)
[]
byte
{
return
bytes
.
TrimRightFunc
(
origData
,
func
(
r
rune
)
bool
{
return
r
==
rune
(
0
)
})
}
func
PKCS5Padding
(
ciphertext
[]
byte
,
blockSize
int
)
[]
byte
{
padding
:=
blockSize
-
len
(
ciphertext
)
%
blockSize
padtext
:=
bytes
.
Repeat
([]
byte
{
byte
(
padding
)},
padding
)
return
append
(
ciphertext
,
padtext
...
)
}
func
PKCS5UnPadding
(
origData
[]
byte
)
[]
byte
{
length
:=
len
(
origData
)
// 去掉最后一个字节 unpadding 次
unpadding
:=
int
(
origData
[
length
-
1
])
return
origData
[
:
(
length
-
unpadding
)]
}
plugin/dapp/storage/crypto/des.go
0 → 100644
View file @
c22e26c7
package
crypto
import
(
"crypto/cipher"
"crypto/des"
)
type
DES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小
iv
[]
byte
}
func
NewDES
(
key
,
iv
[]
byte
)
*
DES
{
return
&
DES
{
key
:
key
,
iv
:
iv
}
}
func
(
d
*
DES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
origData
=
PKCS5Padding
(
origData
,
block
.
BlockSize
())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
crypted
:=
make
([]
byte
,
len
(
origData
))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
// 密钥key长度固定8字节
func
(
d
*
DES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
type
TripleDES
struct
{
key
[]
byte
//iv的长度必须等于block块的大小
iv
[]
byte
}
func
NewTripleDES
(
key
,
iv
[]
byte
)
*
TripleDES
{
return
&
TripleDES
{
key
:
key
,
iv
:
iv
}
}
// 3DES加密 24字节
func
(
d
*
TripleDES
)
Encrypt
(
origData
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewTripleDESCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
origData
=
PKCS5Padding
(
origData
,
block
.
BlockSize
())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode
:=
cipher
.
NewCBCEncrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
crypted
:=
make
([]
byte
,
len
(
origData
))
blockMode
.
CryptBlocks
(
crypted
,
origData
)
return
crypted
,
nil
}
// 3DES解密
func
(
d
*
TripleDES
)
Decrypt
(
crypted
[]
byte
)
([]
byte
,
error
)
{
block
,
err
:=
des
.
NewTripleDESCipher
(
d
.
key
)
if
err
!=
nil
{
return
nil
,
err
}
blockMode
:=
cipher
.
NewCBCDecrypter
(
block
,
d
.
iv
[
:
block
.
BlockSize
()])
origData
:=
make
([]
byte
,
len
(
crypted
))
// origData := crypted
blockMode
.
CryptBlocks
(
origData
,
crypted
)
origData
=
PKCS5UnPadding
(
origData
)
// origData = ZeroUnPadding(origData)
return
origData
,
nil
}
plugin/dapp/storage/crypto/des_test.go
0 → 100644
View file @
c22e26c7
package
crypto
import
(
"encoding/base64"
"testing"
"github.com/stretchr/testify/assert"
)
var
(
contents
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
keys
=
[][]
byte
{
[]
byte
(
"123456ab"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScs"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScsHD3psX7k"
),
}
ivs
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
//DES 加解密测试
func
TestDes
(
t
*
testing
.
T
)
{
des
:=
NewDES
(
keys
[
0
],
ivs
[
0
])
result
,
err
:=
des
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
des
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
0
],
origData
)
}
//3DES 加解密测试
func
Test3Des
(
t
*
testing
.
T
)
{
des
:=
NewTripleDES
(
keys
[
1
],
ivs
[
1
])
result
,
err
:=
des
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
base64
.
StdEncoding
.
EncodeToString
(
result
))
origData
,
err
:=
des
.
Decrypt
(
result
)
if
err
!=
nil
{
t
.
Error
(
err
)
}
assert
.
Equal
(
t
,
contents
[
0
],
origData
)
}
plugin/dapp/storage/executor/exec.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 实现交易的链上执行接口
* 关键数据上链(statedb)并生成交易回执(log)
*/
func
(
s
*
storage
)
Exec_ContentStorage
(
payload
*
storagetypes
.
ContentOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
ContentStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_ContentStorage
{
ContentStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_HashStorage
(
payload
*
storagetypes
.
HashOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
HashStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_HashStorage
{
HashStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_LinkStorage
(
payload
*
storagetypes
.
LinkNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
LinkStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_LinkStorage
{
LinkStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_EncryptStorage
(
payload
*
storagetypes
.
EncryptNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
EncryptStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_EncryptStorage
{
EncryptStorage
:
payload
}})
}
func
(
s
*
storage
)
Exec_EncryptShareStorage
(
payload
*
storagetypes
.
EncryptShareNotaryStorage
,
tx
*
types
.
Transaction
,
index
int
)
(
*
types
.
Receipt
,
error
)
{
action
:=
newStorageAction
(
s
,
tx
,
index
)
return
action
.
EncryptShareStorage
(
&
storagetypes
.
Storage
{
Value
:
&
storagetypes
.
Storage_EncryptShareStorage
{
EncryptShareStorage
:
payload
}})
}
plugin/dapp/storage/executor/exec_del_local.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"github.com/33cn/chain33/types"
)
/*
* 实现区块回退时本地执行的数据清除
*/
// ExecDelLocal 回退自动删除,重写基类
func
(
s
*
storage
)
ExecDelLocal
(
tx
*
types
.
Transaction
,
receipt
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
kvs
,
err
:=
s
.
DelRollbackKV
(
tx
,
tx
.
Execer
)
if
err
!=
nil
{
return
nil
,
err
}
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
append
(
dbSet
.
KV
,
kvs
...
)
return
dbSet
,
nil
}
plugin/dapp/storage/executor/exec_local.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 实现交易相关数据本地执行,数据不上链
* 非关键数据,本地存储(localDB), 用于辅助查询,效率高
*/
func
(
s
*
storage
)
ExecLocal_ContentStorage
(
payload
*
storagetypes
.
ContentOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_HashStorage
(
payload
*
storagetypes
.
HashOnlyNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_LinkStorage
(
payload
*
storagetypes
.
LinkNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_EncryptStorage
(
payload
*
storagetypes
.
EncryptNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
func
(
s
*
storage
)
ExecLocal_EncryptShareStorage
(
payload
*
storagetypes
.
EncryptShareNotaryStorage
,
tx
*
types
.
Transaction
,
receiptData
*
types
.
ReceiptData
,
index
int
)
(
*
types
.
LocalDBSet
,
error
)
{
dbSet
:=
&
types
.
LocalDBSet
{}
//implement code
return
s
.
addAutoRollBack
(
tx
,
dbSet
.
KV
),
nil
}
//设置自动回滚
func
(
s
*
storage
)
addAutoRollBack
(
tx
*
types
.
Transaction
,
kv
[]
*
types
.
KeyValue
)
*
types
.
LocalDBSet
{
dbSet
:=
&
types
.
LocalDBSet
{}
dbSet
.
KV
=
s
.
AddRollbackKV
(
tx
,
tx
.
Execer
,
kv
)
return
dbSet
}
plugin/dapp/storage/executor/kv.go
0 → 100644
View file @
c22e26c7
package
executor
/*
* 用户合约存取kv数据时,key值前缀需要满足一定规范
* 即key = keyPrefix + userKey
* 需要字段前缀查询时,使用’-‘作为分割符号
*/
var
(
//KeyPrefixStateDB state db key必须前缀
KeyPrefixStateDB
=
"mavl-storage-"
//KeyPrefixLocalDB local db的key必须前缀
KeyPrefixLocalDB
=
"LODB-storage-"
)
// Key Storage to save key
func
Key
(
txHash
string
)
(
key
[]
byte
)
{
key
=
append
(
key
,
[]
byte
(
KeyPrefixStateDB
)
...
)
key
=
append
(
key
,
[]
byte
(
txHash
)
...
)
return
key
}
plugin/dapp/storage/executor/query.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
//从statedb 读取原始数据
func
(
s
*
storage
)
Query_QueryStorage
(
in
*
storagetypes
.
QueryStorage
)
(
types
.
Message
,
error
)
{
return
QueryStorage
(
s
.
GetStateDB
(),
in
)
}
//通过状态查询ids
func
(
s
*
storage
)
Query_BatchQueryStorage
(
in
*
storagetypes
.
BatchQueryStorage
)
(
types
.
Message
,
error
)
{
return
BatchQueryStorage
(
s
.
GetStateDB
(),
in
)
}
plugin/dapp/storage/executor/storage.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
log
"github.com/33cn/chain33/common/log/log15"
drivers
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 执行器相关定义
* 重载基类相关接口
*/
var
(
//日志
elog
=
log
.
New
(
"module"
,
"storage.executor"
)
)
var
driverName
=
storagetypes
.
StorageX
// Init register dapp
func
Init
(
name
string
,
cfg
*
types
.
Chain33Config
,
sub
[]
byte
)
{
drivers
.
Register
(
cfg
,
GetName
(),
newStorage
,
cfg
.
GetDappFork
(
driverName
,
"Enable"
))
InitExecType
()
}
// InitExecType Init Exec Type
func
InitExecType
()
{
ety
:=
types
.
LoadExecutorType
(
driverName
)
ety
.
InitFuncList
(
types
.
ListMethod
(
&
storage
{}))
}
type
storage
struct
{
drivers
.
DriverBase
}
func
newStorage
()
drivers
.
Driver
{
t
:=
&
storage
{}
t
.
SetChild
(
t
)
t
.
SetExecutorType
(
types
.
LoadExecutorType
(
driverName
))
return
t
}
// GetName get driver name
func
GetName
()
string
{
return
newStorage
()
.
GetName
()
}
func
(
s
*
storage
)
GetDriverName
()
string
{
return
driverName
}
// CheckTx 实现自定义检验交易接口,供框架调用
func
(
s
*
storage
)
CheckTx
(
tx
*
types
.
Transaction
,
index
int
)
error
{
// implement code
return
nil
}
plugin/dapp/storage/executor/storage_test.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"math/rand"
"testing"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"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"
"github.com/33cn/chain33/queue"
des
"github.com/33cn/plugin/plugin/dapp/storage/crypto"
oty
"github.com/33cn/plugin/plugin/dapp/storage/types"
"github.com/stretchr/testify/assert"
"strings"
)
type
execEnv
struct
{
blockTime
int64
blockHeight
int64
difficulty
uint64
}
var
(
PrivKeyA
=
"0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
// 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
Nodes
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
contents
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
keys
=
[][]
byte
{
[]
byte
(
"123456ab"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScs"
),
[]
byte
(
"G2F4ED5m123456abx6vDrScsHD3psX7k"
),
}
ivs
=
[][]
byte
{
[]
byte
(
"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
),
[]
byte
(
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"
),
[]
byte
(
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"
),
[]
byte
(
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"
),
}
)
var
(
r
*
rand
.
Rand
)
func
init
()
{
r
=
rand
.
New
(
rand
.
NewSource
(
types
.
Now
()
.
UnixNano
()))
}
func
TestOrace
(
t
*
testing
.
T
)
{
cfg
:=
types
.
NewChain33Config
(
strings
.
Replace
(
types
.
GetDefaultCfgstring
(),
"Title=
\"
local
\"
"
,
"Title=
\"
chain33
\"
"
,
1
))
Init
(
oty
.
StorageX
,
cfg
,
nil
)
total
:=
100
*
types
.
Coin
accountA
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
0
]),
}
accountB
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
1
]),
}
accountC
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
2
]),
}
accountD
:=
types
.
Account
{
Balance
:
total
,
Frozen
:
0
,
Addr
:
string
(
Nodes
[
3
]),
}
execAddr
:=
address
.
ExecAddress
(
oty
.
StorageX
)
stateDB
,
_
:=
dbm
.
NewGoMemDB
(
"1"
,
"2"
,
1000
)
_
,
_
,
kvdb
:=
util
.
CreateTestDB
()
accA
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accA
.
SaveExecAccount
(
execAddr
,
&
accountA
)
accB
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accB
.
SaveExecAccount
(
execAddr
,
&
accountB
)
accC
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accC
.
SaveExecAccount
(
execAddr
,
&
accountC
)
accD
,
_
:=
account
.
NewAccountDB
(
cfg
,
"coins"
,
"bty"
,
stateDB
)
accD
.
SaveExecAccount
(
execAddr
,
&
accountD
)
env
:=
execEnv
{
10
,
cfg
.
GetDappFork
(
oty
.
StorageX
,
"Enable"
),
1539918074
,
}
// publish event
ety
:=
types
.
LoadExecutorType
(
oty
.
StorageX
)
tx
,
err
:=
ety
.
Create
(
"ContentStorage"
,
&
oty
.
ContentOnlyNotaryStorage
{
Content
:
contents
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
:=
newStorage
()
q
:=
queue
.
New
(
"channel"
)
q
.
SetConfig
(
cfg
)
api
,
_
:=
client
.
New
(
q
.
Client
(),
nil
)
exec
.
SetAPI
(
api
)
exec
.
SetStateDB
(
stateDB
)
exec
.
SetLocalDB
(
kvdb
)
exec
.
SetEnv
(
1
,
env
.
blockTime
,
env
.
difficulty
)
receipt
,
err
:=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
:=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
:=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
:=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
:=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
:=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
contents
[
0
],
reply
.
GetContentStorage
()
.
Content
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
:=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
contents
[
0
],
reply2
.
Storages
[
0
]
.
GetContentStorage
()
.
Content
)
tx
,
err
=
ety
.
Create
(
"HashStorage"
,
&
oty
.
HashOnlyNotaryStorage
{
Hash
:
common
.
Sha256
(
contents
[
0
])})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetHashStorage
()
.
Hash
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply2
.
Storages
[
0
]
.
GetHashStorage
()
.
Hash
)
//存储链接地址
tx
,
err
=
ety
.
Create
(
"LinkStorage"
,
&
oty
.
LinkNotaryStorage
{
Hash
:
common
.
Sha256
(
contents
[
0
]),
Link
:
contents
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetLinkStorage
()
.
Hash
)
//根据hash批量查询存储数据
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameBatchQueryStorage
,
types
.
Encode
(
&
oty
.
BatchQueryStorage
{
TxHashs
:
[]
string
{
txhash
}}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply2
=
msg
.
(
*
oty
.
BatchReplyStorage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply2
.
Storages
[
0
]
.
GetLinkStorage
()
.
Hash
)
//加密存储
aes
:=
des
.
NewAES
(
keys
[
2
],
ivs
[
0
])
crypted
,
err
:=
aes
.
Encrypt
(
contents
[
0
])
if
err
!=
nil
{
t
.
Error
(
err
)
}
tx
,
err
=
ety
.
Create
(
"EncryptStorage"
,
&
oty
.
EncryptNotaryStorage
{
ContentHash
:
common
.
Sha256
(
contents
[
0
]),
EncryptContent
:
crypted
,
Nonce
:
ivs
[
0
]})
assert
.
Nil
(
t
,
err
)
tx
,
err
=
types
.
FormatTx
(
cfg
,
oty
.
StorageX
,
tx
)
assert
.
Nil
(
t
,
err
)
tx
,
err
=
signTx
(
tx
,
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
t
.
Log
(
"tx"
,
tx
)
exec
.
SetEnv
(
env
.
blockHeight
+
1
,
env
.
blockTime
+
20
,
env
.
difficulty
+
1
)
receipt
,
err
=
exec
.
Exec
(
tx
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
receipt
.
KV
{
stateDB
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
receiptDate
=
&
types
.
ReceiptData
{
Ty
:
receipt
.
Ty
,
Logs
:
receipt
.
Logs
}
set
,
err
=
exec
.
ExecLocal
(
tx
,
receiptDate
,
int
(
1
))
if
err
!=
nil
{
t
.
Error
(
err
)
}
for
_
,
kv
:=
range
set
.
KV
{
kvdb
.
Set
(
kv
.
Key
,
kv
.
Value
)
}
txhash
=
common
.
ToHex
(
tx
.
Hash
())
t
.
Log
(
"txhash:"
,
txhash
)
//根据hash查询存储得明文内容
msg
,
err
=
exec
.
Query
(
oty
.
FuncNameQueryStorage
,
types
.
Encode
(
&
oty
.
QueryStorage
{
TxHash
:
txhash
}))
if
err
!=
nil
{
t
.
Error
(
err
)
}
t
.
Log
(
msg
)
reply
=
msg
.
(
*
oty
.
Storage
)
assert
.
Equal
(
t
,
common
.
Sha256
(
contents
[
0
]),
reply
.
GetEncryptStorage
()
.
ContentHash
)
assert
.
Equal
(
t
,
crypted
,
reply
.
GetEncryptStorage
()
.
EncryptContent
)
assert
.
Equal
(
t
,
ivs
[
0
],
reply
.
GetEncryptStorage
()
.
Nonce
)
}
func
signTx
(
tx
*
types
.
Transaction
,
hexPrivKey
string
)
(
*
types
.
Transaction
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
oty
.
StorageX
,
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/storage/executor/storagedb.go
0 → 100644
View file @
c22e26c7
package
executor
import
(
"fmt"
"github.com/33cn/chain33/common"
dbm
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
"github.com/gogo/protobuf/proto"
)
type
StorageAction
struct
{
db
dbm
.
KV
txhash
[]
byte
fromaddr
string
blocktime
int64
height
int64
index
int
}
func
newStorageAction
(
s
*
storage
,
tx
*
types
.
Transaction
,
index
int
)
*
StorageAction
{
hash
:=
tx
.
Hash
()
fromaddr
:=
tx
.
From
()
return
&
StorageAction
{
s
.
GetStateDB
(),
hash
,
fromaddr
,
s
.
GetBlockTime
(),
s
.
GetHeight
(),
index
}
}
func
(
s
*
StorageAction
)
GetKVSet
(
payload
proto
.
Message
)
(
kvset
[]
*
types
.
KeyValue
)
{
kvset
=
append
(
kvset
,
&
types
.
KeyValue
{
Key
:
Key
(
common
.
ToHex
(
s
.
txhash
)),
Value
:
types
.
Encode
(
payload
)})
return
kvset
}
func
(
s
*
StorageAction
)
ContentStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
//TODO 这里可以加具体得文本内容限制,超过指定大小的数据不容许写到状态数据库中
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyContentStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
HashStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyHashStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
LinkStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyLinkStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
EncryptStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyEncryptStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
(
s
*
StorageAction
)
EncryptShareStorage
(
payload
proto
.
Message
)
(
*
types
.
Receipt
,
error
)
{
var
logs
[]
*
types
.
ReceiptLog
log
:=
&
types
.
ReceiptLog
{
Ty
:
storagetypes
.
TyEncryptShareStorageLog
}
logs
=
append
(
logs
,
log
)
kv
:=
s
.
GetKVSet
(
payload
)
receipt
:=
&
types
.
Receipt
{
Ty
:
types
.
ExecOk
,
KV
:
kv
,
Logs
:
logs
}
return
receipt
,
nil
}
func
QueryStorageByTxHash
(
db
dbm
.
KV
,
txhash
string
)
(
*
storagetypes
.
Storage
,
error
)
{
data
,
err
:=
db
.
Get
(
Key
(
txhash
))
if
err
!=
nil
{
elog
.
Debug
(
"QueryStorage"
,
"get"
,
err
)
return
nil
,
err
}
var
storage
storagetypes
.
Storage
//decode
err
=
types
.
Decode
(
data
,
&
storage
)
if
err
!=
nil
{
elog
.
Debug
(
"QueryStorage"
,
"decode"
,
err
)
return
nil
,
err
}
return
&
storage
,
nil
}
func
QueryStorage
(
db
dbm
.
KV
,
in
*
storagetypes
.
QueryStorage
)
(
types
.
Message
,
error
)
{
if
in
.
TxHash
==
""
{
return
nil
,
fmt
.
Errorf
(
"txhash can't equail nil"
)
}
return
QueryStorageByTxHash
(
db
,
in
.
TxHash
)
}
func
BatchQueryStorage
(
db
dbm
.
KV
,
in
*
storagetypes
.
BatchQueryStorage
)
(
types
.
Message
,
error
)
{
if
len
(
in
.
TxHashs
)
>
10
{
return
nil
,
fmt
.
Errorf
(
"The number of batch queries is too large! the maximux is %d,but current num %d"
,
10
,
len
(
in
.
TxHashs
))
}
var
storage
storagetypes
.
BatchReplyStorage
for
_
,
txhash
:=
range
in
.
TxHashs
{
msg
,
err
:=
QueryStorageByTxHash
(
db
,
txhash
)
if
err
!=
nil
{
return
msg
,
err
}
storage
.
Storages
=
append
(
storage
.
Storages
,
msg
)
}
return
&
storage
,
nil
}
plugin/dapp/storage/plugin.go
0 → 100644
View file @
c22e26c7
package
types
import
(
"github.com/33cn/chain33/pluginmgr"
"github.com/33cn/plugin/plugin/dapp/storage/commands"
"github.com/33cn/plugin/plugin/dapp/storage/executor"
"github.com/33cn/plugin/plugin/dapp/storage/rpc"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* 初始化dapp相关的组件
*/
func
init
()
{
pluginmgr
.
Register
(
&
pluginmgr
.
PluginBase
{
Name
:
storagetypes
.
StorageX
,
ExecName
:
executor
.
GetName
(),
Exec
:
executor
.
Init
,
Cmd
:
commands
.
Cmd
,
RPC
:
rpc
.
Init
,
})
}
plugin/dapp/storage/proto/Makefile
0 → 100644
View file @
c22e26c7
all
:
./create_protobuf.sh
plugin/dapp/storage/proto/create_protobuf.sh
0 → 100644
View file @
c22e26c7
#!/bin/sh
# proto生成命令,将pb.go文件生成到types/目录下, chain33_path支持引用chain33框架的proto文件
chain33_path
=
$(
go list
-f
'{{.Dir}}'
"github.com/33cn/chain33"
)
protoc
--go_out
=
plugins
=
grpc:../types ./
*
.proto
--proto_path
=
.
--proto_path
=
"
${
chain33_path
}
/types/proto/"
plugin/dapp/storage/proto/storage.proto
0 → 100644
View file @
c22e26c7
syntax
=
"proto3"
;
package
types
;
//后面如果有其他数据模型可继续往上面添加
message
Storage
{
oneof
value
{
ContentOnlyNotaryStorage
contentStorage
=
1
;
HashOnlyNotaryStorage
hashStorage
=
2
;
LinkNotaryStorage
linkStorage
=
3
;
EncryptNotaryStorage
encryptStorage
=
4
;
EncryptShareNotaryStorage
encryptShareStorage
=
5
;
}
}
message
StorageAction
{
oneof
value
{
ContentOnlyNotaryStorage
contentStorage
=
1
;
HashOnlyNotaryStorage
hashStorage
=
2
;
LinkNotaryStorage
linkStorage
=
3
;
EncryptNotaryStorage
encryptStorage
=
4
;
EncryptShareNotaryStorage
encryptShareStorage
=
5
;
}
int32
ty
=
6
;
}
// 内容存证模型
message
ContentOnlyNotaryStorage
{
//长度需要小于512k
bytes
content
=
1
;
}
//哈希存证模型,推荐使用sha256哈希,限制256位得摘要值
message
HashOnlyNotaryStorage
{
//长度固定为32字节
bytes
hash
=
1
;
}
// 链接存证模型
message
LinkNotaryStorage
{
//存证内容的链接,可以写入URL,或者其他可用于定位源文件得线索.
bytes
link
=
1
;
//源文件得hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
hash
=
2
;
}
// 隐私存证模型,如果一个文件需要存证,且不公开内容,可以选择将源文件通过对称加密算法加密后上链
message
EncryptNotaryStorage
{
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
contentHash
=
1
;
//源文件得密文,由加密key及nonce对明文加密得到该值。
bytes
encryptContent
=
2
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
3
;
}
// 隐私存证模型
message
EncryptContentOnlyNotaryStorage
{
//存证内容的hash值,推荐使用sha256哈希,限制256位得摘要值
// bytes contentHash = 1;
//源文件得密文。
bytes
encryptContent
=
1
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
2
;
}
// 分享隐私存证模型,需要完备的sdk或者相应的密钥库支持
message
EncryptShareNotaryStorage
{
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes
contentHash
=
1
;
//源文件得密文。
bytes
encryptContent
=
2
;
//密钥的kdf推导路径。密钥tree父节点根据该路径可以推导出私钥key
bytes
keyName
=
3
;
//加密key的wrap key。加密key随机生成,对明文进行加密,该key有私密key进行key wrap后公开。
//使用时,通过私密key对wrap key解密得到加密key对密文进行解密。
bytes
keyWrap
=
4
;
//加密iv,通过AES进行加密时制定随机生成的iv,解密时需要使用该值
bytes
nonce
=
5
;
}
service
storage
{
}
//根据txhash去状态数据库中查询存储内容
message
QueryStorage
{
string
txHash
=
1
;
}
//批量查询有可能导致数据库崩溃
message
BatchQueryStorage
{
repeated
string
txHashs
=
1
;
}
message
BatchReplyStorage
{
repeated
Storage
storages
=
1
;
}
\ No newline at end of file
plugin/dapp/storage/rpc/rpc.go
0 → 100644
View file @
c22e26c7
package
rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
plugin/dapp/storage/rpc/types.go
0 → 100644
View file @
c22e26c7
package
rpc
import
(
rpctypes
"github.com/33cn/chain33/rpc/types"
storagetypes
"github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
* rpc相关结构定义和初始化
*/
// 实现grpc的service接口
type
channelClient
struct
{
rpctypes
.
ChannelClient
}
// Jrpc 实现json rpc调用实例
type
Jrpc
struct
{
cli
*
channelClient
}
// Grpc grpc
type
Grpc
struct
{
*
channelClient
}
// Init init rpc
func
Init
(
name
string
,
s
rpctypes
.
RPCServer
)
{
cli
:=
&
channelClient
{}
grpc
:=
&
Grpc
{
channelClient
:
cli
}
cli
.
Init
(
name
,
s
,
&
Jrpc
{
cli
:
cli
},
grpc
)
//存在grpc service时注册grpc server,需要生成对应的pb.go文件
storagetypes
.
RegisterStorageServer
(
s
.
GRPC
(),
grpc
)
}
plugin/dapp/storage/types/storage.go
0 → 100644
View file @
c22e26c7
package
types
import
(
"github.com/33cn/chain33/types"
)
/*
* 交易相关类型定义
* 交易action通常有对应的log结构,用于交易回执日志记录
* 每一种action和log需要用id数值和name名称加以区分
*/
// action类型id和name,这些常量可以自定义修改
const
(
TyUnknowAction
=
iota
TyContentStorageAction
TyHashStorageAction
TyLinkStorageAction
TyEncryptStorageAction
TyEncryptShareStorageAction
NameContentStorageAction
=
"ContentStorage"
NameHashStorageAction
=
"HashStorage"
NameLinkStorageAction
=
"LinkStorage"
NameEncryptStorageAction
=
"EncryptStorage"
NameEncryptShareStorageAction
=
"EncryptShareStorage"
FuncNameQueryStorage
=
"QueryStorage"
FuncNameBatchQueryStorage
=
"BatchQueryStorage"
)
// log类型id值
const
(
TyUnknownLog
=
iota
TyContentStorageLog
TyHashStorageLog
TyLinkStorageLog
TyEncryptStorageLog
TyEncryptShareStorageLog
)
var
(
//StorageX 执行器名称定义
StorageX
=
"storage"
//定义actionMap
actionMap
=
map
[
string
]
int32
{
NameContentStorageAction
:
TyContentStorageAction
,
NameHashStorageAction
:
TyHashStorageAction
,
NameLinkStorageAction
:
TyLinkStorageAction
,
NameEncryptStorageAction
:
TyEncryptStorageAction
,
NameEncryptShareStorageAction
:
TyEncryptShareStorageAction
,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap
=
map
[
int64
]
*
types
.
LogInfo
{
//LogID: {Ty: reflect.TypeOf(LogStruct), Name: LogName},
}
//tlog = log.New("module", "storage.types")
)
// init defines a register function
func
init
()
{
types
.
AllowUserExec
=
append
(
types
.
AllowUserExec
,
[]
byte
(
StorageX
))
//注册合约启用高度
types
.
RegFork
(
StorageX
,
InitFork
)
types
.
RegExec
(
StorageX
,
InitExecutor
)
}
// InitFork defines register fork
func
InitFork
(
cfg
*
types
.
Chain33Config
)
{
cfg
.
RegisterDappFork
(
StorageX
,
"Enable"
,
0
)
}
// InitExecutor defines register executor
func
InitExecutor
(
cfg
*
types
.
Chain33Config
)
{
types
.
RegistorExecutor
(
StorageX
,
NewType
(
cfg
))
}
type
StorageType
struct
{
types
.
ExecTypeBase
}
func
NewType
(
cfg
*
types
.
Chain33Config
)
*
StorageType
{
c
:=
&
StorageType
{}
c
.
SetChild
(
c
)
c
.
SetConfig
(
cfg
)
return
c
}
// GetPayload 获取合约action结构
func
(
s
*
StorageType
)
GetPayload
()
types
.
Message
{
return
&
StorageAction
{}
}
// GeTypeMap 获取合约action的id和name信息
func
(
s
*
StorageType
)
GetTypeMap
()
map
[
string
]
int32
{
return
actionMap
}
// GetLogMap 获取合约log相关信息
func
(
s
*
StorageType
)
GetLogMap
()
map
[
int64
]
*
types
.
LogInfo
{
return
logMap
}
plugin/dapp/storage/types/storage.pb.go
0 → 100644
View file @
c22e26c7
This diff is collapsed.
Click to expand it.
plugin/dapp/ticket/commands/ticket.go
View file @
c22e26c7
...
@@ -29,6 +29,7 @@ func TicketCmd() *cobra.Command {
...
@@ -29,6 +29,7 @@ func TicketCmd() *cobra.Command {
CountTicketCmd
(),
CountTicketCmd
(),
CloseTicketCmd
(),
CloseTicketCmd
(),
GetColdAddrByMinerCmd
(),
GetColdAddrByMinerCmd
(),
listTicketCmd
(),
)
)
return
cmd
return
cmd
...
@@ -97,6 +98,41 @@ func countTicket(cmd *cobra.Command, args []string) {
...
@@ -97,6 +98,41 @@ func countTicket(cmd *cobra.Command, args []string) {
ctx
.
Run
()
ctx
.
Run
()
}
}
// listTicketCmd get ticket count
func
listTicketCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
Use
:
"list"
,
Short
:
"Get ticket id list"
,
Run
:
listTicket
,
}
cmd
.
Flags
()
.
StringP
(
"miner_acct"
,
"m"
,
""
,
"miner address (optional)"
)
cmd
.
Flags
()
.
Int32P
(
"status"
,
"s"
,
1
,
"ticket status (default 1:opened tickets)"
)
return
cmd
}
func
listTicket
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
rpcLaddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"rpc_laddr"
)
minerAddr
,
_
:=
cmd
.
Flags
()
.
GetString
(
"miner_acct"
)
status
,
_
:=
cmd
.
Flags
()
.
GetInt32
(
"status"
)
if
minerAddr
!=
""
{
var
params
rpctypes
.
Query4Jrpc
params
.
Execer
=
ty
.
TicketX
params
.
FuncName
=
"TicketList"
req
:=
ty
.
TicketList
{
Addr
:
minerAddr
,
Status
:
status
}
params
.
Payload
=
types
.
MustPBToJSON
(
&
req
)
var
res
ty
.
ReplyTicketList
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"Chain33.Query"
,
params
,
&
res
)
ctx
.
Run
()
return
}
var
res
[]
ty
.
Ticket
ctx
:=
jsonclient
.
NewRPCCtx
(
rpcLaddr
,
"ticket.GetTicketList"
,
nil
,
&
res
)
ctx
.
Run
()
}
// CloseTicketCmd close all accessible tickets
// CloseTicketCmd close all accessible tickets
func
CloseTicketCmd
()
*
cobra
.
Command
{
func
CloseTicketCmd
()
*
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
cmd
:=
&
cobra
.
Command
{
...
...
plugin/dapp/ticket/executor/exec_test.go
0 → 100644
View file @
c22e26c7
// 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_test
import
(
"testing"
apimock
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
executor
"github.com/33cn/plugin/plugin/dapp/ticket/executor"
pty
"github.com/33cn/plugin/plugin/dapp/ticket/types"
)
type
execEnv
struct
{
blockTime
int64
// 1539918074
blockHeight
int64
index
int
difficulty
uint64
txHash
string
}
var
(
Symbol
=
"TEST"
SymbolA
=
"TESTA"
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"
),
}
//chain33TestCfg = types.NewChain33Config(strings.Replace(types.GetDefaultCfgstring(), "Title=\"local\"", "Title=\"chain33\"", 1))
)
func
Test_Exec_Bind_Unbind
(
t
*
testing
.
T
)
{
chain33TestCfg
:=
mock33
.
GetAPI
()
.
GetConfig
()
env
:=
execEnv
{
1539918074
,
10000
,
2
,
1539918074
,
"hash"
,
}
_
,
ldb
,
kvdb
:=
util
.
CreateTestDB
()
api
:=
new
(
apimock
.
QueueProtocolAPI
)
api
.
On
(
"GetConfig"
,
mock
.
Anything
)
.
Return
(
chain33TestCfg
,
nil
)
driver
,
err
:=
dapp
.
LoadDriver
(
"ticket"
,
1000
)
assert
.
Nil
(
t
,
err
)
driver
.
SetAPI
(
api
)
driver
.
SetEnv
(
env
.
blockHeight
,
env
.
blockTime
,
env
.
difficulty
)
driver
.
SetStateDB
(
kvdb
)
driver
.
SetLocalDB
(
kvdb
)
priv
,
err
:=
FromPrivkey
(
PrivKeyA
)
assert
.
Nil
(
t
,
err
)
bindTx
:=
createBindMiner
(
t
,
chain33TestCfg
,
string
(
Nodes
[
1
]),
string
(
Nodes
[
0
]),
priv
)
receipt
,
err
:=
driver
.
Exec
(
bindTx
,
env
.
index
)
if
err
!=
nil
{
assert
.
Nil
(
t
,
err
,
"exec failed"
)
return
}
assert
.
Equal
(
t
,
1
,
len
(
receipt
.
KV
))
assert
.
Equal
(
t
,
executor
.
BindKey
(
string
(
Nodes
[
0
])),
receipt
.
KV
[
0
]
.
Key
)
var
bindInfo
pty
.
TicketBind
err
=
types
.
Decode
(
receipt
.
KV
[
0
]
.
Value
,
&
bindInfo
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
string
(
Nodes
[
1
]),
bindInfo
.
MinerAddress
)
assert
.
Equal
(
t
,
string
(
Nodes
[
0
]),
bindInfo
.
ReturnAddress
)
unbindTx
:=
createBindMiner
(
t
,
chain33TestCfg
,
""
,
string
(
Nodes
[
0
]),
priv
)
receipt
,
err
=
driver
.
Exec
(
unbindTx
,
env
.
index
)
if
err
!=
nil
{
assert
.
Nil
(
t
,
err
,
"exec failed"
)
return
}
assert
.
Equal
(
t
,
1
,
len
(
receipt
.
KV
))
assert
.
Equal
(
t
,
executor
.
BindKey
(
string
(
Nodes
[
0
])),
receipt
.
KV
[
0
]
.
Key
)
var
bindInfo2
pty
.
TicketBind
err
=
types
.
Decode
(
receipt
.
KV
[
0
]
.
Value
,
&
bindInfo2
)
assert
.
Nil
(
t
,
err
)
assert
.
Equal
(
t
,
""
,
bindInfo2
.
MinerAddress
)
assert
.
Equal
(
t
,
string
(
Nodes
[
0
]),
bindInfo2
.
ReturnAddress
)
ldb
.
Close
()
}
func
FromPrivkey
(
hexPrivKey
string
)
(
crypto
.
PrivKey
,
error
)
{
signType
:=
types
.
SECP256K1
c
,
err
:=
crypto
.
New
(
types
.
GetSignName
(
"ticket"
,
signType
))
if
err
!=
nil
{
return
nil
,
err
}
bytes
,
err
:=
common
.
FromHex
(
hexPrivKey
[
:
])
if
err
!=
nil
{
return
nil
,
err
}
return
c
.
PrivKeyFromBytes
(
bytes
)
}
plugin/dapp/ticket/executor/ticket_test.go
View file @
c22e26c7
...
@@ -3,6 +3,7 @@ package executor_test
...
@@ -3,6 +3,7 @@ package executor_test
import
(
import
(
"encoding/hex"
"encoding/hex"
"fmt"
"fmt"
"os"
"strings"
"strings"
"testing"
"testing"
...
@@ -26,8 +27,9 @@ var mock33 *testnode.Chain33Mock
...
@@ -26,8 +27,9 @@ var mock33 *testnode.Chain33Mock
func
TestMain
(
m
*
testing
.
M
)
{
func
TestMain
(
m
*
testing
.
M
)
{
mock33
=
testnode
.
New
(
"testdata/chain33.cfg.toml"
,
nil
)
mock33
=
testnode
.
New
(
"testdata/chain33.cfg.toml"
,
nil
)
mock33
.
Listen
()
mock33
.
Listen
()
m
.
Run
()
code
:=
m
.
Run
()
mock33
.
Close
()
mock33
.
Close
()
os
.
Exit
(
code
)
}
}
func
TestTicketPrice
(
t
*
testing
.
T
)
{
func
TestTicketPrice
(
t
*
testing
.
T
)
{
...
...
plugin/dapp/ticket/executor/ticketdb.go
View file @
c22e26c7
...
@@ -51,7 +51,7 @@ func NewDB(cfg *types.Chain33Config, id, minerAddress, returnWallet string, bloc
...
@@ -51,7 +51,7 @@ func NewDB(cfg *types.Chain33Config, id, minerAddress, returnWallet string, bloc
t
.
MinerAddress
=
minerAddress
t
.
MinerAddress
=
minerAddress
t
.
ReturnAddress
=
returnWallet
t
.
ReturnAddress
=
returnWallet
t
.
CreateTime
=
blocktime
t
.
CreateTime
=
blocktime
t
.
Status
=
1
t
.
Status
=
ty
.
TicketOpened
t
.
IsGenesis
=
isGenesis
t
.
IsGenesis
=
isGenesis
t
.
prevstatus
=
0
t
.
prevstatus
=
0
//height == 0 的情况下,不去改变 genesis block
//height == 0 的情况下,不去改变 genesis block
...
@@ -73,11 +73,11 @@ func NewDB(cfg *types.Chain33Config, id, minerAddress, returnWallet string, bloc
...
@@ -73,11 +73,11 @@ func NewDB(cfg *types.Chain33Config, id, minerAddress, returnWallet string, bloc
// GetReceiptLog get receipt
// GetReceiptLog get receipt
func
(
t
*
DB
)
GetReceiptLog
()
*
types
.
ReceiptLog
{
func
(
t
*
DB
)
GetReceiptLog
()
*
types
.
ReceiptLog
{
log
:=
&
types
.
ReceiptLog
{}
log
:=
&
types
.
ReceiptLog
{}
if
t
.
Status
==
1
{
if
t
.
Status
==
ty
.
TicketOpened
{
log
.
Ty
=
ty
.
TyLogNewTicket
log
.
Ty
=
ty
.
TyLogNewTicket
}
else
if
t
.
Status
==
2
{
}
else
if
t
.
Status
==
ty
.
TicketMined
{
log
.
Ty
=
ty
.
TyLogMinerTicket
log
.
Ty
=
ty
.
TyLogMinerTicket
}
else
if
t
.
Status
==
3
{
}
else
if
t
.
Status
==
ty
.
TicketClosed
{
log
.
Ty
=
ty
.
TyLogCloseTicket
log
.
Ty
=
ty
.
TyLogCloseTicket
}
}
r
:=
&
ty
.
ReceiptTicket
{}
r
:=
&
ty
.
ReceiptTicket
{}
...
@@ -305,7 +305,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
...
@@ -305,7 +305,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
if
ticket
.
Status
!=
1
{
if
ticket
.
Status
!=
ty
.
TicketOpened
{
return
nil
,
types
.
ErrCoinBaseTicketStatus
return
nil
,
types
.
ErrCoinBaseTicketStatus
}
}
cfg
:=
ty
.
GetTicketMinerParam
(
chain33Cfg
,
action
.
height
)
cfg
:=
ty
.
GetTicketMinerParam
(
chain33Cfg
,
action
.
height
)
...
@@ -330,7 +330,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
...
@@ -330,7 +330,7 @@ func (action *Action) TicketMiner(miner *ty.TicketMiner, index int) (*types.Rece
}
}
}
}
prevstatus
:=
ticket
.
Status
prevstatus
:=
ticket
.
Status
ticket
.
Status
=
2
ticket
.
Status
=
ty
.
TicketMined
ticket
.
MinerValue
=
miner
.
Reward
ticket
.
MinerValue
=
miner
.
Reward
if
chain33Cfg
.
IsFork
(
action
.
height
,
"ForkMinerTime"
)
{
if
chain33Cfg
.
IsFork
(
action
.
height
,
"ForkMinerTime"
)
{
ticket
.
MinerTime
=
action
.
blocktime
ticket
.
MinerTime
=
action
.
blocktime
...
@@ -383,20 +383,20 @@ func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error
...
@@ -383,20 +383,20 @@ func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error
return
nil
,
err
return
nil
,
err
}
}
//ticket 的生成时间超过 2天,可提款
//ticket 的生成时间超过 2天,可提款
if
ticket
.
Status
!=
2
&&
ticket
.
Status
!=
1
{
if
ticket
.
Status
!=
ty
.
TicketMined
&&
ticket
.
Status
!=
ty
.
TicketOpened
{
tlog
.
Error
(
"ticket"
,
"id"
,
ticket
.
GetTicketId
(),
"status"
,
ticket
.
GetStatus
())
tlog
.
Error
(
"ticket"
,
"id"
,
ticket
.
GetTicketId
(),
"status"
,
ticket
.
GetStatus
())
return
nil
,
ty
.
ErrTicketClosed
return
nil
,
ty
.
ErrTicketClosed
}
}
if
!
ticket
.
IsGenesis
{
if
!
ticket
.
IsGenesis
{
//分成两种情况
//分成两种情况
if
ticket
.
Status
==
1
&&
action
.
blocktime
-
ticket
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
if
ticket
.
Status
==
ty
.
TicketOpened
&&
action
.
blocktime
-
ticket
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
return
nil
,
ty
.
ErrTime
return
nil
,
ty
.
ErrTime
}
}
//已经挖矿成功了
//已经挖矿成功了
if
ticket
.
Status
==
2
&&
action
.
blocktime
-
ticket
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
if
ticket
.
Status
==
ty
.
TicketMined
&&
action
.
blocktime
-
ticket
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
return
nil
,
ty
.
ErrTime
return
nil
,
ty
.
ErrTime
}
}
if
ticket
.
Status
==
2
&&
action
.
blocktime
-
ticket
.
GetMinerTime
()
<
cfg
.
TicketMinerWaitTime
{
if
ticket
.
Status
==
ty
.
TicketMined
&&
action
.
blocktime
-
ticket
.
GetMinerTime
()
<
cfg
.
TicketMinerWaitTime
{
return
nil
,
ty
.
ErrTime
return
nil
,
ty
.
ErrTime
}
}
}
}
...
@@ -405,7 +405,7 @@ func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error
...
@@ -405,7 +405,7 @@ func (action *Action) TicketClose(tclose *ty.TicketClose) (*types.Receipt, error
return
nil
,
types
.
ErrFromAddr
return
nil
,
types
.
ErrFromAddr
}
}
prevstatus
:=
ticket
.
Status
prevstatus
:=
ticket
.
Status
ticket
.
Status
=
3
ticket
.
Status
=
ty
.
TicketClosed
tickets
[
i
]
=
&
DB
{
*
ticket
,
prevstatus
}
tickets
[
i
]
=
&
DB
{
*
ticket
,
prevstatus
}
}
}
var
logs
[]
*
types
.
ReceiptLog
var
logs
[]
*
types
.
ReceiptLog
...
...
plugin/dapp/ticket/rpc/rpc.go
View file @
c22e26c7
...
@@ -28,11 +28,13 @@ func bindMiner(cfg *types.Chain33Config, param *ty.ReqBindMiner) (*ty.ReplyBindM
...
@@ -28,11 +28,13 @@ func bindMiner(cfg *types.Chain33Config, param *ty.ReqBindMiner) (*ty.ReplyBindM
// CreateBindMiner 创建绑定挖矿
// CreateBindMiner 创建绑定挖矿
func
(
g
*
channelClient
)
CreateBindMiner
(
ctx
context
.
Context
,
in
*
ty
.
ReqBindMiner
)
(
*
ty
.
ReplyBindMiner
,
error
)
{
func
(
g
*
channelClient
)
CreateBindMiner
(
ctx
context
.
Context
,
in
*
ty
.
ReqBindMiner
)
(
*
ty
.
ReplyBindMiner
,
error
)
{
err
:=
address
.
CheckAddress
(
in
.
BindAddr
)
if
in
.
BindAddr
!=
""
{
if
err
!=
nil
{
err
:=
address
.
CheckAddress
(
in
.
BindAddr
)
return
nil
,
err
if
err
!=
nil
{
return
nil
,
err
}
}
}
err
=
address
.
CheckAddress
(
in
.
OriginAddr
)
err
:
=
address
.
CheckAddress
(
in
.
OriginAddr
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -141,3 +143,25 @@ func (c *Jrpc) SetAutoMining(in *ty.MinerFlag, result *rpctypes.Reply) error {
...
@@ -141,3 +143,25 @@ func (c *Jrpc) SetAutoMining(in *ty.MinerFlag, result *rpctypes.Reply) error {
*
result
=
reply
*
result
=
reply
return
nil
return
nil
}
}
// GetTicketList get ticket list info
func
(
g
*
channelClient
)
GetTicketList
(
ctx
context
.
Context
,
in
*
types
.
ReqNil
)
([]
*
ty
.
Ticket
,
error
)
{
inn
:=
*
in
data
,
err
:=
g
.
ExecWalletFunc
(
ty
.
TicketX
,
"WalletGetTickets"
,
&
inn
)
if
err
!=
nil
{
return
nil
,
err
}
return
data
.
(
*
ty
.
ReplyWalletTickets
)
.
Tickets
,
nil
}
// GetTicketList get ticket list info
func
(
c
*
Jrpc
)
GetTicketList
(
in
*
types
.
ReqNil
,
result
*
interface
{})
error
{
resp
,
err
:=
c
.
cli
.
GetTicketList
(
context
.
Background
(),
&
types
.
ReqNil
{})
if
err
!=
nil
{
return
err
}
*
result
=
resp
return
nil
}
plugin/dapp/ticket/rpc/rpc_test.go
View file @
c22e26c7
...
@@ -58,6 +58,15 @@ func TestChannelClient_BindMiner(t *testing.T) {
...
@@ -58,6 +58,15 @@ func TestChannelClient_BindMiner(t *testing.T) {
}
}
_
,
err
:=
client
.
CreateBindMiner
(
context
.
Background
(),
in
)
_
,
err
:=
client
.
CreateBindMiner
(
context
.
Background
(),
in
)
assert
.
Nil
(
t
,
err
)
assert
.
Nil
(
t
,
err
)
var
in2
=
&
ty
.
ReqBindMiner
{
BindAddr
:
""
,
OriginAddr
:
"1Jn2qu84Z1SUUosWjySggBS9pKWdAP3tZt"
,
Amount
:
10000
*
types
.
Coin
,
CheckBalance
:
false
,
}
_
,
err
=
client
.
CreateBindMiner
(
context
.
Background
(),
in2
)
assert
.
Nil
(
t
,
err
)
}
}
func
testGetTicketCountOK
(
t
*
testing
.
T
)
{
func
testGetTicketCountOK
(
t
*
testing
.
T
)
{
...
...
plugin/dapp/ticket/types/ticket.go
View file @
c22e26c7
...
@@ -13,6 +13,18 @@ import (
...
@@ -13,6 +13,18 @@ import (
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/types"
)
)
// 0 -> 未成熟 1 -> 可挖矿 2 -> 已挖成功 3-> 已关闭
const
(
//TicketInit ticket init status
TicketInit
=
iota
//TicketOpened ticket opened status
TicketOpened
//TicketMined ticket mined status
TicketMined
//TicketClosed ticket closed status
TicketClosed
)
const
(
const
(
//log for ticket
//log for ticket
...
...
plugin/dapp/ticket/wallet/ticket.go
View file @
c22e26c7
...
@@ -406,13 +406,13 @@ func (policy *ticketPolicy) forceCloseTicketList(height int64, priv crypto.PrivK
...
@@ -406,13 +406,13 @@ func (policy *ticketPolicy) forceCloseTicketList(height int64, priv crypto.PrivK
cfg
:=
ty
.
GetTicketMinerParam
(
chain33Cfg
,
height
)
cfg
:=
ty
.
GetTicketMinerParam
(
chain33Cfg
,
height
)
for
_
,
t
:=
range
tlist
{
for
_
,
t
:=
range
tlist
{
if
!
t
.
IsGenesis
{
if
!
t
.
IsGenesis
{
if
t
.
Status
==
1
&&
now
-
t
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
if
t
.
Status
==
ty
.
TicketOpened
&&
now
-
t
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
continue
continue
}
}
if
t
.
Status
==
2
&&
now
-
t
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
if
t
.
Status
==
ty
.
TicketMined
&&
now
-
t
.
GetCreateTime
()
<
cfg
.
TicketWithdrawTime
{
continue
continue
}
}
if
t
.
Status
==
2
&&
now
-
t
.
GetMinerTime
()
<
cfg
.
TicketMinerWaitTime
{
if
t
.
Status
==
ty
.
TicketMined
&&
now
-
t
.
GetMinerTime
()
<
cfg
.
TicketMinerWaitTime
{
continue
continue
}
}
}
}
...
...
plugin/dapp/ticket/wallet/ticket_test.go
View file @
c22e26c7
...
@@ -40,10 +40,16 @@ func TestForceCloseTicketList(t *testing.T) {
...
@@ -40,10 +40,16 @@ func TestForceCloseTicketList(t *testing.T) {
wallet
.
api
=
qapi
wallet
.
api
=
qapi
ticket
.
walletOperate
=
wallet
ticket
.
walletOperate
=
wallet
t1
:=
&
ty
.
Ticket
{
Status
:
1
,
IsGenesis
:
false
}
t1
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketOpened
,
IsGenesis
:
false
}
t2
:=
&
ty
.
Ticket
{
Status
:
2
,
IsGenesis
:
false
}
t2
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketMined
,
IsGenesis
:
false
}
t3
:=
&
ty
.
Ticket
{
Status
:
3
,
IsGenesis
:
false
}
t3
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketClosed
,
IsGenesis
:
false
}
tlist
:=
[]
*
ty
.
Ticket
{
t1
,
t2
,
t3
}
now
:=
types
.
Now
()
.
Unix
()
t4
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketOpened
,
IsGenesis
:
false
,
CreateTime
:
now
}
t5
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketMined
,
IsGenesis
:
false
,
CreateTime
:
now
}
t6
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketMined
,
IsGenesis
:
false
,
MinerTime
:
now
}
tlist
:=
[]
*
ty
.
Ticket
{
t1
,
t2
,
t3
,
t4
,
t5
,
t6
}
r1
,
r2
:=
ticket
.
forceCloseTicketList
(
0
,
nil
,
tlist
)
r1
,
r2
:=
ticket
.
forceCloseTicketList
(
0
,
nil
,
tlist
)
assert
.
Equal
(
t
,
[]
byte
(
sendhash
),
r1
)
assert
.
Equal
(
t
,
[]
byte
(
sendhash
),
r1
)
...
@@ -69,9 +75,9 @@ func TestCloseTicketsByAddr(t *testing.T) {
...
@@ -69,9 +75,9 @@ func TestCloseTicketsByAddr(t *testing.T) {
wallet
.
api
=
qapi
wallet
.
api
=
qapi
ticket
.
walletOperate
=
wallet
ticket
.
walletOperate
=
wallet
t1
:=
&
ty
.
Ticket
{
Status
:
1
,
IsGenesis
:
false
}
t1
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketOpened
,
IsGenesis
:
false
}
t2
:=
&
ty
.
Ticket
{
Status
:
2
,
IsGenesis
:
false
}
t2
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketMined
,
IsGenesis
:
false
}
t3
:=
&
ty
.
Ticket
{
Status
:
3
,
IsGenesis
:
false
}
t3
:=
&
ty
.
Ticket
{
Status
:
ty
.
TicketClosed
,
IsGenesis
:
false
}
tlist
:=
&
ty
.
ReplyTicketList
{
Tickets
:
[]
*
ty
.
Ticket
{
t1
,
t2
,
t3
}}
tlist
:=
&
ty
.
ReplyTicketList
{
Tickets
:
[]
*
ty
.
Ticket
{
t1
,
t2
,
t3
}}
qapi
.
On
(
"Query"
,
ty
.
TicketX
,
"TicketList"
,
mock
.
Anything
)
.
Return
(
tlist
,
nil
)
qapi
.
On
(
"Query"
,
ty
.
TicketX
,
"TicketList"
,
mock
.
Anything
)
.
Return
(
tlist
,
nil
)
...
...
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