Commit 83b42f56 authored by jiangpeng's avatar jiangpeng Committed by vipwzw

privacy:add exec test

parent 5abdef2c
// 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 { ...@@ -206,7 +206,7 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
err := types.Decode(tx.Payload, &action) err := types.Decode(tx.Payload, &action)
if err != nil { if err != nil {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "Decode tx.Payload error", err) 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) privacylog.Debug("PrivacyTrading CheckTx", "txhash", txhashstr, "action type ", action.Ty)
assertExec := action.GetAssertExec() assertExec := action.GetAssertExec()
...@@ -214,32 +214,32 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error { ...@@ -214,32 +214,32 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
if token == "" { if token == "" {
return types.ErrInvalidParam return types.ErrInvalidParam
} }
if pty.ActionPublic2Privacy == action.Ty { if pty.ActionPublic2Privacy == action.Ty && action.GetPublic2Privacy() != nil {
return nil return nil
} }
input := action.GetInput() input := action.GetInput()
output := action.GetOutput() //无论是私对私还是私对公, input都不能为空
if input == nil || output == nil { if len(input.GetKeyinput()) == 0 {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "input", input, "output", output) privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr)
return nil return pty.ErrNilUtxoInput
} }
//如果是私到私 或者私到公,交易费扣除则需要utxo实现,交易费并不生成真正的UTXO,也是即时燃烧掉而已
var amount int64
keyinput := input.Keyinput
if action.Ty == pty.ActionPrivacy2Public && action.GetPrivacy2Public() != nil { output := action.GetOutput()
amount = action.GetPrivacy2Public().Amount //私对私必须有utxo输出
if action.GetPrivacy2Privacy() != nil && len(output.GetKeyoutput()) == 0 {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr)
return pty.ErrNilUtxoOutput
} }
// check sign
var ringSignature types.RingSignature var ringSignature types.RingSignature
if err := types.Decode(tx.Signature.Signature, &ringSignature); err != nil { if err := types.Decode(tx.Signature.Signature, &ringSignature); err != nil {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "Decode tx.Signature.Signature error ", err) privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "Decode tx.Signature.Signature error ", err)
return err return pty.ErrRingSign
} }
totalInput := int64(0) totalInput := int64(0)
totalOutput := int64(0) keyinput := input.GetKeyinput()
inputCnt := len(keyinput) keyImages := make([][]byte, len(keyinput))
keyImages := make([][]byte, inputCnt)
keys := make([][]byte, 0) keys := make([][]byte, 0)
pubkeys := make([][]byte, 0) pubkeys := make([][]byte, 0)
for i, input := range keyinput { for i, input := range keyinput {
...@@ -273,18 +273,20 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error { ...@@ -273,18 +273,20 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
cfg := p.GetAPI().GetConfig() cfg := p.GetAPI().GetConfig()
if !cfg.IsPara() && (assertExec == "" || assertExec == "coins") { if !cfg.IsPara() && (assertExec == "" || assertExec == "coins") {
for _, output := range output.Keyoutput { totalOutput := int64(0)
totalOutput += output.Amount for _, output := range output.GetKeyoutput() {
totalOutput += output.GetAmount()
} }
if tx.Fee < pty.PrivacyTxFee { if tx.Fee < pty.PrivacyTxFee {
privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "fee set:", tx.Fee, "required:", pty.PrivacyTxFee, " error ErrPrivacyTxFeeNotEnough") privacylog.Error("PrivacyTrading CheckTx", "txhash", txhashstr, "fee set:", tx.Fee, "required:", pty.PrivacyTxFee, " error ErrPrivacyTxFeeNotEnough")
return pty.ErrPrivacyTxFeeNotEnough return pty.ErrPrivacyTxFeeNotEnough
} }
//如果是私到私 或者私到公,交易费扣除则需要utxo实现,交易费并不生成真正的UTXO,也是即时燃烧掉而已
var feeAmount int64 var feeAmount int64
if action.Ty == pty.ActionPrivacy2Privacy { if action.Ty == pty.ActionPrivacy2Privacy {
feeAmount = totalInput - totalOutput feeAmount = totalInput - totalOutput
} else { } else if action.Ty == pty.ActionPrivacy2Public && action.GetPrivacy2Public() != nil {
feeAmount = totalInput - totalOutput - amount feeAmount = totalInput - totalOutput - action.GetPrivacy2Public().Amount
} }
if feeAmount < pty.PrivacyTxFee { 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 ( ...@@ -20,4 +20,7 @@ var (
ErrOutputIndex = errors.New("ErrOutputIndex") ErrOutputIndex = errors.New("ErrOutputIndex")
ErrPubkeysOfUTXO = errors.New("ErrPubkeysOfUTXO") ErrPubkeysOfUTXO = errors.New("ErrPubkeysOfUTXO")
ErrRecoverUTXO = errors.New("ErrRecoverUTXO") 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