Unverified Commit 1c63009b authored by vipwzw's avatar vipwzw Committed by GitHub

Merge pull request #643 from linj-disanbo/fix-retrieve

Fix retrieve
parents 3defc781 506a3b92
......@@ -11,7 +11,7 @@ function dapp_test_rpc() {
cp $DAPP_TEST_COMMON dapptest/
cd dapptest || return
dir=$(find . -maxdepth 1 -type d ! -name dapptest ! -name evm ! -name game ! -name guess ! -name hashlock ! -name ticket ! -name lottery ! -name pokerbull ! -name retrieve ! -name token ! -name trade ! -name . | sed 's/^\.\///' | sort)
dir=$(find . -maxdepth 1 -type d ! -name dapptest ! -name evm ! -name game ! -name guess ! -name hashlock ! -name ticket ! -name lottery ! -name pokerbull ! -name token ! -name trade ! -name . | sed 's/^\.\///' | sort)
echo "dapps list: $dir"
for app in $dir; do
......
......@@ -8,20 +8,72 @@ MAIN_HTTP=""
# shellcheck source=/dev/null
source ../dapp-test-common.sh
# TODO
# 1. 合约测试的先后顺序 是否可以在指定合约之后测试
# 2. 或将资产类的合约先测试
# 3. 或资产类的合约提供创建的函数 创建一个某某名字的token
function updateConfig() {
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer": "manage","actionName":"Modify","payload":{ "key": "token-blacklist","value": "BTY","op": "add","addr": ""}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "update config create tx" 1
return
fi
chain33_SignRawTx "${unsignedTx}" "0x4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01" "${MAIN_HTTP}"
}
function token_preCreate() {
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"token.CreateRawTokenPreCreateTx","params":[{"name": "yinhebib", "symbol": "'"$1"'", "total": 1000000000000, "price": 0, "category": 1,"owner":"'"$2"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token preCreate create tx" 1
return
fi
chain33_SignRawTx "${unsignedTx}" "0x4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01" "${MAIN_HTTP}"
}
function token_finish() {
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"token.CreateRawTokenFinishTx","params":[{"symbol": "'"$1"'", "owner":"'"$2"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token finish create tx" 1
return
fi
chain33_SignRawTx "${unsignedTx}" "0x4257d8692ef7fe13c68b65d6a52f03933db2fa5ce8faf210b5b8b80c721ced01" "${MAIN_HTTP}"
}
function token_sendExec() {
unsignedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.CreateTransaction","params":[{"execer": "'"${token_ame}"'","actionName":"TransferToExec","payload": {"cointoken":"'"$1"'", "amount": "10000000000", "note": "", "to": "'"${retrieve_addr}"'", "execName": "'"${retrieve_name}"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "${unsignedTx}" == "" ]; then
echo_rst "token sendExec create tx" 1
return
fi
chain33_SignRawTx "${unsignedTx}" "$3" "${MAIN_HTTP}"
}
function createToken() {
# symbol owner owner_key
updateConfig
token_preCreate "$1" "$2"
token_finish "$1" "$2"
token_sendExec "$1" "$2" "$3"
}
retrieve_Backup() {
echo "========== # retrieve backup begin =========="
local req='"method":"retrieve.CreateRawRetrieveBackupTx","params":[{"backupAddr":"1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX","defaultAddr":"1PUiGcbsccfxW3zuvHXZBJfznziph5miAo","delayPeriod": 61}]'
tx=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq -r ".result")
local req='{"method":"retrieve.CreateRawRetrieveBackupTx","params":[{"backupAddr":"'$retrieve1'","defaultAddr":"'$retrieve2'","delayPeriod": 61}]}'
tx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
local reqDecode='"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]'
data=$(curl -ksd "{$reqDecode}" ${MAIN_HTTP} | jq -r ".result.txs[0]")
local reqDecode='{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}'
data=$(curl -ksd "$reqDecode" ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignRawTx "$tx" "56942AD84CCF4788ED6DACBC005A1D0C4F91B63BCF0C99A02BE03C8DEAE71138" ${MAIN_HTTP}
chain33_SignRawTx "$tx" "$retrieve2_key" ${MAIN_HTTP}
echo "========== # retrieve backup end =========="
chain33_BlockWait 1 "${MAIN_HTTP}"
......@@ -30,17 +82,17 @@ retrieve_Backup() {
retrieve_Prepare() {
echo "========== # retrieve prepare begin =========="
local req='"method":"retrieve.CreateRawRetrievePrepareTx","params":[{"backupAddr":"1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX","defaultAddr":"1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"}]'
tx=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq -r ".result")
local req='{"method":"retrieve.CreateRawRetrievePrepareTx","params":[{"backupAddr":"'$retrieve1'","defaultAddr":"'$retrieve2'"}]}'
tx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
local reqDecode='"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]'
data=$(curl -ksd "{$reqDecode}" ${MAIN_HTTP} | jq -r ".result.txs[0]")
local reqDecode='{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}'
data=$(curl -ksd "$reqDecode" ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignRawTx "$tx" "2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989" ${MAIN_HTTP}
chain33_SignRawTx "$tx" "$retrieve1_key" ${MAIN_HTTP}
echo "========== # retrieve prepare end =========="
chain33_BlockWait 1 "${MAIN_HTTP}"
......@@ -49,17 +101,36 @@ retrieve_Prepare() {
retrieve_Perform() {
echo "========== # retrieve perform begin =========="
local req='"method":"retrieve.CreateRawRetrievePerformTx","params":[{"backupAddr":"1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX","defaultAddr":"1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"}]'
tx=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq -r ".result")
local req='{"method":"retrieve.CreateRawRetrievePerformTx","params":[{"backupAddr":"'$retrieve1'","defaultAddr":"'$retrieve2'"}]}'
tx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
local reqDecode='{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}'
data=$(curl -ksd "$reqDecode" ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignRawTx "$tx" "$retrieve1_key" ${MAIN_HTTP}
echo "========== # retrieve perform end =========="
chain33_BlockWait 1 "${MAIN_HTTP}"
}
retrieve_Perform_Token() {
echo "========== # retrieve perform begin =========="
local req='{"method":"retrieve.CreateRawRetrievePerformTx","params":[{"backupAddr":"'$retrieve1'","defaultAddr":"'$retrieve2'","assets": [{"exec":"token","symbol":"'"$symbol"'"}] }]}'
tx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
local reqDecode='"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]'
data=$(curl -ksd "{$reqDecode}" ${MAIN_HTTP} | jq -r ".result.txs[0]")
local reqDecode='{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}'
data=$(curl -ksd "$reqDecode" ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignRawTx "$tx" "2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989" ${MAIN_HTTP}
chain33_SignRawTx "$tx" "$retrieve1_key" ${MAIN_HTTP}
echo "========== # retrieve perform end =========="
chain33_BlockWait 1 "${MAIN_HTTP}"
......@@ -68,17 +139,17 @@ retrieve_Perform() {
retrieve_Cancel() {
echo "========== # retrieve cancel begin =========="
local req='"method":"retrieve.CreateRawRetrieveCancelTx","params":[{"backupAddr":"1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX","defaultAddr":"1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"}]'
tx=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq -r ".result")
local req='{"method":"retrieve.CreateRawRetrieveCancelTx","params":[{"backupAddr":"'$retrieve1'","defaultAddr":"'$retrieve2'"}]}'
tx=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
local reqDecode='"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]'
data=$(curl -ksd "{$reqDecode}" ${MAIN_HTTP} | jq -r ".result.txs[0]")
local reqDecode='{"method":"Chain33.DecodeRawTransaction","params":[{"txHex":"'"$tx"'"}]}'
data=$(curl -ksd "$reqDecode" ${MAIN_HTTP} | jq -r ".result.txs[0]")
ok=$(jq '(.execer != "")' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
chain33_SignRawTx "$tx" "56942AD84CCF4788ED6DACBC005A1D0C4F91B63BCF0C99A02BE03C8DEAE71138" ${MAIN_HTTP}
chain33_SignRawTx "$tx" "$retrieve2_key" ${MAIN_HTTP}
echo "========== # retrieve cancel end =========="
chain33_BlockWait 1 "${MAIN_HTTP}"
......@@ -89,8 +160,22 @@ retrieve_QueryResult() {
local status=$1
local req='"method":"Chain33.Query","params":[{"execer":"retrieve","funcName":"GetRetrieveInfo","payload":{"backupAddress":"1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX", "defaultAddress":"1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"}}]'
data=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq -r ".result")
local req='{"method":"Chain33.Query","params":[{"execer":"retrieve","funcName":"GetRetrieveInfo","payload":{"backupAddress":"'$retrieve1'", "defaultAddress":"'$retrieve2'"}}]}'
data=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
ok=$(jq '(.status == '"$status"')' <<<"$data")
[ "$ok" == true ]
echo_rst "$FUNCNAME" "$?"
echo "========== # retrieve query result end =========="
}
retrieve_QueryAssetResult() {
echo "========== # retrieve query result begin =========="
local status=$1
local req='{"method":"Chain33.Query","params":[{"execer":"retrieve","funcName":"GetRetrieveInfo","payload":{"backupAddress":"'$retrieve1'", "defaultAddress":"'$retrieve2'","assetExec":"token", "assetSymbol":"'"$symbol"'"}}]}'
data=$(curl -ksd "$req" ${MAIN_HTTP} | jq -r ".result")
ok=$(jq '(.status == '"$status"')' <<<"$data")
[ "$ok" == true ]
......@@ -102,16 +187,36 @@ init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
echo "ipara=$ispara"
if [ "$ispara" == true ]; then
token_ame="user.p.para.token"
retrieve_name="user.p.para.retrieve"
retrieve_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"user.p.para.retrieve"}]}' ${MAIN_HTTP} | jq -r ".result")
else
token_ame="token"
retrieve_name="retrieve"
retrieve_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"retrieve"}]}' ${MAIN_HTTP} | jq -r ".result")
fi
local from="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
chain33_SendToAddress "$from" "$retrieve_addr" 1000000000 ${MAIN_HTTP}
retrieve1_key=0xf54a8ffe50b308a2d37f44a9e595fd2d156c09732b712b8548eccf1dce4d0fde
retrieve1=19P3ZQg5VYgzTUGvLD4etFSrh74mk6HUWW
chain33_ImportPrivkey "${retrieve1_key}" "${retrieve1}" "retrieve1" "${MAIN_HTTP}"
chain33_applyCoins "${retrieve1}" 10000000000 "${MAIN_HTTP}"
retrieve2_key=0x61d86bf173ed37835fba9ff5b062382249c1b978cb2d3c6e2a3abbdf38314432
retrieve2=18x7o8Uktqs8RHEcPsMLJvaHKo22swLbqF
chain33_ImportPrivkey "${retrieve2_key}" "${retrieve2}" "retrieve2" "${MAIN_HTTP}"
chain33_applyCoins "${retrieve2}" 10000000000 "${MAIN_HTTP}"
if [ "$ispara" == true ]; then
# for fee
local main_ip=${MAIN_HTTP//8901/8801}
chain33_applyCoins "${retrieve1}" 1000000000 "${main_ip}"
chain33_applyCoins "${retrieve2}" 1000000000 "${main_ip}"
fi
from="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
chain33_SendToAddress "$from" "$retrieve_addr" 1000000000 ${MAIN_HTTP}
chain33_SendToAddress "$retrieve1" "$retrieve_addr" 1000000000 ${MAIN_HTTP}
chain33_SendToAddress "$retrieve2" "$retrieve_addr" 1000000000 ${MAIN_HTTP}
symbol="RETRIEVE"
createToken "$symbol" "$retrieve2" "$retrieve2_key"
chain33_BlockWait 1 "${MAIN_HTTP}"
}
......@@ -134,6 +239,8 @@ function run_test() {
sleep 61
retrieve_Perform
retrieve_QueryResult 3
retrieve_Perform_Token
retrieve_QueryAssetResult 3
}
function main() {
......@@ -152,4 +259,5 @@ function main() {
fi
}
set -x
main "$1"
......@@ -168,7 +168,7 @@ func performCmd(cmd *cobra.Command, args []string) {
return
}
for i := 0; i < len(execs); i++ {
params.Assets = append(params.Assets, rpc.Asset{Exec: execs[i], Symbol: symbols[0]})
params.Assets = append(params.Assets, rpc.Asset{Exec: execs[i], Symbol: symbols[i]})
}
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "retrieve.CreateRawRetrievePerformTx", params, nil)
......@@ -206,7 +206,7 @@ func cancelCmd(cmd *cobra.Command, args []string) {
func RetrieveQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Short: "Backup the wallet",
Short: "show retrieve info",
Run: queryRetrieveCmd,
}
addQueryRetrieveCmdFlags(cmd)
......@@ -218,6 +218,9 @@ func addQueryRetrieveCmdFlags(cmd *cobra.Command) {
cmd.MarkFlagRequired("backup")
cmd.Flags().StringP("default", "t", "", "default address")
cmd.MarkFlagRequired("default")
cmd.Flags().StringP("asset_exec", "e", "", "asset exec")
cmd.Flags().StringP("asset_symbol", "s", "", "asset symbol")
}
func parseRerieveDetail(arg interface{}) (interface{}, error) {
......@@ -246,10 +249,14 @@ func queryRetrieveCmd(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
backup, _ := cmd.Flags().GetString("backup")
defaultAddr, _ := cmd.Flags().GetString("default")
exec, _ := cmd.Flags().GetString("asset_exec")
symbol, _ := cmd.Flags().GetString("asset_symbol")
req := &rt.ReqRetrieveInfo{
BackupAddress: backup,
DefaultAddress: defaultAddr,
AssetExec: exec,
AssetSymbol: symbol,
}
var params rpctypes.Query4Jrpc
......
......@@ -97,7 +97,7 @@ func (c *Retrieve) ExecDelLocal_Perform(perf *rt.PerformRetrieve, tx *types.Tran
if types.IsDappFork(c.GetHeight(), rt.RetrieveX, rt.ForkRetriveAssetX) {
if len(perf.Assets) == 0 {
perf.Assets = append(perf.Assets, &types.Asset{Exec: "coins", Symbol: types.GetCoinSymbol()})
perf.Assets = append(perf.Assets, &rt.AssetSymbol{Exec: "coins", Symbol: types.GetCoinSymbol()})
}
}
for _, asset := range perf.Assets {
......
......@@ -104,7 +104,7 @@ func (c *Retrieve) ExecLocal_Perform(perf *rt.PerformRetrieve, tx *types.Transac
}
if types.IsDappFork(c.GetHeight(), rt.RetrieveX, rt.ForkRetriveAssetX) {
if len(perf.Assets) == 0 {
perf.Assets = append(perf.Assets, &types.Asset{Exec: "coins", Symbol: types.GetCoinSymbol()})
perf.Assets = append(perf.Assets, &rt.AssetSymbol{Exec: "coins", Symbol: types.GetCoinSymbol()})
}
}
for _, asset := range perf.Assets {
......
......@@ -5,8 +5,6 @@
package executor
import (
"fmt"
"github.com/33cn/chain33/types"
rt "github.com/33cn/plugin/plugin/dapp/retrieve/types"
)
......@@ -29,11 +27,9 @@ func (r *Retrieve) Query_GetRetrieveInfo(in *rt.ReqRetrieveInfo) (types.Message,
if info.Status == retrievePerform && in.GetAssetExec() != "" {
// retrievePerform状态下,不存在有两种情况
// 1 还没找回, 2 fork 之前是没有coins 找回记录的
count := r.GetLocalDB().PrefixCount(calcRetrieveAssetPrefix(in.BackupAddress, in.DefaultAddress))
// 2 fork 之前是 没有coins 找回记录的, 相当于都找回了
if count == 0 {
return info, nil
}
// localdb not support PrefixCount
// 所以在填写具体资产的情况下, 认为是要找对应的资产
asset, _ := getRetrieveAsset(r.GetLocalDB(), in.BackupAddress, in.DefaultAddress, in.AssetExec, in.AssetSymbol)
if asset != nil {
......@@ -48,8 +44,3 @@ func (r *Retrieve) Query_GetRetrieveInfo(in *rt.ReqRetrieveInfo) (types.Message,
}
return info, nil
}
func calcRetrieveAssetPrefix(backupAddr, defaultAddr string) []byte {
key := fmt.Sprintf("LODB-retrieve-backup-asset:%s:%s:", backupAddr, defaultAddr)
return []byte(key)
}
......@@ -211,7 +211,7 @@ func (action *Action) RetrievePerformAssets(perfRet *rt.PerformRetrieve, default
// 兼容原来的找回, 在不指定的情况下,找回主币
if len(perfRet.Assets) == 0 {
perfRet.Assets = append(perfRet.Assets, &types.Asset{Exec: "coins", Symbol: types.GetCoinSymbol()})
perfRet.Assets = append(perfRet.Assets, &rt.AssetSymbol{Exec: "coins", Symbol: types.GetCoinSymbol()})
//return nil, nil
}
......@@ -224,7 +224,7 @@ func (action *Action) RetrievePerformAssets(perfRet *rt.PerformRetrieve, default
acc := accdb.LoadExecAccount(defaultAddress, action.execaddr)
rlog.Debug("RetrievePerform", "acc.Balance", acc.Balance)
if acc.Balance > 0 {
receipt, err = action.coinsAccount.ExecTransfer(defaultAddress, perfRet.BackupAddress, action.execaddr, acc.Balance)
receipt, err = accdb.ExecTransfer(defaultAddress, perfRet.BackupAddress, action.execaddr, acc.Balance)
if err != nil {
rlog.Debug("RetrievePerform", "ExecTransfer", err)
return nil, err
......
......@@ -40,10 +40,16 @@ message PrepareRetrieve {
string defaultAddress = 2;
}
message AssetSymbol {
string exec = 1;
string symbol = 2;
}
message PerformRetrieve {
string backupAddress = 1;
string defaultAddress = 2;
repeated Asset assets = 3;
repeated AssetSymbol assets = 3;
}
message CancelRetrieve {
......
......@@ -49,6 +49,11 @@ func (c *Jrpc) CreateRawRetrievePerformTx(in *RetrievePerformTx, result *interfa
head := &types.PerformRetrieve{
BackupAddress: in.BackupAddr,
DefaultAddress: in.DefaultAddr,
Assets: []*types.AssetSymbol{},
}
for i := 0; i < len(in.Assets); i++ {
head.Assets = append(head.Assets, &types.AssetSymbol{Exec: in.Assets[i].Exec, Symbol: in.Assets[i].Symbol})
}
reply, err := c.cli.Perform(context.Background(), head)
if err != nil {
......
......@@ -8,11 +8,14 @@ import (
"strings"
"testing"
"github.com/33cn/chain33/common"
commonlog "github.com/33cn/chain33/common/log"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util/testnode"
"github.com/33cn/plugin/plugin/dapp/retrieve/rpc"
pty "github.com/33cn/plugin/plugin/dapp/retrieve/types"
"github.com/stretchr/testify/assert"
......@@ -67,8 +70,28 @@ func testPrepareCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
}
func testPerformCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
params := rpc.RetrievePerformTx{}
return jrpc.Call("retrieve.CreateRawRetrievePerformTx", params, nil)
params := rpc.RetrievePerformTx{
BackupAddr: "b",
DefaultAddr: "d",
Assets: []rpc.Asset{{"e", "s"}},
}
var txS string
t.Log("tx info", "x", params.Assets)
err := jrpc.Call("retrieve.CreateRawRetrievePerformTx", &params, &txS)
var tx types.Transaction
bytes, err := common.FromHex(txS)
if err != nil {
return err
}
err = types.Decode(bytes, &tx)
if err != nil {
return err
}
var p2 pty.RetrieveAction
err = types.Decode(tx.Payload, &p2)
t.Log("asset", p2.GetPerform().GetAssets())
return err
}
func testCancelCmd(t *testing.T, jrpc *jsonclient.JSONClient) error {
......
......@@ -43,10 +43,12 @@ func (c *channelClient) Perform(ctx context.Context, v *rt.PerformRetrieve) (*ty
Ty: rt.RetrieveActionPerform,
Value: &rt.RetrieveAction_Perform{Perform: v},
}
tx, err := types.CreateFormatTx(types.ExecName(rt.RetrieveX), types.Encode(perform))
payload := types.Encode(perform)
tx, err := types.CreateFormatTx(types.ExecName(rt.RetrieveX), payload)
if err != nil {
return nil, err
}
data := types.Encode(tx)
return &types.UnsignTx{Data: data}, nil
}
......
......@@ -44,7 +44,7 @@ func (m *RetrievePara) Reset() { *m = RetrievePara{} }
func (m *RetrievePara) String() string { return proto.CompactTextString(m) }
func (*RetrievePara) ProtoMessage() {}
func (*RetrievePara) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{0}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{0}
}
func (m *RetrievePara) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RetrievePara.Unmarshal(m, b)
......@@ -112,7 +112,7 @@ func (m *Retrieve) Reset() { *m = Retrieve{} }
func (m *Retrieve) String() string { return proto.CompactTextString(m) }
func (*Retrieve) ProtoMessage() {}
func (*Retrieve) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{1}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{1}
}
func (m *Retrieve) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Retrieve.Unmarshal(m, b)
......@@ -163,7 +163,7 @@ func (m *RetrieveAction) Reset() { *m = RetrieveAction{} }
func (m *RetrieveAction) String() string { return proto.CompactTextString(m) }
func (*RetrieveAction) ProtoMessage() {}
func (*RetrieveAction) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{2}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{2}
}
func (m *RetrieveAction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RetrieveAction.Unmarshal(m, b)
......@@ -378,7 +378,7 @@ func (m *BackupRetrieve) Reset() { *m = BackupRetrieve{} }
func (m *BackupRetrieve) String() string { return proto.CompactTextString(m) }
func (*BackupRetrieve) ProtoMessage() {}
func (*BackupRetrieve) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{3}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{3}
}
func (m *BackupRetrieve) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BackupRetrieve.Unmarshal(m, b)
......@@ -431,7 +431,7 @@ func (m *PrepareRetrieve) Reset() { *m = PrepareRetrieve{} }
func (m *PrepareRetrieve) String() string { return proto.CompactTextString(m) }
func (*PrepareRetrieve) ProtoMessage() {}
func (*PrepareRetrieve) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{4}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{4}
}
func (m *PrepareRetrieve) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PrepareRetrieve.Unmarshal(m, b)
......@@ -465,10 +465,56 @@ func (m *PrepareRetrieve) GetDefaultAddress() string {
return ""
}
type AssetSymbol struct {
Exec string `protobuf:"bytes,1,opt,name=exec,proto3" json:"exec,omitempty"`
Symbol string `protobuf:"bytes,2,opt,name=symbol,proto3" json:"symbol,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *AssetSymbol) Reset() { *m = AssetSymbol{} }
func (m *AssetSymbol) String() string { return proto.CompactTextString(m) }
func (*AssetSymbol) ProtoMessage() {}
func (*AssetSymbol) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{5}
}
func (m *AssetSymbol) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_AssetSymbol.Unmarshal(m, b)
}
func (m *AssetSymbol) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_AssetSymbol.Marshal(b, m, deterministic)
}
func (dst *AssetSymbol) XXX_Merge(src proto.Message) {
xxx_messageInfo_AssetSymbol.Merge(dst, src)
}
func (m *AssetSymbol) XXX_Size() int {
return xxx_messageInfo_AssetSymbol.Size(m)
}
func (m *AssetSymbol) XXX_DiscardUnknown() {
xxx_messageInfo_AssetSymbol.DiscardUnknown(m)
}
var xxx_messageInfo_AssetSymbol proto.InternalMessageInfo
func (m *AssetSymbol) GetExec() string {
if m != nil {
return m.Exec
}
return ""
}
func (m *AssetSymbol) GetSymbol() string {
if m != nil {
return m.Symbol
}
return ""
}
type PerformRetrieve struct {
BackupAddress string `protobuf:"bytes,1,opt,name=backupAddress,proto3" json:"backupAddress,omitempty"`
DefaultAddress string `protobuf:"bytes,2,opt,name=defaultAddress,proto3" json:"defaultAddress,omitempty"`
Assets []*types.Asset `protobuf:"bytes,3,rep,name=assets,proto3" json:"assets,omitempty"`
Assets []*AssetSymbol `protobuf:"bytes,3,rep,name=assets,proto3" json:"assets,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -478,7 +524,7 @@ func (m *PerformRetrieve) Reset() { *m = PerformRetrieve{} }
func (m *PerformRetrieve) String() string { return proto.CompactTextString(m) }
func (*PerformRetrieve) ProtoMessage() {}
func (*PerformRetrieve) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{5}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{6}
}
func (m *PerformRetrieve) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PerformRetrieve.Unmarshal(m, b)
......@@ -512,7 +558,7 @@ func (m *PerformRetrieve) GetDefaultAddress() string {
return ""
}
func (m *PerformRetrieve) GetAssets() []*types.Asset {
func (m *PerformRetrieve) GetAssets() []*AssetSymbol {
if m != nil {
return m.Assets
}
......@@ -531,7 +577,7 @@ func (m *CancelRetrieve) Reset() { *m = CancelRetrieve{} }
func (m *CancelRetrieve) String() string { return proto.CompactTextString(m) }
func (*CancelRetrieve) ProtoMessage() {}
func (*CancelRetrieve) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{6}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{7}
}
func (m *CancelRetrieve) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CancelRetrieve.Unmarshal(m, b)
......@@ -579,7 +625,7 @@ func (m *ReqRetrieveInfo) Reset() { *m = ReqRetrieveInfo{} }
func (m *ReqRetrieveInfo) String() string { return proto.CompactTextString(m) }
func (*ReqRetrieveInfo) ProtoMessage() {}
func (*ReqRetrieveInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{7}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{8}
}
func (m *ReqRetrieveInfo) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReqRetrieveInfo.Unmarshal(m, b)
......@@ -643,7 +689,7 @@ func (m *RetrieveQuery) Reset() { *m = RetrieveQuery{} }
func (m *RetrieveQuery) String() string { return proto.CompactTextString(m) }
func (*RetrieveQuery) ProtoMessage() {}
func (*RetrieveQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_retrieve_7b99e170a1cce215, []int{8}
return fileDescriptor_retrieve_1666ef19b265e4fc, []int{9}
}
func (m *RetrieveQuery) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RetrieveQuery.Unmarshal(m, b)
......@@ -711,6 +757,7 @@ func init() {
proto.RegisterType((*RetrieveAction)(nil), "types.RetrieveAction")
proto.RegisterType((*BackupRetrieve)(nil), "types.BackupRetrieve")
proto.RegisterType((*PrepareRetrieve)(nil), "types.PrepareRetrieve")
proto.RegisterType((*AssetSymbol)(nil), "types.AssetSymbol")
proto.RegisterType((*PerformRetrieve)(nil), "types.PerformRetrieve")
proto.RegisterType((*CancelRetrieve)(nil), "types.CancelRetrieve")
proto.RegisterType((*ReqRetrieveInfo)(nil), "types.ReqRetrieveInfo")
......@@ -888,41 +935,43 @@ var _Retrieve_serviceDesc = grpc.ServiceDesc{
Metadata: "retrieve.proto",
}
func init() { proto.RegisterFile("retrieve.proto", fileDescriptor_retrieve_7b99e170a1cce215) }
var fileDescriptor_retrieve_7b99e170a1cce215 = []byte{
// 527 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xd1, 0x6e, 0xd3, 0x30,
0x14, 0x9d, 0x5b, 0x9a, 0xae, 0xb7, 0x5b, 0x2a, 0x8c, 0x98, 0xa2, 0x09, 0x4d, 0x55, 0x34, 0xa1,
0xbe, 0x50, 0xa4, 0xc0, 0x0f, 0x74, 0x08, 0x09, 0xde, 0x8a, 0x19, 0xaf, 0x20, 0x37, 0xb9, 0x45,
0x11, 0x6d, 0x12, 0x6c, 0x67, 0x5a, 0xde, 0x78, 0xe1, 0x3b, 0xf8, 0x07, 0xfe, 0x86, 0x17, 0x7e,
0x82, 0x1f, 0x40, 0xb1, 0x1d, 0xcd, 0x29, 0xa9, 0xb4, 0x87, 0x8a, 0xc7, 0x1c, 0x9f, 0x63, 0xdf,
0x7b, 0xee, 0xed, 0x29, 0xf8, 0x02, 0x95, 0x48, 0xf1, 0x06, 0xe7, 0x85, 0xc8, 0x55, 0x4e, 0x07,
0xaa, 0x2a, 0x50, 0x9e, 0x3f, 0x54, 0x82, 0x67, 0x92, 0xc7, 0x2a, 0xcd, 0x33, 0x73, 0x12, 0xfe,
0x24, 0x70, 0xc2, 0x2c, 0x79, 0xc9, 0x05, 0xa7, 0x4f, 0xc1, 0x4f, 0x70, 0xcd, 0xcb, 0x8d, 0x5a,
0x24, 0x89, 0x40, 0x29, 0x03, 0x32, 0x25, 0xb3, 0x11, 0xdb, 0x41, 0xe9, 0x19, 0x78, 0x52, 0x71,
0x55, 0xca, 0xa0, 0x37, 0x25, 0xb3, 0x01, 0xb3, 0x5f, 0xf4, 0x02, 0x20, 0x16, 0xc8, 0x15, 0x5e,
0xa7, 0x5b, 0x0c, 0xfa, 0x53, 0x32, 0xeb, 0x33, 0x07, 0xa1, 0x53, 0x18, 0x17, 0x02, 0x0b, 0x2e,
0x0c, 0xe1, 0x81, 0x26, 0xb8, 0x50, 0xcd, 0x48, 0x70, 0xc3, 0xab, 0x25, 0x8a, 0x34, 0x4f, 0x82,
0x81, 0x61, 0x38, 0x50, 0xf8, 0x09, 0x8e, 0x9b, 0x9a, 0xe9, 0x25, 0x9c, 0xae, 0x78, 0xfc, 0xa5,
0x2c, 0xda, 0xe5, 0xb6, 0x41, 0xfa, 0x0c, 0x86, 0x02, 0x55, 0xdd, 0x60, 0xd0, 0x9b, 0xf6, 0x67,
0xe3, 0xe8, 0xd1, 0x5c, 0x5b, 0x32, 0x77, 0x7b, 0x67, 0x0d, 0x27, 0xfc, 0x43, 0xc0, 0x6f, 0x4e,
0x16, 0xda, 0x2e, 0x1a, 0xc1, 0xd0, 0x16, 0xa9, 0x5f, 0x18, 0x47, 0x67, 0xf6, 0x86, 0xa5, 0x41,
0x1b, 0xfa, 0x9b, 0x23, 0xd6, 0x10, 0xb5, 0x06, 0xc5, 0x3a, 0x17, 0x5b, 0x6d, 0x92, 0xa3, 0x31,
0x68, 0x4b, 0x63, 0x20, 0xfa, 0x1c, 0x3c, 0x53, 0xba, 0xf6, 0x6e, 0x1c, 0x3d, 0xb6, 0x92, 0x2b,
0x0d, 0x3a, 0x0a, 0x4b, 0xab, 0x05, 0x31, 0xcf, 0x62, 0xdc, 0x68, 0x2f, 0xef, 0x04, 0xaf, 0x34,
0xe8, 0x0a, 0x0c, 0x8d, 0xfa, 0xd0, 0x53, 0x95, 0xb6, 0x75, 0xc0, 0x7a, 0xaa, 0xba, 0x1a, 0xc2,
0xe0, 0x86, 0x6f, 0x4a, 0x0c, 0xbf, 0x11, 0xf0, 0xdb, 0xcf, 0xdc, 0xd3, 0xdd, 0x7f, 0x77, 0xa6,
0xd7, 0xb9, 0x33, 0x3b, 0x93, 0xed, 0x77, 0x4d, 0x76, 0xb2, 0xe3, 0xe7, 0x61, 0x4b, 0x08, 0xbf,
0x13, 0x98, 0xec, 0xb8, 0x7f, 0xe0, 0x26, 0x2f, 0xc1, 0xe3, 0x52, 0xa2, 0x92, 0x41, 0x5f, 0x6f,
0xda, 0x89, 0x9d, 0xc7, 0xa2, 0x06, 0x99, 0x3d, 0x0b, 0x3f, 0x82, 0xdf, 0x1e, 0xd0, 0x81, 0xfb,
0xfc, 0x41, 0x60, 0xc2, 0xf0, 0x6b, 0x73, 0xfb, 0xdb, 0x6c, 0x9d, 0x1f, 0xb8, 0xcf, 0x27, 0x30,
0xd2, 0xbd, 0xbc, 0xbe, 0xc5, 0x58, 0x8f, 0x72, 0xc4, 0xee, 0x80, 0x7a, 0xd4, 0xfa, 0xe3, 0x7d,
0xb5, 0x5d, 0xe5, 0x66, 0x35, 0x47, 0xcc, 0x85, 0xc2, 0x5f, 0x04, 0x4e, 0x9b, 0xf2, 0xde, 0x95,
0x28, 0xaa, 0xff, 0xbd, 0x6c, 0xf7, 0x88, 0xa2, 0x0b, 0x00, 0x81, 0x5b, 0x9e, 0x66, 0x9a, 0x60,
0x92, 0xc8, 0x41, 0x9c, 0x10, 0xf4, 0xdc, 0x10, 0x8c, 0x7e, 0x13, 0x38, 0x6e, 0x22, 0x98, 0xbe,
0x84, 0xa1, 0xdd, 0x69, 0xba, 0x27, 0x33, 0xce, 0x27, 0x16, 0xff, 0x90, 0xc9, 0xf4, 0x73, 0x76,
0x7d, 0x1b, 0x1e, 0x69, 0x95, 0x8d, 0x84, 0x3d, 0xa9, 0xd1, 0xa5, 0x8a, 0xc0, 0x33, 0xbf, 0x60,
0xda, 0x9d, 0x1b, 0x7b, 0x34, 0x66, 0x15, 0x69, 0x77, 0x74, 0x74, 0x68, 0x56, 0x9e, 0xfe, 0xf7,
0x78, 0xf1, 0x37, 0x00, 0x00, 0xff, 0xff, 0x32, 0x13, 0x1c, 0xa2, 0x69, 0x06, 0x00, 0x00,
func init() { proto.RegisterFile("retrieve.proto", fileDescriptor_retrieve_1666ef19b265e4fc) }
var fileDescriptor_retrieve_1666ef19b265e4fc = []byte{
// 552 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0xed, 0xc6, 0x8d, 0xd3, 0x4c, 0xa8, 0x23, 0x16, 0x51, 0x59, 0x15, 0xaa, 0x22, 0x0b, 0xa1,
0x08, 0x89, 0x20, 0x19, 0x2e, 0x1c, 0x53, 0x84, 0x04, 0xb7, 0x60, 0xca, 0x15, 0xb4, 0x71, 0x26,
0xc8, 0x22, 0xb1, 0xc3, 0xee, 0xa6, 0xaa, 0x6f, 0xdc, 0xf9, 0x08, 0xfe, 0x81, 0xbf, 0xe1, 0xc2,
0x4f, 0xf0, 0x03, 0xc8, 0xb3, 0x6b, 0x65, 0x13, 0x1c, 0xa9, 0x87, 0xa8, 0xb7, 0xf8, 0xed, 0x7b,
0xeb, 0x99, 0x37, 0x93, 0x67, 0x08, 0x24, 0x6a, 0x99, 0xe1, 0x35, 0x8e, 0x56, 0xb2, 0xd0, 0x05,
0x6f, 0xeb, 0x72, 0x85, 0xea, 0xfc, 0xbe, 0x96, 0x22, 0x57, 0x22, 0xd5, 0x59, 0x91, 0x9b, 0x93,
0xe8, 0x17, 0x83, 0x7b, 0x89, 0x25, 0x4f, 0x84, 0x14, 0xfc, 0x09, 0x04, 0x33, 0x9c, 0x8b, 0xf5,
0x42, 0x8f, 0x67, 0x33, 0x89, 0x4a, 0x85, 0x6c, 0xc0, 0x86, 0xdd, 0x64, 0x07, 0xe5, 0x67, 0xe0,
0x2b, 0x2d, 0xf4, 0x5a, 0x85, 0xad, 0x01, 0x1b, 0xb6, 0x13, 0xfb, 0xc4, 0x2f, 0x00, 0x52, 0x89,
0x42, 0xe3, 0x55, 0xb6, 0xc4, 0xd0, 0x1b, 0xb0, 0xa1, 0x97, 0x38, 0x08, 0x1f, 0x40, 0x6f, 0x25,
0x71, 0x25, 0xa4, 0x21, 0x1c, 0x13, 0xc1, 0x85, 0x2a, 0xc6, 0x0c, 0x17, 0xa2, 0x9c, 0xa0, 0xcc,
0x8a, 0x59, 0xd8, 0x36, 0x0c, 0x07, 0x8a, 0x3e, 0xc3, 0x49, 0x5d, 0x33, 0x7f, 0x0c, 0xa7, 0x53,
0x91, 0x7e, 0x5d, 0xaf, 0xb6, 0xcb, 0xdd, 0x06, 0xf9, 0x33, 0xe8, 0x48, 0xd4, 0x55, 0x83, 0x61,
0x6b, 0xe0, 0x0d, 0x7b, 0xf1, 0x83, 0x11, 0x59, 0x32, 0x72, 0x7b, 0x4f, 0x6a, 0x4e, 0xf4, 0x97,
0x41, 0x50, 0x9f, 0x8c, 0xc9, 0x2e, 0x1e, 0x43, 0xc7, 0x16, 0x49, 0x6f, 0xe8, 0xc5, 0x67, 0xf6,
0x86, 0x89, 0x41, 0x6b, 0xfa, 0xdb, 0xa3, 0xa4, 0x26, 0x92, 0x06, 0xe5, 0xbc, 0x90, 0x4b, 0x32,
0xc9, 0xd1, 0x18, 0x74, 0x4b, 0x63, 0x20, 0xfe, 0x1c, 0x7c, 0x53, 0x3a, 0x79, 0xd7, 0x8b, 0x1f,
0x5a, 0xc9, 0x25, 0x81, 0x8e, 0xc2, 0xd2, 0x2a, 0x41, 0x2a, 0xf2, 0x14, 0x17, 0xe4, 0xe5, 0x46,
0xf0, 0x9a, 0x40, 0x57, 0x60, 0x68, 0x3c, 0x80, 0x96, 0x2e, 0xc9, 0xd6, 0x76, 0xd2, 0xd2, 0xe5,
0x65, 0x07, 0xda, 0xd7, 0x62, 0xb1, 0xc6, 0xe8, 0x3b, 0x83, 0x60, 0xfb, 0x35, 0xb7, 0x74, 0xf7,
0xff, 0x9d, 0x69, 0x35, 0xee, 0xcc, 0xce, 0x64, 0xbd, 0xa6, 0xc9, 0xf6, 0x77, 0xfc, 0x3c, 0x6c,
0x09, 0xd1, 0x2b, 0xe8, 0x8d, 0x95, 0x42, 0xfd, 0xa1, 0x5c, 0x4e, 0x8b, 0x05, 0xe7, 0x70, 0x8c,
0x37, 0x98, 0xda, 0x3b, 0xe9, 0x37, 0x6d, 0x36, 0x9d, 0xda, 0x2b, 0xec, 0x53, 0xf4, 0x83, 0x41,
0x7f, 0x67, 0x70, 0x07, 0xf6, 0xe7, 0x29, 0xf8, 0xa2, 0x2a, 0x4e, 0x85, 0x1e, 0x2d, 0x29, 0xb7,
0xa3, 0x74, 0x2a, 0x4e, 0x2c, 0x23, 0xfa, 0x04, 0xc1, 0xf6, 0x84, 0x0f, 0x6c, 0xd4, 0x4f, 0x06,
0xfd, 0x04, 0xbf, 0xd5, 0xb7, 0xbf, 0xcb, 0xe7, 0xc5, 0x81, 0xbb, 0x7d, 0x04, 0x5d, 0xea, 0xe5,
0x4d, 0x35, 0x00, 0x8f, 0x28, 0x1b, 0xa0, 0xda, 0x15, 0xb1, 0x69, 0x9b, 0x76, 0xbb, 0x9b, 0xb8,
0x50, 0xf4, 0x9b, 0xc1, 0x69, 0x5d, 0xde, 0xfb, 0x35, 0xca, 0xf2, 0xae, 0xb7, 0xf5, 0x16, 0x59,
0x76, 0x01, 0x20, 0x71, 0x29, 0xb2, 0x9c, 0x08, 0x26, 0xca, 0x1c, 0xc4, 0x49, 0x51, 0xdf, 0x4d,
0xd1, 0xf8, 0x0f, 0x83, 0x93, 0x3a, 0xc3, 0xf9, 0x4b, 0xe8, 0xd8, 0x3f, 0x05, 0xdf, 0x13, 0x3a,
0xe7, 0x7d, 0x8b, 0x7f, 0xcc, 0x55, 0xf6, 0x25, 0xbf, 0xba, 0x89, 0x8e, 0x48, 0x65, 0x33, 0x65,
0x4f, 0xec, 0x34, 0xa9, 0x62, 0xf0, 0x4d, 0x04, 0xf0, 0xe6, 0xe0, 0xd9, 0xa3, 0x31, 0xab, 0xc8,
0x9b, 0xb3, 0xa7, 0x41, 0x33, 0xf5, 0xe9, 0xf3, 0xf3, 0xe2, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff,
0x01, 0xad, 0xc9, 0x3d, 0xaa, 0x06, 0x00, 0x00,
}
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