Unverified Commit 11c2be11 authored by linj's avatar linj Committed by GitHub

Merge branch 'master' into trade-query-use-localdb2

parents c1f09ca9 232133ee
......@@ -121,6 +121,13 @@ docker-compose-down: ## build docker-compose for chain33 run
fi; \
cd ..
metrics:## build docker-compose for chain33 metrics
@cd build && if ! [ -d ci ]; then \
make -C ../ ; \
fi; \
cp chain33* Dockerfile docker-compose.yml docker-compose-metrics.yml influxdb.conf *.sh ci/paracross/testcase.sh metrics/ && ./docker-compose-pre.sh run $(proj) metrics && cd ../..
fork-test: ## build fork-test for chain33 run
@cd build && cp chain33* Dockerfile system-fork-test.sh docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh forktest $(proj) $(dapp) && cd ../..
......@@ -135,6 +142,7 @@ clean: ## Remove previous build
@rm -rf build/ci
@rm -rf build/system-rpc-test.sh
@rm -rf tool
@cd build/metrics && find * -not -name readme.md | xargs rm -fr && cd ../..
@go clean
proto:protobuf
......
version: '3'
services:
chain33:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para33.toml"
expose:
- "8802"
chain32:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para32.toml"
chain31:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para31.toml"
chain30:
entrypoint: /root/entrypoint.sh
environment:
PARAFILE: "/root/chain33.para30.toml"
expose:
- "8802"
nginx:
image: nginx:latest
depends_on:
- chain33
- chain30
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
expose:
- "8803"
influxdb:
image: influxdb:latest
environment:
INFLUXDB_DB: "db"
volumes:
- ./influxdb.conf:/etc/influxdb/influxdb.conf
expose:
- "8089/udp"
- "8086"
grafana:
image: grafana/grafana
expose:
- "3000"
......@@ -37,12 +37,22 @@ function run_dapp() {
local test=$2
echo "============ run dapp=$app start ================="
rm -rf "${app}"-ci && mkdir -p "${app}"-ci && cp ./"${app}"/* ./"${app}"-ci && echo $?
cp -n ./* ./"${app}"-ci/ && echo $?
if [ "$app" == "paracross" ]; then
cp -r dapptest/ "${app}"-ci/ && echo $?
if [ "$app" == "metrics" ]; then
cp ./ci/paracross/* ./metrics && echo $?
cp -n ./* ./metrics/ && echo $?
cp -r ci/dapptest/ metrics/ && echo $?
cd metrics && pwd
rm docker-compose-paracross.yml
mv docker-compose-metrics.yml docker-compose-paracross.yml
app="paracross"
else
rm -rf "${app}"-ci && mkdir -p "${app}"-ci && cp ./"${app}"/* ./"${app}"-ci && echo $?
cp -n ./* ./"${app}"-ci/ && echo $?
if [ "$app" == "paracross" ]; then
cp -r dapptest/ "${app}"-ci/ && echo $?
fi
cd "${app}"-ci/ && pwd
fi
cd "${app}"-ci/ && pwd
if [ "$test" == "$FORKTESTFILE" ]; then
sed -i $sedfix 's/^system_coins_file=.*/system_coins_file="..\/system\/coins\/fork-test.sh"/g' system-fork-test.sh
......
......@@ -131,6 +131,14 @@ function start() {
docker-compose ps
set +e
influxdbcontainer=$(docker ps -a | grep build_influxdb_1)
if [ -n "$influxdbcontainer" ]; then
echo "create database chain33metrics in docker container build_influxdb_1"
docker exec build_influxdb_1 influx -execute 'create database chain33metrics'
fi
set -e
# query node run status
check_docker_status
${CLI} block last_header
......
reporting-disabled = false
bind-address = "127.0.0.1:8088"
[meta]
dir = "/var/lib/influxdb/meta"
retention-autocreate = true
logging-enabled = true
[data]
dir = "/var/lib/influxdb/data"
index-version = "inmem"
wal-dir = "/var/lib/influxdb/wal"
wal-fsync-delay = "0s"
validate-keys = false
query-log-enabled = true
cache-max-memory-size = 1073741824
cache-snapshot-memory-size = 26214400
cache-snapshot-write-cold-duration = "10m0s"
compact-full-write-cold-duration = "4h0m0s"
compact-throughput = 50331648
compact-throughput-burst = 50331648
max-series-per-database = 1000000
max-values-per-tag = 100000
max-concurrent-compactions = 0
max-index-log-file-size = 1048576
trace-logging-enabled = false
tsm-use-madv-willneed = false
[coordinator]
write-timeout = "10s"
max-concurrent-queries = 0
query-timeout = "0s"
log-queries-after = "0s"
max-select-point = 0
max-select-series = 0
max-select-buckets = 0
[retention]
enabled = true
check-interval = "30m0s"
[shard-precreation]
enabled = true
check-interval = "10m0s"
advance-period = "30m0s"
[monitor]
store-enabled = true
store-database = "_internal"
store-interval = "10s"
[subscriber]
enabled = true
http-timeout = "30s"
insecure-skip-verify = false
ca-certs = ""
write-concurrency = 40
write-buffer-size = 1000
[http]
enabled = true
bind-address = ":8086"
auth-enabled = false
log-enabled = true
suppress-write-log = false
write-tracing = false
flux-enabled = false
pprof-enabled = true
debug-pprof-enabled = false
https-enabled = false
https-certificate = "/etc/ssl/influxdb.pem"
https-private-key = ""
max-row-limit = 0
max-connection-limit = 0
shared-secret = ""
realm = "InfluxDB"
unix-socket-enabled = false
unix-socket-permissions = "0777"
bind-socket = "/var/run/influxdb.sock"
max-body-size = 25000000
access-log-path = ""
max-concurrent-write-limit = 0
max-enqueued-write-limit = 0
enqueued-write-timeout = 30000000000
[logging]
format = "auto"
level = "info"
suppress-logo = false
[[graphite]]
enabled = false
bind-address = ":2003"
database = "graphite"
retention-policy = ""
protocol = "tcp"
batch-size = 5000
batch-pending = 10
batch-timeout = "1s"
consistency-level = "one"
separator = "."
udp-read-buffer = 0
[[collectd]]
enabled = false
bind-address = ":25826"
database = "collectd"
retention-policy = ""
batch-size = 5000
batch-pending = 10
batch-timeout = "10s"
read-buffer = 0
typesdb = "/usr/share/collectd/types.db"
security-level = "none"
auth-file = "/etc/collectd/auth_file"
parse-multivalue-plugin = "split"
[[opentsdb]]
enabled = false
bind-address = ":4242"
database = "opentsdb"
retention-policy = ""
consistency-level = "one"
tls-enabled = false
certificate = "/etc/ssl/influxdb.pem"
batch-size = 1000
batch-pending = 5
batch-timeout = "1s"
log-point-errors = true
[[udp]]
enabled = true
bind-address = ":8089"
database = "db"
retention-policy = ""
batch-size = 1
batch-pending = 1
read-buffer = 0
batch-timeout = "1s"
precision = ""
[continuous_queries]
log-enabled = true
enabled = true
query-stats-enabled = false
run-interval = "1s"
[tls]
min-version = ""
max-version = ""
# Metrics 功能
* 通过make metrics来测试plugin的metrics数据收集功能
* 在容器build_influxdb_1中运行以下语句,查看结果:
```
1.influx 进入influxdb交互界面
```
```
2.use chain33metrics
```
```
3.show field keys
```
```
4.使用select进行查询,如select * from mesurment
```
* 数据的可视化展示可以通过Grafana工具进行展示,只需要访问以下链接:
http://build_grafana_1:3000,更多的操作可以参考以下链接中的使用Grafana工具展示部分
......@@ -324,3 +324,18 @@ ForkKvmvccmavl=0
[pprof]
listenAddr = "localhost:6061"
[metrics]
#是否使能发送metrics数据的发送
enableMetrics=true
#数据保存模式
dataEmitMode="influxdb"
[metrics.sub.influxdb]
#以纳秒为单位的发送间隔
duration=1000000000
url="http://influxdb:8086"
database="chain33metrics"
username=""
password=""
namespace=""
......@@ -244,3 +244,18 @@ paraConsensusStopBlocks=30000
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
[metrics]
#是否使能发送metrics数据的发送
enableMetrics=true
#数据保存模式
dataEmitMode="influxdb"
[metrics.sub.influxdb]
#以纳秒为单位的发送间隔
duration=1000000000
url="http://influxdb:8086"
database="chain33metrics"
username=""
password=""
namespace=""
\ No newline at end of file
// 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
import (
"testing"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
pty "github.com/33cn/plugin/plugin/dapp/privacy/types"
"github.com/stretchr/testify/assert"
)
const (
testStateCheck = iota + 1
testStateExec
testStateExecLocal
testStateExecDelLocal
)
func testExec(mock *testExecMock, tcArr []*testcase, priv string, t *testing.T) {
exec := mock.exec
for i, tc := range tcArr {
signPriv := priv
if tc.priv != "" {
signPriv = tc.priv
}
tx, err := createTx(mock, tc.payload, signPriv, tc.systemCreate)
assert.NoErrorf(t, err, "createTxErr, testIndex=%d", tc.index)
if err != nil {
continue
}
if len(tc.testSign) > 0 {
tx.Signature.Signature = append([]byte(""), tc.testSign...)
}
if tc.testFee > 0 {
tx.Fee = tc.testFee
}
err = exec.CheckTx(tx, i)
assert.Equalf(t, tc.expectCheckErr, err, "checkTx err index %d", tc.index)
if tc.testState == testStateCheck {
continue
}
recp, err := exec.Exec(tx, i)
recpData := &types.ReceiptData{
Ty: recp.GetTy(),
Logs: recp.GetLogs(),
}
if err == nil && len(recp.GetKV()) > 0 {
util.SaveKVList(mock.stateDB, recp.KV)
mock.addBlockTx(tx, recpData)
}
assert.Equalf(t, tc.expectExecErr, err, "execTx err index %d", tc.index)
if tc.testState == testStateExec {
continue
}
kvSet, err := exec.ExecLocal(tx, recpData, i)
for _, kv := range kvSet.GetKV() {
err := mock.localDB.Set(kv.Key, kv.Value)
assert.Nil(t, err)
}
assert.Equalf(t, tc.expectExecLocalErr, err, "execLocalTx err index %d", tc.index)
if tc.testState == testStateExecLocal {
continue
}
kvSet, err = exec.ExecDelLocal(tx, recpData, i)
for _, kv := range kvSet.GetKV() {
err := mock.localDB.Set(kv.Key, kv.Value)
assert.Nil(t, err)
}
assert.Equalf(t, tc.expectExecDelErr, err, "execDelLocalTx err index %d", tc.index)
}
}
func TestPrivacy_CheckTx(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
//用于测试双花
testKeyImage := []byte("testKeyImage")
mock.stateDB.Set(calcPrivacyKeyImageKey("coins", "bty", testKeyImage), []byte("testval"))
tcArr := []*testcase{
{
index: 1,
payload: &pty.Public2Privacy{},
expectCheckErr: types.ErrInvalidParam,
},
{
index: 2,
payload: &pty.Public2Privacy{Tokenname: "bty"},
},
{
index: 4,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{}}},
expectCheckErr: pty.ErrNilUtxoInput,
},
{
index: 5,
payload: &pty.Privacy2Privacy{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{}}}},
expectCheckErr: pty.ErrNilUtxoOutput,
},
{
index: 6,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{}}}},
expectCheckErr: pty.ErrRingSign,
},
{
index: 7,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{KeyImage: testKeyImage}}}},
expectCheckErr: pty.ErrDoubleSpendOccur,
testSign: types.Encode(&types.RingSignature{Items: []*types.RingSignatureItem{{Pubkey: [][]byte{[]byte("test")}}}}),
},
{
index: 8,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{UtxoGlobalIndex: []*pty.UTXOGlobalIndex{{}}}}}},
expectCheckErr: pty.ErrPubkeysOfUTXO,
testSign: types.Encode(&types.RingSignature{Items: []*types.RingSignatureItem{{Pubkey: [][]byte{[]byte("test")}}}}),
},
{
index: 9,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{}}}},
expectCheckErr: pty.ErrPrivacyTxFeeNotEnough,
testSign: types.Encode(&types.RingSignature{Items: []*types.RingSignatureItem{{Pubkey: [][]byte{[]byte("test")}}}}),
},
{
index: 10,
payload: &pty.Privacy2Public{Tokenname: "bty", Input: &pty.PrivacyInput{Keyinput: []*pty.KeyInput{{}}}},
expectCheckErr: pty.ErrPrivacyTxFeeNotEnough,
testSign: types.Encode(&types.RingSignature{Items: []*types.RingSignatureItem{{Pubkey: [][]byte{[]byte("test")}}}}),
testFee: pty.PrivacyTxFee,
},
}
for _, tc := range tcArr {
tc.systemCreate = true
tc.testState = testStateCheck
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
func TestPrivacy_Exec_Public2Privacy(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
tcArr := []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
AssetExec: "btc-coins",
Tokenname: "btc",
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[0],
},
expectExecErr: types.ErrExecNameNotAllow,
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Amount: types.Coin * 10001,
Pubkeypair: testPubkeyPairs[0],
},
expectExecErr: types.ErrNoBalance,
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[0],
},
},
}
for _, tc := range tcArr {
req := tc.payload.(*pty.ReqCreatePrivacyTx)
req.Type = types.PrivacyTypePublic2Privacy
tc.testState = testStateExec
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
func TestPrivacy_Exec_Privacy2Privacy(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
tcArr := []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePublic2Privacy,
Amount: types.Coin * 9,
Pubkeypair: testPubkeyPairs[0],
},
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
},
},
}
for _, tc := range tcArr {
req := tc.payload.(*pty.ReqCreatePrivacyTx)
if req.Type == 0 {
req.Type = types.PrivacyTypePrivacy2Privacy
}
tc.testState = testStateExec
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
func TestPrivacy_Exec_Privacy2Public(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
tcArr := []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePublic2Privacy,
Amount: types.Coin * 9,
Pubkeypair: testPubkeyPairs[0],
},
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
To: testAddrs[1],
},
},
}
for _, tc := range tcArr {
req := tc.payload.(*pty.ReqCreatePrivacyTx)
if req.Type == 0 {
req.Type = types.PrivacyTypePrivacy2Public
}
tc.testState = testStateExec
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
func TestPrivacy_ExecLocal(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
tcArr := []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePublic2Privacy,
Amount: types.Coin * 9,
Pubkeypair: testPubkeyPairs[0],
},
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePrivacy2Privacy,
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
},
},
{
index: 3,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePrivacy2Public,
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
To: testAddrs[1],
},
},
}
for _, tc := range tcArr {
tc.testState = testStateExecLocal
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
func TestPrivacy_ExecDelLocal(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
tcArr := []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePublic2Privacy,
Amount: types.Coin * 9,
Pubkeypair: testPubkeyPairs[0],
},
},
{
index: 2,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePrivacy2Privacy,
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
},
},
{
index: 3,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePrivacy2Public,
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[1],
From: testAddrs[0],
To: testAddrs[1],
},
},
}
for _, tc := range tcArr {
tc.testState = testStateExecDelLocal
}
testExec(mock, tcArr, testPrivateKeys[0], t)
}
......@@ -206,7 +206,7 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
err := types.Decode(tx.Payload, &action)
if err != nil {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "Decode tx.Payload error", err)
return err
return types.ErrActionNotSupport
}
privacylog.Debug("PrivacyTrading CheckTx", "txhash", txhashstr, "action type ", action.Ty)
assertExec := action.GetAssertExec()
......@@ -214,32 +214,32 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
if token == "" {
return types.ErrInvalidParam
}
if pty.ActionPublic2Privacy == action.Ty {
if pty.ActionPublic2Privacy == action.Ty && action.GetPublic2Privacy() != nil {
return nil
}
input := action.GetInput()
output := action.GetOutput()
if input == nil || output == nil {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "input", input, "output", output)
return nil
//无论是私对私还是私对公, input都不能为空
if len(input.GetKeyinput()) == 0 {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr)
return pty.ErrNilUtxoInput
}
//如果是私到私 或者私到公,交易费扣除则需要utxo实现,交易费并不生成真正的UTXO,也是即时燃烧掉而已
var amount int64
keyinput := input.Keyinput
if action.Ty == pty.ActionPrivacy2Public && action.GetPrivacy2Public() != nil {
amount = action.GetPrivacy2Public().Amount
output := action.GetOutput()
//私对私必须有utxo输出
if action.GetPrivacy2Privacy() != nil && len(output.GetKeyoutput()) == 0 {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr)
return pty.ErrNilUtxoOutput
}
// check sign
var ringSignature types.RingSignature
if err := types.Decode(tx.Signature.Signature, &ringSignature); err != nil {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "Decode tx.Signature.Signature error ", err)
return err
return pty.ErrRingSign
}
totalInput := int64(0)
totalOutput := int64(0)
inputCnt := len(keyinput)
keyImages := make([][]byte, inputCnt)
keyinput := input.GetKeyinput()
keyImages := make([][]byte, len(keyinput))
keys := make([][]byte, 0)
pubkeys := make([][]byte, 0)
for i, input := range keyinput {
......@@ -273,18 +273,20 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
cfg := p.GetAPI().GetConfig()
if !cfg.IsPara() && (assertExec == "" || assertExec == "coins") {
for _, output := range output.Keyoutput {
totalOutput += output.Amount
totalOutput := int64(0)
for _, output := range output.GetKeyoutput() {
totalOutput += output.GetAmount()
}
if tx.Fee < pty.PrivacyTxFee {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "fee set:", tx.Fee, "required:", pty.PrivacyTxFee, " error ErrPrivacyTxFeeNotEnough")
return pty.ErrPrivacyTxFeeNotEnough
}
//如果是私到私 或者私到公,交易费扣除则需要utxo实现,交易费并不生成真正的UTXO,也是即时燃烧掉而已
var feeAmount int64
if action.Ty == pty.ActionPrivacy2Privacy {
feeAmount = totalInput - totalOutput
} else {
feeAmount = totalInput - totalOutput - amount
} else if action.Ty == pty.ActionPrivacy2Public && action.GetPrivacy2Public() != nil {
feeAmount = totalInput - totalOutput - action.GetPrivacy2Public().Amount
}
if feeAmount < pty.PrivacyTxFee {
......
// 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
import (
"testing"
"github.com/33cn/chain33/types"
pty "github.com/33cn/plugin/plugin/dapp/privacy/types"
"github.com/stretchr/testify/assert"
)
var (
execTestCases = []*testcase{
{
index: 1,
payload: &pty.ReqCreatePrivacyTx{
Type: types.PrivacyTypePublic2Privacy,
Amount: types.Coin,
Pubkeypair: testPubkeyPairs[0],
},
},
}
)
type queryTestCase struct {
index int
funcName string
params types.Message
expectErr error
expectReply types.Message
disableReplyCheck bool
}
func testQuery(mock *testExecMock, tcArr []*queryTestCase, t *testing.T) {
for _, tc := range tcArr {
reply, err := mock.exec.Query(tc.funcName, types.Encode(tc.params))
assert.Equalf(t, tc.expectErr, err, "queryTest index=%d", tc.index)
if err == nil && !tc.disableReplyCheck {
assert.Equalf(t, tc.expectReply, reply, "queryTest index=%d", tc.index)
}
}
}
func TestPrivacy_Query_ShowAmountsOfUTXO(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
for _, tc := range execTestCases {
tc.testState = testStateExecLocal
}
testExec(mock, execTestCases, testPrivateKeys[0], t)
queryCases := []*queryTestCase{
{
index: 1,
params: &pty.ReqPrivacyToken{
Token: "btc",
},
expectErr: types.ErrNotFound,
},
{
index: 2,
params: &pty.ReqPrivacyToken{
Token: "bty",
},
expectReply: &pty.ReplyPrivacyAmounts{
AmountDetail: []*pty.AmountDetail{
{Amount: types.Coin, Count: 1},
},
},
},
}
for _, tc := range queryCases {
tc.funcName = "ShowAmountsOfUTXO"
}
testQuery(mock, queryCases, t)
}
func TestPrivacy_Query_ShowUTXOs4SpecifiedAmount(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
for _, tc := range execTestCases {
tc.testState = testStateExecLocal
}
testExec(mock, execTestCases, testPrivateKeys[0], t)
queryCases := []*queryTestCase{
{
index: 1,
params: &pty.ReqPrivacyToken{
Token: "bty",
},
expectErr: types.ErrNotFound,
},
{
index: 2,
params: &pty.ReqPrivacyToken{
Token: "bty",
Amount: types.Coin,
},
disableReplyCheck: true,
},
}
for _, tc := range queryCases {
tc.funcName = "ShowUTXOs4SpecifiedAmount"
}
testQuery(mock, queryCases, t)
}
func TestPrivacy_Query_GetUTXOGlobalIndex(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
for _, tc := range execTestCases {
tc.testState = testStateExecLocal
}
testExec(mock, execTestCases, testPrivateKeys[0], t)
queryCases := []*queryTestCase{
{
index: 1,
params: &pty.ReqUTXOGlobalIndex{},
disableReplyCheck: true,
},
{
index: 2,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "btc",
MixCount: 1,
Amount: []int64{types.Coin},
},
disableReplyCheck: true,
expectErr: types.ErrNotFound,
},
{
index: 3,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "bty",
MixCount: 1,
Amount: []int64{types.Coin, types.Coin * 2},
},
disableReplyCheck: true,
expectErr: types.ErrNotFound,
},
{
index: 4,
params: &pty.ReqUTXOGlobalIndex{
Tokenname: "bty",
MixCount: 1,
Amount: []int64{types.Coin},
},
disableReplyCheck: true,
},
}
for _, tc := range queryCases {
tc.funcName = "GetUTXOGlobalIndex"
}
testQuery(mock, queryCases, t)
}
func TestPrivacy_Query_GetTxsByAddr(t *testing.T) {
mock := &testExecMock{}
mock.InitEnv()
defer mock.FreeEnv()
for _, tc := range execTestCases {
tc.testState = testStateExecLocal
}
testExec(mock, execTestCases, testPrivateKeys[0], t)
queryCases := []*queryTestCase{
{
index: 1,
params: &types.ReqAddr{
Addr: testAddrs[0],
},
expectErr: types.ErrNotFound,
},
}
for _, tc := range queryCases {
tc.funcName = "GetTxsByAddr"
}
testQuery(mock, queryCases, t)
}
// 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
import (
"errors"
"fmt"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/queue"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/wallet"
wcom "github.com/33cn/chain33/wallet/common"
pty "github.com/33cn/plugin/plugin/dapp/privacy/types"
pwallet "github.com/33cn/plugin/plugin/dapp/privacy/wallet"
)
var (
initBalance = types.Coin * 10000
initHeight = int64(100)
// 测试的私钥
testPrivateKeys = []string{
"0x8dea7332c7bb3e3b0ce542db41161fd021e3cfda9d7dabacf24f98f2dfd69558",
"0x920976ffe83b5a98f603b999681a0bc790d97e22ffc4e578a707c2234d55cc8a",
"0xb59f2b02781678356c231ad565f73699753a28fd3226f1082b513ebf6756c15c",
}
// 测试的地址
testAddrs = []string{
"1EDDghAtgBsamrNEtNmYdQzC1QEhLkr87t",
"13cS5G1BDN2YfGudsxRxr7X25yu6ZdgxMU",
"1JSRSwp16NvXiTjYBYK9iUQ9wqp3sCxz2p",
}
// 测试的隐私公钥对
testPubkeyPairs = []string{
"92fe6cfec2e19cd15f203f83b5d440ddb63d0cb71559f96dc81208d819fea85886b08f6e874fca15108d244b40f9086d8c03260d4b954a40dfb3cbe41ebc7389",
"6326126c968a93a546d8f67d623ad9729da0e3e4b47c328a273dfea6930ffdc87bcc365822b80b90c72d30e955e7870a7a9725e9a946b9e89aec6db9455557eb",
"44bf54abcbae297baf3dec4dd998b313eafb01166760f0c3a4b36509b33d3b50239de0a5f2f47c2fc98a98a382dcd95a2c5bf1f4910467418a3c2595b853338e",
}
// exec privacy addr
execAddr = "1FeyE6VDZ4FYgpK1n2okWMDAtPkwBuooQd"
testPolicy = pwallet.New()
testPolicyName = pty.PrivacyX + "test"
testCfg = types.NewChain33Config(types.GetDefaultCfgstring())
)
func init() {
log.SetLogLevel("error")
Init(pty.PrivacyX, testCfg, nil)
wcom.RegisterPolicy(testPolicyName, testPolicy)
}
type testExecMock struct {
dbDir string
localDB dbm.KVDB
stateDB dbm.DB
exec dapp.Driver
wallet *walletMock
policy wcom.WalletBizPolicy
cfg *types.Chain33Config
q queue.Queue
qapi client.QueueProtocolAPI
}
type testcase struct {
payload types.Message
expectExecErr error
expectCheckErr error
expectExecLocalErr error
expectExecDelErr error
priv string
index int
systemCreate bool
testState int
testSign []byte
testFee int64
}
// InitEnv init env
func (mock *testExecMock) InitEnv() {
mock.cfg = testCfg
util.ResetDatadir(mock.cfg.GetModuleConfig(), "$TEMP/")
mock.q = queue.New("channel")
mock.q.SetConfig(mock.cfg)
mock.qapi, _ = client.New(mock.q.Client(), nil)
mock.initExec()
mock.initWallet()
}
func (mock *testExecMock) FreeEnv() {
util.CloseTestDB(mock.dbDir, mock.stateDB)
}
func (mock *testExecMock) initExec() {
mock.dbDir, mock.stateDB, mock.localDB = util.CreateTestDB()
exec := newPrivacy()
exec.SetAPI(mock.qapi)
exec.SetStateDB(mock.stateDB)
exec.SetLocalDB(mock.localDB)
exec.SetEnv(100, 1539918074, 1539918074)
mock.exec = exec
}
func (mock *testExecMock) initWallet() {
mock.wallet = &walletMock{}
mock.wallet.Wallet = wallet.New(mock.cfg)
mock.policy = testPolicy
mock.wallet.SetQueueClient(mock.q.Client())
mock.policy.Init(mock.wallet, nil)
seed, _ := mock.wallet.GenSeed(1)
mock.wallet.SaveSeed("abcd1234", seed.Seed)
mock.wallet.ProcWalletUnLock(&types.WalletUnLock{Passwd: "abcd1234"})
accCoin := account.NewCoinsAccount(mock.cfg)
accCoin.SetDB(mock.stateDB)
for index, addr := range testAddrs {
account := &types.Account{
Balance: initBalance,
Addr: addr,
}
accCoin.SaveAccount(account)
accCoin.SaveExecAccount(execAddr, account)
privBytes, _ := common.FromHex(testPrivateKeys[index])
bpriv := wcom.CBCEncrypterPrivkey([]byte(mock.wallet.Password), privBytes)
was := &types.WalletAccountStore{
Privkey: common.ToHex(bpriv),
Label: fmt.Sprintf("label%d", index),
Addr: addr,
TimeStamp: types.Now().String(),
}
mock.wallet.SetWalletAccount(false, addr, was)
}
mock.wallet.GetAPI().ExecWalletFunc(testPolicyName, "EnablePrivacy", &pty.ReqEnablePrivacy{Addrs: testAddrs})
}
func (mock *testExecMock) addBlockTx(tx *types.Transaction, receipt *types.ReceiptData) {
block := &types.BlockDetail{
Block: &types.Block{
Height: initHeight,
},
Receipts: []*types.ReceiptData{receipt},
}
batch := mock.wallet.GetDBStore().NewBatch(true)
defer batch.Write()
mock.policy.OnAddBlockTx(block, tx, 0, batch)
}
func createTx(mock *testExecMock, payload types.Message, priv string, systemCreate bool) (*types.Transaction, error) {
c, err := crypto.New(crypto.GetName(types.SECP256K1))
if err != nil {
return nil, err
}
bytes, err := common.FromHex(priv[:])
if err != nil {
return nil, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
if err != nil {
return nil, err
}
if systemCreate {
action, _ := buildAction(payload)
tx, err := types.CreateFormatTx(mock.cfg, mock.cfg.ExecName(pty.PrivacyX), types.Encode(action))
if err != nil {
return nil, err
}
tx.Sign(int32(types.SECP256K1), privKey)
return tx, nil
}
req := payload.(*pty.ReqCreatePrivacyTx)
if req.GetAssetExec() == "" {
req.AssetExec = "coins"
}
reply, err := mock.wallet.GetAPI().ExecWalletFunc(testPolicyName, "CreateTransaction", payload)
if err != nil {
return nil, errors.New("createTxErr:" + err.Error())
}
signTxReq := &types.ReqSignRawTx{
TxHex: common.ToHex(types.Encode(reply)),
}
_, signTx, err := mock.policy.SignTransaction(privKey, signTxReq)
if err != nil {
return nil, errors.New("signPrivacyTxErr:" + err.Error())
}
signTxBytes, _ := common.FromHex(signTx)
tx := &types.Transaction{}
err = types.Decode(signTxBytes, tx)
if err != nil {
return nil, err
}
return tx, nil
}
func buildAction(param types.Message) (types.Message, error) {
action := &pty.PrivacyAction{
Value: nil,
Ty: 0,
}
if val, ok := param.(*pty.Public2Privacy); ok {
action.Value = &pty.PrivacyAction_Public2Privacy{Public2Privacy: val}
action.Ty = pty.ActionPublic2Privacy
} else if val, ok := param.(*pty.Privacy2Privacy); ok {
action.Value = &pty.PrivacyAction_Privacy2Privacy{Privacy2Privacy: val}
action.Ty = pty.ActionPrivacy2Privacy
} else if val, ok := param.(*pty.Privacy2Public); ok {
action.Value = &pty.PrivacyAction_Privacy2Public{Privacy2Public: val}
action.Ty = pty.ActionPrivacy2Public
} else {
return nil, types.ErrActionNotSupport
}
return action, nil
}
type walletMock struct {
*wallet.Wallet
}
func (w *walletMock) GetBlockHeight() int64 {
return initHeight + types.PrivacyMaturityDegree
}
......@@ -20,4 +20,7 @@ var (
ErrOutputIndex = errors.New("ErrOutputIndex")
ErrPubkeysOfUTXO = errors.New("ErrPubkeysOfUTXO")
ErrRecoverUTXO = errors.New("ErrRecoverUTXO")
ErrNilUtxoInput = errors.New("ErrNilUtxoInput")
ErrNilUtxoOutput = errors.New("ErrNilUtxoOutput")
ErrRingSign = errors.New("ErrRingSign")
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment