Commit f89f1b0a authored by jiangpeng's avatar jiangpeng

privacy:update wallet utxo manage

* add utxo store key with asset exec * fix rescan nil pointer
parent 3ef9413b
......@@ -284,6 +284,7 @@ func showPrivacyAccountSpendCmd() *cobra.Command {
func showPrivacyAccountSpendFlag(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "account address")
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token, paracross), default coins")
cmd.Flags().StringP("symbol", "s", "BTY", "asset symbol, default BTY")
cmd.MarkFlagRequired("addr")
}
......@@ -291,10 +292,12 @@ func showPrivacyAccountSpendFlag(cmd *cobra.Command) {
func showPrivacyAccountSpend(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
addr, _ := cmd.Flags().GetString("addr")
exec, _ := cmd.Flags().GetString("exec")
symbol, _ := cmd.Flags().GetString("symbol")
params := pty.ReqPrivBal4AddrToken{
Addr: addr,
Token: symbol,
Addr: addr,
Token: symbol,
AssetExec: exec,
}
var res pty.UTXOHaveTxHashs
......@@ -453,7 +456,7 @@ func showPrivacyAccountInfoCmd() *cobra.Command {
func showPrivacyAccountInfoFlag(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "account address")
cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token, paracross), default coins")
cmd.Flags().StringP("symbol", "s", "BTY", "asset symbol, default BTY")
cmd.Flags().Int32P("displaymode", "d", 0, "display mode.(0: display collect. 1:display available detail. 2:display frozen detail. 3:display all")
}
......@@ -461,6 +464,7 @@ func showPrivacyAccountInfoFlag(cmd *cobra.Command) {
func showPrivacyAccountInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
addr, _ := cmd.Flags().GetString("addr")
exec, _ := cmd.Flags().GetString("exec")
token, _ := cmd.Flags().GetString("symbol")
mode, _ := cmd.Flags().GetInt32("displaymode")
if mode < 0 || mode > 3 {
......@@ -468,10 +472,11 @@ func showPrivacyAccountInfo(cmd *cobra.Command, args []string) {
return
}
params := pty.ReqPPrivacyAccount{
params := pty.ReqPrivacyAccount{
Addr: addr,
Token: token,
Displaymode: mode,
AssetExec: exec,
}
var res pty.ReplyPrivacyAccount
......@@ -546,6 +551,7 @@ func addListPrivacyTxsFlags(cmd *cobra.Command) {
//
cmd.Flags().Int32P("sendrecv", "", 0, "send or recv flag (0: send, 1: recv), default 0")
cmd.Flags().Int32P("count", "c", 10, "number of transactions, default 10")
cmd.Flags().StringP("exec", "e", "coins", "asset executor(coins, token, paracross), default coins")
cmd.Flags().StringP("token", "", types.BTY, "token name.(BTY supported)")
cmd.Flags().Int32P("direction", "d", 1, "query direction (0: pre page, 1: next page), valid with seedtxhash param")
cmd.Flags().StringP("seedtxhash", "", "", "seed trasnaction hash")
......@@ -559,7 +565,9 @@ func listPrivacyTxsFlags(cmd *cobra.Command, args []string) {
sendRecvFlag, _ := cmd.Flags().GetInt32("sendrecv")
tokenname, _ := cmd.Flags().GetString("token")
seedtxhash, _ := cmd.Flags().GetString("seedtxhash")
exec, _ := cmd.Flags().GetString("exec")
params := pty.ReqPrivacyTransactionList{
AssetExec: exec,
Tokenname: tokenname,
SendRecvFlag: sendRecvFlag,
Direction: direction,
......
......@@ -43,8 +43,8 @@ func (p *privacy) Exec_Public2Privacy(payload *ty.Public2Privacy, tx *types.Tran
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
privacylog.Debug("testkey", "output", payload.GetOutput().Keyoutput)
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog := &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
......@@ -79,7 +79,7 @@ func (p *privacy) Exec_Privacy2Privacy(payload *ty.Privacy2Privacy, tx *types.Tr
value := types.Encode(keyOutput)
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
receiptLogs := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLogs)}
receipt.Logs = append(receipt.Logs, execlog)
......@@ -125,7 +125,7 @@ func (p *privacy) Exec_Privacy2Public(payload *ty.Privacy2Public, tx *types.Tran
receipt.KV = append(receipt.KV, &types.KeyValue{Key: key, Value: value})
}
receiptLog := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput().GetKeyoutput())
receiptLog := p.buildPrivacyReceiptLog(payload.GetAssetExec(), payload.GetTokenname(), payload.GetOutput())
execlog = &types.ReceiptLog{Ty: ty.TyLogPrivacyOutput, Log: types.Encode(receiptLog)}
receipt.Logs = append(receipt.Logs, execlog)
......@@ -146,14 +146,14 @@ func (p *privacy) createAccountDB(exec, symbol string) (*account.DB, error) {
return account.NewAccountDB(cfg, exec, symbol, p.GetStateDB())
}
func (p *privacy) buildPrivacyReceiptLog(assetExec, assetSymbol string, output []*ty.KeyOutput) *ty.ReceiptPrivacyOutput {
func (p *privacy) buildPrivacyReceiptLog(assetExec, assetSymbol string, output *ty.PrivacyOutput) *ty.ReceiptPrivacyOutput {
if assetExec == "" {
assetExec = "coins"
}
receipt := &ty.ReceiptPrivacyOutput{
AssetExec: assetExec,
AssetSymbol: assetSymbol,
Keyoutput: output,
Keyoutput: output.Keyoutput,
}
return receipt
......
......@@ -208,8 +208,7 @@ func (p *privacy) CheckTx(tx *types.Transaction, index int) error {
return types.ErrActionNotSupport
}
privacylog.Debug("PrivacyTrading CheckTx", "txhash", txhashstr, "action type ", action.Ty)
assertExec := action.GetAssertExec()
token := action.GetTokenName()
assertExec, token := action.GetAssetExecSymbol()
if token == "" {
return types.ErrInvalidParam
}
......
......@@ -206,8 +206,9 @@ message ReplyPrivacyPkPair {
}
message ReqPrivBal4AddrToken {
string addr = 1;
string token = 2;
string addr = 1;
string token = 2;
string assetExec = 3;
}
message ReplyPrivacyBalance {
......@@ -226,6 +227,7 @@ message PrivacyDBStore {
int64 height = 8;
int32 txindex = 9;
bytes blockhash = 10;
string assetExec = 11;
}
message UTXO {
......@@ -271,9 +273,10 @@ message FTXOsSTXOsInOneTx {
string tokenname = 1;
string sender = 2;
// FTXO的超期,设定原则与Transaction.expire一致
int64 expire = 3;
string txhash = 4;
repeated UTXO utxos = 5;
int64 expire = 3;
string txhash = 4;
repeated UTXO utxos = 5;
string assetExec = 6;
}
message RealKeyInput {
......@@ -314,11 +317,6 @@ message ReplyCacheTxList {
}
message ReqPrivacyAccount {
string tokenname = 1;
string addr = 2;
}
message ReqPPrivacyAccount {
string addr = 1;
string token = 2;
// 设定显示的数据类型信息
......@@ -326,7 +324,8 @@ message ReqPPrivacyAccount {
// 1: 显示UTXO明细
// 2: 显示FTXO明细
// 3: 全部显示
int32 displaymode = 3;
int32 displaymode = 3;
string assetExec = 4;
}
// 请求隐私账户信息的应答
......@@ -354,6 +353,7 @@ message ReqPrivacyTransactionList {
string from = 5;
string address = 6;
bytes seedtxhash = 7;
string assetExec = 8;
}
message ReqRescanUtxos {
......
......@@ -50,7 +50,7 @@ func (g *channelClient) CreateRawTransaction(ctx context.Context, in *pty.ReqCre
}
// ShowPrivacyAccountInfo display privacy account information for json rpc
func (c *Jrpc) ShowPrivacyAccountInfo(in *pty.ReqPPrivacyAccount, result *json.RawMessage) error {
func (c *Jrpc) ShowPrivacyAccountInfo(in *pty.ReqPrivacyAccount, result *json.RawMessage) error {
reply, err := c.cli.ExecWalletFunc(pty.PrivacyX, "ShowPrivacyAccountInfo", in)
if err != nil {
return err
......
......@@ -72,7 +72,7 @@ func testShowPrivacyKey(t *testing.T, jrpc *jsonclient.JSONClient) error {
}
func testShowPrivacyAccountInfo(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := pty.ReqPPrivacyAccount{
params := pty.ReqPrivacyAccount{
Addr: "1JSRSwp16NvXiTjYBYK9iUQ9wqp3sCxz2p",
Token: types.BTY,
Displaymode: 1,
......
......@@ -41,7 +41,7 @@ func TestRPC_Call(t *testing.T) {
assert.NotNil(t, jsonClient)
//调用:
params := pty.ReqPPrivacyAccount{
params := pty.ReqPrivacyAccount{
Addr: "addr",
Token: "token",
Displaymode: 3,
......
......@@ -81,7 +81,7 @@ func (t *PrivacyType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogPrivacyFee: {Ty: reflect.TypeOf(types.ReceiptExecAccountTransfer{}), Name: "LogPrivacyFee"},
TyLogPrivacyInput: {Ty: reflect.TypeOf(PrivacyInput{}), Name: "LogPrivacyInput"},
TyLogPrivacyOutput: {Ty: reflect.TypeOf(PrivacyOutput{}), Name: "LogPrivacyOutput"},
TyLogPrivacyOutput: {Ty: reflect.TypeOf(ReceiptPrivacyOutput{}), Name: "LogPrivacyOutput"},
}
}
......@@ -168,26 +168,14 @@ func (action *PrivacyAction) GetActionName() string {
return "unknow-privacy"
}
// GetTokenName get action token name
func (action *PrivacyAction) GetTokenName() string {
// GetAssetExecSymbol get assert exec and symbol
func (action *PrivacyAction) GetAssetExecSymbol() (assetExec, assetSymbol string) {
if action.GetTy() == ActionPublic2Privacy && action.GetPublic2Privacy() != nil {
return action.GetPublic2Privacy().GetTokenname()
return action.GetPublic2Privacy().GetAssetExec(), action.GetPublic2Privacy().GetTokenname()
} else if action.GetTy() == ActionPrivacy2Privacy && action.GetPrivacy2Privacy() != nil {
return action.GetPrivacy2Privacy().GetTokenname()
return action.GetPrivacy2Privacy().GetAssetExec(), action.GetPrivacy2Privacy().GetTokenname()
} else if action.GetTy() == ActionPrivacy2Public && action.GetPrivacy2Public() != nil {
return action.GetPrivacy2Public().GetTokenname()
return action.GetPrivacy2Public().GetAssetExec(), action.GetPrivacy2Public().GetTokenname()
}
return ""
}
// GetAssertExec get assert exec
func (action *PrivacyAction) GetAssertExec() string {
if action.GetTy() == ActionPublic2Privacy && action.GetPublic2Privacy() != nil {
return action.GetPublic2Privacy().GetAssetExec()
} else if action.GetTy() == ActionPrivacy2Privacy && action.GetPrivacy2Privacy() != nil {
return action.GetPrivacy2Privacy().GetAssetExec()
} else if action.GetTy() == ActionPrivacy2Public && action.GetPrivacy2Public() != nil {
return action.GetPrivacy2Public().GetAssetExec()
}
return ""
return "", ""
}
This diff is collapsed.
......@@ -67,7 +67,7 @@ func (policy *privacyPolicy) On_CreateTransaction(req *privacytypes.ReqCreatePri
return reply, err
}
func (policy *privacyPolicy) On_ShowPrivacyAccountInfo(req *privacytypes.ReqPPrivacyAccount) (types.Message, error) {
func (policy *privacyPolicy) On_ShowPrivacyAccountInfo(req *privacytypes.ReqPrivacyAccount) (types.Message, error) {
policy.getWalletOperate().GetMutex().Lock()
defer policy.getWalletOperate().GetMutex().Unlock()
reply, err := policy.getPrivacyAccountInfo(req)
......
......@@ -96,45 +96,37 @@ func calcAddrKey(addr string) []byte {
}
// calcPrivacyUTXOPrefix4Addr 获取指定地址下可用UTXO信息索引的KEY值前缀
func calcPrivacyUTXOPrefix4Addr(token, addr string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-", AvailUTXOs, token, addr))
func calcPrivacyUTXOPrefix4Addr(assetExec, token, addr string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s-", AvailUTXOs, assetExec, token, addr))
}
// calcFTXOsKeyPrefix 获取指定地址下由于交易未被确认而让交易使用到的UTXO处于冻结状态信息的KEY值前缀
func calcFTXOsKeyPrefix(token, addr string) []byte {
var prefix string
if len(token) > 0 && len(addr) > 0 {
prefix = fmt.Sprintf("%s:%s-%s-", FrozenUTXOs, token, addr)
} else if len(token) > 0 {
prefix = fmt.Sprintf("%s:%s-", FrozenUTXOs, token)
} else {
prefix = fmt.Sprintf("%s:", FrozenUTXOs)
}
return []byte(prefix)
func calcFTXOsKeyPrefix(assetExec, token, addr string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s-", FrozenUTXOs, assetExec, token, addr))
}
// calcSendPrivacyTxKey 计算以指定地址作为发送地址的交易信息索引
// addr为发送地址
// key为通过calcTxKey(heightstr)计算出来的值
func calcSendPrivacyTxKey(tokenname, addr, key string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s", SendPrivacyTx, tokenname, addr, key))
func calcSendPrivacyTxKey(assetExec, tokenname, addr, key string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s-%s", SendPrivacyTx, assetExec, tokenname, addr, key))
}
// calcRecvPrivacyTxKey 计算以指定地址作为接收地址的交易信息索引
// addr为接收地址
// key为通过calcTxKey(heightstr)计算出来的值
func calcRecvPrivacyTxKey(tokenname, addr, key string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s", RecvPrivacyTx, tokenname, addr, key))
func calcRecvPrivacyTxKey(assetExec, tokenname, addr, key string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s-%s", RecvPrivacyTx, assetExec, tokenname, addr, key))
}
// calcUTXOKey4TokenAddr 计算当前地址可用UTXO的Key健值
func calcUTXOKey4TokenAddr(token, addr, txhash string, index int) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s-%d", AvailUTXOs, token, addr, txhash, index))
func calcUTXOKey4TokenAddr(assetExec, token, addr, txhash string, index int) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s-%s-%d", AvailUTXOs, assetExec, token, addr, txhash, index))
}
// calcKey4FTXOsInTx 交易构建以后,将可用UTXO冻结的健值
func calcKey4FTXOsInTx(token, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s", FrozenUTXOs, token, addr, txhash))
func calcKey4FTXOsInTx(assetExec, token, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s-%s", FrozenUTXOs, assetExec, token, addr, txhash))
}
// calcRescanUtxosFlagKey 新账户导入时扫描区块上该地址相关的UTXO信息
......@@ -151,17 +143,17 @@ func calcKey4STXOsInTx(txhash string) []byte {
}
// calcSTXOTokenAddrTxKey 计算当前地址已花费的UTXO
func calcSTXOTokenAddrTxKey(token, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s", PrivacySTXO, token, addr, txhash))
func calcSTXOTokenAddrTxKey(assetExec, token, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s-%s", PrivacySTXO, assetExec, token, addr, txhash))
}
func calcSTXOPrefix4Addr(token, addr string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-", PrivacySTXO, token, addr))
func calcSTXOPrefix4Addr(assetExec, token, addr string) []byte {
return []byte(fmt.Sprintf("%s-%s-%s-%s-", PrivacySTXO, assetExec, token, addr))
}
// calcRevertSendTxKey 交易因为区块回退而将已经花费的UTXO移动到冻结UTXO队列的健值
func calcRevertSendTxKey(tokenname, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s", RevertSendtx, tokenname, addr, txhash))
func calcRevertSendTxKey(assetExec, tokenname, addr, txhash string) []byte {
return []byte(fmt.Sprintf("%s:%s-%s-%s-%s", RevertSendtx, assetExec, tokenname, addr, txhash))
}
//通过height*100000+index 查询Tx交易信息
......
This diff is collapsed.
......@@ -171,6 +171,7 @@ func (policy *privacyPolicy) SignTransaction(key crypto.PrivKey, req *types.ReqS
}
type buildStoreWalletTxDetailParam struct {
assetExec string
tokenname string
block *types.BlockDetail
tx *types.Transaction
......
......@@ -399,7 +399,7 @@ func Test_PrivacyAccountInfo(t *testing.T) {
mock.init()
testCases := []struct {
req *ty.ReqPPrivacyAccount
req *ty.ReqPrivacyAccount
needReply *ty.ReplyPrivacyAccount
needError error
}{
......@@ -407,7 +407,7 @@ func Test_PrivacyAccountInfo(t *testing.T) {
needError: types.ErrInvalidParam,
},
{
req: &ty.ReqPPrivacyAccount{
req: &ty.ReqPrivacyAccount{
Addr: testAddrs[0],
Token: types.BTY,
Displaymode: 0,
......
This diff is collapsed.
......@@ -73,12 +73,12 @@ func testStore_unsetUTXO(t *testing.T) {
addr := ""
txhash := ""
batch := store.NewBatch(true)
err := store.unsetUTXO(&addr, &txhash, 0, "", batch)
err := store.unsetUTXO("", "", addr, txhash, 0, batch)
assert.NotNil(t, err)
addr = "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
txhash = "TXHASH"
err = store.unsetUTXO(&addr, &txhash, 0, "BTY", batch)
err = store.unsetUTXO("coins", "BTY", addr, txhash, 0, batch)
assert.NoError(t, err)
}
......@@ -174,10 +174,11 @@ func testStore_moveUTXO2FTXO(t *testing.T) {
func testStore_getPrivacyTokenUTXOs(t *testing.T) {
store := createStore(t)
utxos, err := store.getPrivacyTokenUTXOs("", "")
utxos, err := store.getPrivacyTokenUTXOs("", "", "")
assert.Nil(t, err)
assert.NotNil(t, utxos)
assetExec := "coins"
token := "BTY"
addr := "getPrivacyTokenUTXOs"
......@@ -186,12 +187,12 @@ func testStore_getPrivacyTokenUTXOs(t *testing.T) {
bt, err := proto.Marshal(data)
assert.NoError(t, err)
key := fmt.Sprintf("Key%d", n)
err = store.Set(calcUTXOKey4TokenAddr(token, addr, "txhash", n), []byte(key))
err = store.Set(calcUTXOKey4TokenAddr(assetExec, token, addr, "txhash", n), []byte(key))
assert.NoError(t, err)
err = store.Set([]byte(key), bt)
assert.NoError(t, err)
}
utxos, err = store.getPrivacyTokenUTXOs(token, addr)
utxos, err = store.getPrivacyTokenUTXOs(assetExec, token, addr)
assert.NoError(t, err)
assert.Equal(t, 5, len(utxos.utxos))
}
......@@ -209,27 +210,28 @@ func testStore_getWalletPrivacyTxDetails(t *testing.T) {
func testStore_listFrozenUTXOs(t *testing.T) {
store := createStore(t)
assetExec := "coins"
token := "BTY"
addr := "26htvcBNSEA7fZhAdLJphDwQRQJaHpyHTq"
txs, err := store.listFrozenUTXOs("", "")
txs, err := store.listFrozenUTXOs("", "", "")
assert.Nil(t, txs)
assert.NotNil(t, err)
txs, err = store.listFrozenUTXOs(token, addr)
txs, err = store.listFrozenUTXOs(assetExec, token, addr)
assert.Nil(t, txs)
assert.Nil(t, err)
tx := &pt.FTXOsSTXOsInOneTx{Tokenname: "BTY"}
bt, err := proto.Marshal(tx)
assert.NoError(t, err)
err = store.Set(calcKey4FTXOsInTx(token, addr, "TXHASH"), bt)
err = store.Set(calcKey4FTXOsInTx(assetExec, token, addr, "TXHASH"), bt)
assert.NoError(t, err)
txs, err = store.listFrozenUTXOs(token, addr)
txs, err = store.listFrozenUTXOs(assetExec, token, addr)
assert.Nil(t, txs)
assert.NotNil(t, err)
err = store.Set(calcKey4FTXOsInTx(token, addr, "TXHASH"), []byte("DataKey"))
err = store.Set(calcKey4FTXOsInTx(assetExec, token, addr, "TXHASH"), []byte("DataKey"))
assert.NoError(t, err)
err = store.Set([]byte("DataKey"), bt)
assert.NoError(t, err)
txs, err = store.listFrozenUTXOs(token, addr)
txs, err = store.listFrozenUTXOs(assetExec, token, addr)
assert.NoError(t, err)
assert.Equal(t, 1, len(txs))
assert.Equal(t, true, proto.Equal(tx, txs[0]))
......@@ -237,27 +239,29 @@ func testStore_listFrozenUTXOs(t *testing.T) {
func testStore_listAvailableUTXOs(t *testing.T) {
store := createStore(t)
utxos, err := store.listAvailableUTXOs("", "")
utxos, err := store.listAvailableUTXOs("", "", "")
assert.Nil(t, utxos)
assert.Equal(t, err, types.ErrInvalidParam)
addr := "16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTq"
assetExec := "coins"
token := "BTY"
txhash := "123456"
utxo := &pt.PrivacyDBStore{
AssetExec: assetExec,
Tokenname: "BTY",
}
key := calcUTXOKey4TokenAddr(token, addr, txhash, 0)
key := calcUTXOKey4TokenAddr(assetExec, token, addr, txhash, 0)
bt, err := proto.Marshal(utxo)
assert.NoError(t, err)
err = store.Set(key, []byte("AccKey"))
assert.NoError(t, err)
utxos, err = store.listAvailableUTXOs(token, addr)
utxos, err = store.listAvailableUTXOs(assetExec, token, addr)
assert.Nil(t, utxos)
assert.NotNil(t, err)
err = store.Set([]byte("AccKey"), bt)
assert.NoError(t, err)
utxos, err = store.listAvailableUTXOs(token, addr)
utxos, err = store.listAvailableUTXOs(assetExec, token, addr)
assert.NoError(t, err)
assert.Equal(t, 1, len(utxos))
assert.Equal(t, true, proto.Equal(utxo, utxos[0]))
......
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