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
9f95ccab
Commit
9f95ccab
authored
Dec 03, 2019
by
pengjun
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master'
parents
5523229c
94b4b613
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
1717 additions
and
46 deletions
+1717
-46
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
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
No files found.
build/dapp-test-common.sh
View file @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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
...
...
plugin/dapp/init/init.go
View file @
9f95ccab
...
@@ -22,6 +22,7 @@ import (
...
@@ -22,6 +22,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 @
9f95ccab
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/cmd/scripts/autodeploy/Dockerfile
0 → 100644
View file @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
#!/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 @
9f95ccab
version
:
'
3'
services
:
\ No newline at end of file
plugin/dapp/paracross/cmd/scripts/autodeploy/entrypoint.sh
0 → 100755
View file @
9f95ccab
#!/usr/bin/env bash
/root/chain33
-f
"
$PARAFILE
"
plugin/dapp/paracross/cmd/test/test-rpc.sh
View file @
9f95ccab
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/commands/paracross.go
View file @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
...
@@ -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 @
9f95ccab
This diff is collapsed.
Click to expand it.
plugin/dapp/paracross/types/type.go
View file @
9f95ccab
...
@@ -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 @
9f95ccab
all
:
chmod
+x ./build.sh
./build.sh
$(OUT)
$(FLAG)
plugin/dapp/storage/cmd/build.sh
0 → 100755
View file @
9f95ccab
#!/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 @
9f95ccab
/*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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
all
:
./create_protobuf.sh
plugin/dapp/storage/proto/create_protobuf.sh
0 → 100644
View file @
9f95ccab
#!/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 @
9f95ccab
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 @
9f95ccab
package
rpc
/*
* 实现json rpc和grpc service接口
* json rpc用Jrpc结构作为接收实例
* grpc使用channelClient结构作为接收实例
*/
plugin/dapp/storage/rpc/types.go
0 → 100644
View file @
9f95ccab
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 @
9f95ccab
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 @
9f95ccab
This diff is collapsed.
Click to expand it.
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