Commit 83f86a48 authored by 张振华's avatar 张振华

Merge branch 'master' into guess-rpc-test

parents 893f8745 95f6063b
...@@ -136,12 +136,12 @@ returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa" ...@@ -136,12 +136,12 @@ returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa"
count=10000 count=10000
[store] [store]
name="mavl" name="kvmvccmavl"
driver="leveldb" driver="leveldb"
dbPath="datadir/mavltree" dbPath="datadir/mavltree"
dbCache=128 dbCache=128
# store数据库版本 # store数据库版本
storedbVersion="1.0.0" storedbVersion="2.0.0"
[store.sub.mavl] [store.sub.mavl]
enableMavlPrefix=false enableMavlPrefix=false
...@@ -154,6 +154,7 @@ enableMemTree=true ...@@ -154,6 +154,7 @@ enableMemTree=true
enableMemVal=true enableMemVal=true
[store.sub.kvmvccmavl] [store.sub.kvmvccmavl]
enableMVCCIter=true
enableMavlPrefix=false enableMavlPrefix=false
enableMVCC=false enableMVCC=false
enableMavlPrune=false enableMavlPrune=false
......
...@@ -34,7 +34,7 @@ const ( ...@@ -34,7 +34,7 @@ const (
addAct int64 = 1 //add para block action addAct int64 = 1 //add para block action
delAct int64 = 2 //reference blockstore.go, del para block action delAct int64 = 2 //reference blockstore.go, del para block action
minBlockNum = 6 //min block number startHeight before lastHeight in mainchain minBlockNum = 100 //min block number startHeight before lastHeight in mainchain
) )
var ( var (
......
...@@ -19,7 +19,7 @@ import ( ...@@ -19,7 +19,7 @@ import (
var ( var (
consensusInterval = 16 //about 1 new block interval consensusInterval = 16 //about 1 new block interval
minerInterval = 2 minerInterval = 5
) )
type commitMsgClient struct { type commitMsgClient struct {
...@@ -130,6 +130,9 @@ out: ...@@ -130,6 +130,9 @@ out:
plog.Error("para commit msg read tick", "err", err.Error()) plog.Error("para commit msg read tick", "err", err.Error())
continue continue
} }
if len(status) == 0 {
continue
}
signTx, count, err := client.calcCommitMsgTxs(status) signTx, count, err := client.calcCommitMsgTxs(status)
if err != nil || signTx == nil { if err != nil || signTx == nil {
...@@ -426,9 +429,20 @@ func (client *commitMsgClient) getNodeStatus(start, end int64) ([]*pt.ParacrossN ...@@ -426,9 +429,20 @@ func (client *commitMsgClient) getNodeStatus(start, end int64) ([]*pt.ParacrossN
nodeList[block.Block.Height].StateHash = block.Block.StateHash nodeList[block.Block.Height].StateHash = block.Block.StateHash
} }
var needSentTxs uint32
for i := 0; i < int(count); i++ { for i := 0; i < int(count); i++ {
ret = append(ret, nodeList[req.Start+int64(i)]) ret = append(ret, nodeList[req.Start+int64(i)])
needSentTxs += nodeList[req.Start+int64(i)].NonCommitTxCounts
} }
//1.如果是只有commit tx的空块,推迟发送,直到等到一个完全没有commit tx的空块或者其他tx的块
//2,如果20个块都是 commit tx的空块,20个块打包一次发送,尽量减少commit tx造成的空块
//3,如果形如xxoxx的块排列,x代表commit空块,o代表实际的块,即只要不全部是commit块,也要全部打包一起发出去
//如果=0 意味着全部是paracross commit tx,延迟发送
if needSentTxs == 0 && count < types.TxGroupMaxCount {
plog.Debug("para commitmsg getNodeStatus all self consensus commit tx,send delay", "start", start, "end", end)
return nil, nil
}
return ret, nil return ret, nil
} }
......
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
\ No newline at end of file
#!/usr/bin/env bash
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
OUT_TESTDIR="${1}/dapptest/$strapp"
PARACLI="${OUT_DIR}/chain33-para-cli"
PARANAME=para
SRC_CLI=github.com/33cn/plugin/cli
go build -v -o "${PARACLI}" -ldflags "-X ${SRC_CLI}/buildflags.ParaName=user.p.${PARANAME}. -X ${SRC_CLI}/buildflags.RPCAddr=http://localhost:8901" "${SRC_CLI}"
# shellcheck disable=SC2086
cp ./build/* "${OUT_DIR}"
mkdir -p "${OUT_TESTDIR}"
cp ./build/* "${OUT_TESTDIR}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
set -e
set -o pipefail
MAIN_HTTP=""
CASE_ERR=""
GAME_ID=""
PASSWD="ABCD"
HASH_VALUE=$(echo -n "ABCD1" | sha256sum | awk '{print $1}')
signedTx=""
txHash=""
ACCOUNT_A="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
# PRIVA_A="cc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944"
ACCOUNT_B="19MJmA7GcE1NfMwdGqgLJioBjVbzQnVYvR"
PRIVA_B="5072a3b6ed612845a7c00b88b38e4564093f57ce652212d6e26da9fded83e951"
EXECTOR=""
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
function echo_rst() {
if [ "$2" -eq 0 ]; then
echo -e "${GRE}$1 ok${NOC}"
else
echo -e "${RED}$1 fail${NOC}"
CASE_ERR="FAIL"
fi
}
function chain33_GetExecAddr() {
#获取GAME合约地址
local exector=$1
local req='"method":"Chain33.ConvertExectoAddr","params":[{"execname":"'"${exector}"'"}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
# GAME_ADDR=$(echo "${res}" | jq -r ".result")
echo_rst "$FUNCNAME" "$?"
}
function CreateGameTx() {
local amount=$1
local hash_value=$2
local addr=$3
local req='"method":"Chain33.CreateTransaction","params":[{"execer":"'"${EXECTOR}"'", "actionName":"createGame", "payload":{"amount": '"${amount}"',"hashType":"sha256","hashValue":"'"${hash_value}"'"}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
rawTx=$(echo "${resp}" | jq -r ".result")
if [ "$rawTx" == "null" ]; then
echo_rst "CreateGame createRawTx" 1
fi
signRawTx "${rawTx}" "${ACCOUNT_A}"
echo_rst "CreateGame signRawTx" "$?"
sendSignedTx
echo_rst "CreateGame sendSignedTx" "$?"
GAME_ID="${txHash}"
# create_txHash="${txHash}"
query_tx "${txHash}"
echo_rst "CreateGame query_tx" "$?"
}
function MatchGameTx() {
local gameId=$1
local req='"method":"Chain33.CreateTransaction","params":[{"execer":"'"${EXECTOR}"'", "actionName":"matchGame", "payload":{"gameId": "'"${gameId}"'","guess":2}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
rawTx=$(echo "${resp}" | jq -r ".result")
if [ "$rawTx" == "null" ]; then
echo_rst "MatchGame createRawTx" 1
fi
signRawTx "${rawTx}" "${ACCOUNT_B}"
echo_rst "MatchGame signRawTx" "$?"
sendSignedTx
echo_rst "MatchGame sendSignedTx" "$?"
# match_txHash="${txHash}"
query_tx "${txHash}"
echo_rst "MatchGame query_tx" "$?"
}
function CloseGameTx() {
local gameId=$1
local secret=$2
local req='"method":"Chain33.CreateTransaction","params":[{"execer":"'"${EXECTOR}"'", "actionName":"closeGame", "payload":{"gameId": "'"${gameId}"'","secret":"'"${secret}"'","result":1}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
rawTx=$(echo "${resp}" | jq -r ".result")
if [ "$rawTx" == "null" ]; then
echo_rst "CloseGame createRawTx" 1
fi
signRawTx "${rawTx}" "${ACCOUNT_A}"
echo_rst "CloseGame signRawTx" "$?"
sendSignedTx
echo_rst "CloseGame sendSignedTx" "$?"
query_tx "${txHash}"
echo_rst "CloseGame query_tx" "$?"
}
function CancleGameTx() {
local gameId=$1
local req='"method":"Chain33.CreateTransaction","params":[{"execer":"'"${EXECTOR}"'", "actionName":"cancelGame", "payload":{"gameId": "'"${gameId}"'"}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
rawTx=$(echo "${resp}" | jq -r ".result")
if [ "$rawTx" == "null" ]; then
echo_rst "CancleGame createRawTx" 1
fi
signRawTx "${rawTx}" "${ACCOUNT_A}"
echo_rst "CancleGame signRawTx" "$?"
sendSignedTx
echo_rst "CancleGame sendSignedTx" "$?"
# close_txHash="${txHash}"
query_tx "${txHash}"
echo_rst "CancleGame query_tx" "$?"
}
function QueryGameByStatus() {
local status=$1
local req='"method":"Chain33.Query","params":[{"execer":"'"${EXECTOR}"'","funcName":"QueryGameListByStatusAndAddr","payload":{"status":'"${status}"',"address":""}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
GAMES=$(echo "${resp}" | jq -r ".result.games")
echo "${GAMES}"
echo_rst "$FUNCNAME" "$?"
}
function QueryGameByGameId() {
local gameId=$1
local status=$2
local req='"method":"Chain33.Query","params":[{"execer":"'"${EXECTOR}"'","funcName":"QueryGameById","payload":{"gameId":"'"${gameId}"'"}}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "${MAIN_HTTP}")
echo "#response: $resp"
STATUS=$(echo "${resp}" | jq -r ".result.game.status")
if [ "${STATUS}" -ne "${status}" ]; then
echo "status is not equal"
echo_rst "QueryGameByGameId" 1
return 0
fi
echo_rst "QueryGameByGameId" 0
}
function chain33_ImportPrivkey() {
local pri=$2
#local acc=$3
local req='"method":"Chain33.ImportPrivkey", "params":[{"privkey":"'"$pri"'", "label":"gameB"}]'
echo "#request: $req"
resp=$(curl -ksd "{$req}" "$1")
echo "#response: $resp"
# ok=$(jq '(.error|not) and (.result.label=="gameB") and (.result.acc.addr == "'"$acc"'")' <<<"$resp")
# [ "$ok" == true ]
# echo_rst "$FUNCNAME" "$?"
}
function Chain33_SendToAddress() {
from=$1
to=$2
amount=$3
http=$4
note="test"
resp=$(curl -ksd '{"jsonrpc":"2.0","id":2,"method":"Chain33.SendToAddress","params":[{"from":"'"$from"'","to":"'"$to"'","amount":'"$amount"',"note":"'"$note"'"}]}' -H 'content-type:text/plain;' "${http}")
ok=$(jq '(.error|not)' <<<"$resp")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
function chain33_unlock() {
ok=$(curl -k -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.UnLock","params":[{"passwd":"1314fuzamei","timeout":0}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result.isOK")
[ "$ok" == true ]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
function block_wait() {
local req='"method":"Chain33.GetLastHeader","params":[]'
cur_height=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd "{$req}" ${MAIN_HTTP} | jq ".result.height")
if [ "${new_height}" -ge "${expect}" ]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
function signRawTx() {
unsignedTx=$1
addr=$2
signedTx=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.SignRawTx","params":[{"addr":"'"${addr}"'","txHex":"'"${unsignedTx}"'","expire":"120s","fee":1000000}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "$signedTx" == "null" ]; then
return 1
else
return 0
fi
}
function sendSignedTx() {
txHash=$(curl -s --data-binary '{"jsonrpc":"2.0","id":2,"method":"Chain33.SendTransaction","params":[{"token":"","data":"'"${signedTx}"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result")
if [ "$txHash" == "null" ]; then
return 1
else
return 0
fi
}
function query_tx() {
block_wait 1
txhash="$1"
# echo "req=$req"
local times=10
while true; do
req='{"method":"Chain33.QueryTransaction","params":[{"hash":"'"$txhash"'"}]}'
ret=$(curl -ksd "$req" ${MAIN_HTTP})
tx=$(jq -r ".result.tx.hash" <<<"$ret")
echo "====query tx= ${1}, return=$ret "
if [ "${tx}" != "${1}" ]; then
block_wait 1
times=$((times - 1))
if [ $times -le 0 ]; then
echo "====query tx=$1 failed"
echo "req=$req"
curl -ksd "$req" ${MAIN_HTTP}
exit 1
fi
else
exec_err=$(jq '(.result.receipt.logs[0].tyName == "LogErr")' <<<"$ret")
[ "$exec_err" != true ]
echo "====query tx=$1 success"
break
fi
done
}
function init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
echo "ipara=$ispara"
from="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
chain33_ImportPrivkey "${MAIN_HTTP}" "${PRIVA_B}" "${ACCOUNT_B}"
local game_addr=""
if [ "$ispara" == "true" ]; then
#主链中相应账户需要转帐
M_HTTP=${MAIN_HTTP//8901/8801}
Chain33_SendToAddress "${ACCOUNT_A}" "${ACCOUNT_B}" 20000000000 "${M_HTTP}"
block_wait 1
EXECTOR="user.p.para.game"
game_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"user.p.para.game"}]}' ${MAIN_HTTP} | jq -r ".result")
else
EXECTOR="game"
game_addr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"game"}]}' ${MAIN_HTTP} | jq -r ".result")
fi
echo "gameAddr=${game_addr}"
Chain33_SendToAddress "${ACCOUNT_B}" "$game_addr" 5000000000 "${MAIN_HTTP}"
Chain33_SendToAddress "${ACCOUNT_A}" "$game_addr" 5000000000 "${MAIN_HTTP}"
block_wait 1
}
function run_test() {
local ip=$1
CreateGameTx 1000000000 "${HASH_VALUE}"
QueryGameByGameId "${GAME_ID}" 1
QueryGameByStatus 1
MatchGameTx "${GAME_ID}"
QueryGameByGameId "${GAME_ID}" 2
QueryGameByStatus 2
CloseGameTx "${GAME_ID}" "${PASSWD}"
QueryGameByGameId "${GAME_ID}" 4
QueryGameByStatus 4
CreateGameTx 500000000 "${HASH_VALUE}"
QueryGameByGameId "${GAME_ID}" 1
CancleGameTx "${GAME_ID}"
QueryGameByGameId "${GAME_ID}" 3
QueryGameByStatus 3
}
function main() {
local ip=$1
MAIN_HTTP=$ip
echo "=========== # game rpc test ============="
echo "main_ip=$MAIN_HTTP"
Chain33_SendToAddress "${ACCOUNT_A}" "${ACCOUNT_B}" 20000000000 "${MAIN_HTTP}"
block_wait 1
init
run_test "$MAIN_HTTP"
if [ -n "$CASE_ERR" ]; then
echo -e "${RED}=============game Rpc Test Fail=============${NOC}"
exit 1
else
echo -e "${GRE}=============game Rpc Test Pass==============${NOC}"
fi
}
main "$1"
all:
chmod +x ./build.sh
./build.sh $(OUT) $(FLAG)
\ No newline at end of file
#!/bin/sh
strpwd=$(pwd)
strcmd=${strpwd##*dapp/}
strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
OUT_TESTDIR="${1}/dapptest/$strapp"
mkdir -p "${OUT_TESTDIR}"
cp ./build/test-rpc.sh "${OUT_TESTDIR}"
#!/usr/bin/env bash
# shellcheck disable=SC2128
set -e
set -o pipefail
MAIN_HTTP=""
CASE_ERR=""
#color
RED='\033[1;31m'
GRE='\033[1;32m'
NOC='\033[0m'
# $2=0 means true, other false
echo_rst() {
if [[ $2 -eq 0 ]]; then
echo -e "${GRE}$1 ok${NOC}"
else
echo -e "${RED}$1 fail${NOC}"
CASE_ERR="err"
fi
}
lottery_addCreator_unsignedTx="0a066d616e616765123c0a3a0a0f6c6f74746572792d63726561746f721222313271796f6361794e46374c7636433971573461767873324537553431664b5366761a0361646420a08d0630c788b8f7ccbadbc0703a223151344e687572654a784b4e4266373164323642394a336642516f5163666d657a32"
lottery_addCreator_unsignedTx_para="0a12757365722e702e706172612e6d616e616765123c0a3a0a0f6c6f74746572792d63726561746f721222313271796f6361794e46374c7636433971573461767873324537553431664b5366761a0361646420a08d0630a8bba1b887e7dade2b3a22314469484633317577783977356a6a733571514269474a6b4e686e71656564763157"
lottery_creator_addr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
gID=""
gResp=""
glAddr=""
gameAddr1=""
gameAddr2=""
gameAddr3=""
lottExecAddr=""
purNum=30
drawNum=40
opRatio=5
devRatio=5
luckyNumber=""
init() {
ispara=$(echo '"'"${MAIN_HTTP}"'"' | jq '.|contains("8901")')
echo "ispara=$ispara"
if [[ $ispara == true ]]; then
lottExecAddr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"user.p.para.lottery"}]}' ${MAIN_HTTP} | jq -r ".result")
chain33_SendTransaction "${lottery_addCreator_unsignedTx_para}" "${lottery_creator_addr}"
else
lottExecAddr=$(curl -ksd '{"method":"Chain33.ConvertExectoAddr","params":[{"execname":"lottery"}]}' ${MAIN_HTTP} | jq -r ".result")
chain33_SendTransaction "${lottery_addCreator_unsignedTx}" "${lottery_creator_addr}"
fi
echo "lottExecAddr=$lottExecAddr"
}
chain33_NewAccount() {
label=$1
result=$(curl -ksd '{"method":"Chain33.NewAccount","params":[{"label":"'"$label"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP} | jq -r ".result.acc.addr")
[[ $result != "" ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
glAddr=$result
echo "$glAddr"
}
function block_wait() {
if [[ $# -lt 1 ]]; then
echo "wrong block_wait params"
exit 1
fi
http="$2"
if [[ ! $http ]]; then
http=${MAIN_HTTP}
fi
cur_height=$(curl -ksd '{"method":"Chain33.GetLastHeader","params":[{}]}' -H 'content-type:text/plain;' ${http} | jq -r ".result.height")
expect=$((cur_height + ${1}))
local count=0
while true; do
new_height=$(curl -ksd '{"method":"Chain33.GetLastHeader","params":[{}]}' -H 'content-type:text/plain;' ${http} | jq -r ".result.height")
if [[ ${new_height} -ge ${expect} ]]; then
break
fi
count=$((count + 1))
sleep 1
done
echo "wait new block $count s, cur height=$expect,old=$cur_height"
}
function query_tx() {
if [[ $# -lt 1 ]]; then
echo "wrong block_wait params"
exit 1
fi
http="$2"
if [[ ! $http ]]; then
http=${MAIN_HTTP}
fi
txhash="$1"
req='{"method":"Chain33.QueryTransaction","params":[{"hash":"'"$txhash"'"}]}'
local times=10
block_wait 1 ${http}
while true; do
ret=$(curl -ksd "$req" ${http})
tx=$(jq -r ".result.tx.hash" <<<"$ret")
if [[ ${tx} != "${1}" ]]; then
block_wait 1 ${http}
times=$((times - 1))
if [[ $times -le 0 ]]; then
echo_rst "query tx=$1" 1
exit 1
fi
else
exec_ok=$(jq '(.result.receipt.tyName == "ExecOk")' <<<"$ret")
[[ $exec_ok == true ]]
echo_rst "query tx=$1" $?
echo -e "######\\n response: $ret \\n######"
break
fi
done
}
chain33_SendToAddress() {
from=$1
to=$2
amount=$3
http=$4
note="test"
set -x
resp=$(curl -ksd '{"method":"Chain33.SendToAddress","params":[{"from":"'"$from"'","to":"'"$to"'","amount":'"$amount"',"note":"'"$note"'"}]}' -H 'content-type:text/plain;' "${http}")
ok=$(jq '(.error|not)' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#查询交易
txhash=$(jq -r ".result.hash" <<<"$resp")
query_tx "$txhash" "$http"
}
chain33_SendTransaction() {
rawTx=$1
addr=$2
#签名交易
resp=$(curl -ksd '{"method":"Chain33.SignRawTx","params":[{"addr":"'"$addr"'","txHex":"'"$rawTx"'","expire":"120s","fee":10000000,"index":0}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
[[ $ok == null ]]
rst=$?
echo_rst "chain33_SignRawTx" "$rst"
signTx=$(echo "${resp}" | jq -r ".result")
set -x
resp=$(curl -ksd '{"method":"Chain33.SendTransaction","params":[{"data":"'"$signTx"'"}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
set +x
[[ $ok == null ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#查询交易
gResp=$(jq -r ".result" <<<"$resp")
query_tx "$gResp"
}
lottery_LotteryCreate() {
#创建交易
addr=$1
set -x
resp=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"lottery","actionName":"LotteryCreate",
"payload":{"purBlockNum":'"$purNum"',"drawBlockNum":'"$drawNum"', "opRewardRatio":'"$opRatio"',"devRewardRatio":'"$devRatio"',"fee":1000000}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
set +x
[[ $ok == null ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#发送交易
rawTx=$(echo "${resp}" | jq -r ".result")
chain33_SendTransaction "${rawTx}" "${addr}"
gID="${gResp}"
echo "gameID $gID"
}
lottery_LotteryBuy() {
#创建交易
addr=$1
amount=$2
number=$3
way=$4
set -x
resp=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"lottery","actionName":"LotteryBuy",
"payload":{"lotteryId":"'"$gID"'","amount":'"$amount"',"number":'"$number"',"way":'"$way"',"fee":1000000}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
set +x
[[ $ok == null ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#发送交易
rawTx=$(echo "${resp}" | jq -r ".result")
chain33_SendTransaction "${rawTx}" "${addr}"
}
lottery_LotteryDraw() {
#创建交易
addr=$1
set -x
resp=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"lottery","actionName":"LotteryDraw",
"payload":{"lotteryId":"'"$gID"'","fee":1000000}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
set +x
[[ $ok == null ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#发送交易
rawTx=$(echo "${resp}" | jq -r ".result")
chain33_SendTransaction "${rawTx}" "${addr}"
}
lottery_LotteryClose() {
#创建交易
addr=$1
set -x
resp=$(curl -ksd '{"method":"Chain33.CreateTransaction","params":[{"execer":"lottery","actionName":"LotteryClose",
"payload":{"lotteryId":"'"$gID"'","fee":1000000}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(echo "${resp}" | jq -r ".error")
set +x
[[ $ok == null ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
#发送交易
rawTx=$(echo "${resp}" | jq -r ".result")
chain33_SendTransaction "${rawTx}" "${addr}"
}
lottery_GetLotteryNormalInfo() {
gameID=$1
addr=$2
execer="lottery"
funcName="GetLotteryNormalInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.purBlockNum == "'"$purNum"'") and (.result.drawBlockNum == "'"$drawNum"'") and (.result.createAddr == "'"$addr"'") and (.result.opRewardRatio == "'"$opRatio"'") and (.result.devRewardRatio == "'"$devRatio"'") and (.result | [has("createHeight"), true] | unique | length == 1)' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryCurrentInfo() {
gameID=$1
status=$2
amount=$3
execer="lottery"
funcName="GetLotteryCurrentInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.status == '"$status"') and (.result.buyAmount == "'"$amount"'") and (.result | [has("lastTransToPurState", "lastTransToDrawState", "totalPurchasedTxNum", "round", "luckyNumber", "lastTransToPurStateOnMain", "lastTransToDrawStateOnMain", "purBlockNum", "drawBlockNum", "missingRecords", "totalAddrNum"), true] | unique | length == 1)' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
if [[ $status == 3 ]]; then
luckyNumber=$(echo "${resp}" | jq -r ".result.luckyNumber")
echo -e "######\\n luckyNumber is $luckyNumber \\n######"
fi
}
lottery_GetLotteryPurchaseAddr() {
gameID=$1
count=$2
execer="lottery"
funcName="GetLotteryPurchaseAddr"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.address | length == '"$count"')' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryHistoryLuckyNumber() {
gameID=$1
count=$2
lucky=$3
execer="lottery"
funcName="GetLotteryHistoryLuckyNumber"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.records | length == '"$count"') and (.result.records[0].number == "'"$lucky"'")' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryRoundLuckyNumber() {
gameID=$1
round=$2
lucky=$3
execer="lottery"
funcName="GetLotteryRoundLuckyNumber"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'", "round":['"$round"']}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.records | length == 1) and (.result.records[0].number == "'"$lucky"'")' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryHistoryBuyInfo() {
gameID=$1
addr=$2
count=$3
number=$4
execer="lottery"
funcName="GetLotteryHistoryBuyInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'", "addr":"'"$addr"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.records | length == '"$count"') and (.result.records[0].number == "'"$number"'")' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryBuyRoundInfo() {
gameID=$1
addr=$2
round=$3
count=$4
number=$5
execer="lottery"
funcName="GetLotteryBuyRoundInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'", "addr":"'"$addr"'", "round":'"$round"'}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.records | length == '"$count"') and (.result.records[0].number == "'"$number"'")' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryHistoryGainInfo() {
gameID=$1
addr=$2
count=$3
amount=$4
execer="lottery"
funcName="GetLotteryHistoryGainInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'", "addr":"'"$addr"'"}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.records | length == '"$count"') and (.result.records[0].addr == "'"$addr"'") and (.result.records[0].buyAmount == "'"$amount"'")' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
lottery_GetLotteryRoundGainInfo() {
gameID=$1
addr=$2
round=$3
amount=$4
execer="lottery"
funcName="GetLotteryRoundGainInfo"
set -x
resp=$(curl -ksd '{"method":"Chain33.Query","params":[{"execer":"'"$execer"'","funcName":"'"$funcName"'","payload":{"lotteryId":"'"$gameID"'", "addr":"'"$addr"'", "round":'"$round"'}}]}' -H 'content-type:text/plain;' ${MAIN_HTTP})
ok=$(jq '(.error|not) and (.result.addr == "'"$addr"'") and (.result.round == "'"$round"'") and (.result.buyAmount == "'"$amount"'") and (.result | [has("fundAmount"), true] | unique | length == 1)' <<<"$resp")
set +x
[[ $ok == true ]]
rst=$?
echo_rst "$FUNCNAME" "$rst"
}
function run_testcases() {
#先创建账户地址
chain33_NewAccount "lottery111"
gameAddr1="${glAddr}"
chain33_NewAccount "lottery222"
gameAddr2="${glAddr}"
chain33_NewAccount "lottery333"
gameAddr3="${glAddr}"
#给每个账户分别转帐
origAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
#主链中相应账户需要转帐
M_HTTP=${MAIN_HTTP//8901/8801}
chain33_SendToAddress "${origAddr}" "${gameAddr1}" 300000000 "${M_HTTP}"
chain33_SendToAddress "${origAddr}" "${gameAddr2}" 300000000 "${M_HTTP}"
chain33_SendToAddress "${origAddr}" "${gameAddr3}" 300000000 "${M_HTTP}"
#平行链相应账户需要转帐
chain33_SendToAddress "${origAddr}" "${gameAddr1}" 300000000 "${MAIN_HTTP}"
chain33_SendToAddress "${origAddr}" "${gameAddr2}" 300000000 "${MAIN_HTTP}"
chain33_SendToAddress "${origAddr}" "${gameAddr3}" 300000000 "${MAIN_HTTP}"
#给游戏合约中转帐
chain33_SendToAddress "${gameAddr1}" "${lottExecAddr}" 200000000 "${MAIN_HTTP}"
chain33_SendToAddress "${gameAddr2}" "${lottExecAddr}" 200000000 "${MAIN_HTTP}"
chain33_SendToAddress "${gameAddr3}" "${lottExecAddr}" 200000000 "${MAIN_HTTP}"
#创建游戏
lottery_LotteryCreate "${lottery_creator_addr}"
lottery_GetLotteryNormalInfo "$gID" "${lottery_creator_addr}"
lottery_GetLotteryCurrentInfo "$gID" 1 0
#第一次投注
lottery_LotteryBuy "${gameAddr1}" 1 12345 1
lottery_LotteryBuy "${gameAddr2}" 1 66666 2
lottery_LotteryBuy "${gameAddr3}" 1 56789 5
#查询
lottery_GetLotteryCurrentInfo "$gID" 2 3
lottery_GetLotteryPurchaseAddr "$gID" 3
lottery_GetLotteryHistoryBuyInfo "$gID" "${gameAddr1}" 1 "12345"
lottery_GetLotteryBuyRoundInfo "$gID" "${gameAddr2}" 1 1 "66666"
#第二次投注
lottery_LotteryBuy "${gameAddr1}" 1 12321 1
lottery_LotteryBuy "${gameAddr3}" 1 78987 5
#查询
lottery_GetLotteryCurrentInfo "$gID" 2 5
lottery_GetLotteryPurchaseAddr "$gID" 3
lottery_GetLotteryHistoryBuyInfo "$gID" "${gameAddr1}" 2 "12321"
lottery_GetLotteryBuyRoundInfo "$gID" "${gameAddr3}" 1 2 "78987"
#游戏开奖
block_wait ${drawNum} "${M_HTTP}"
lottery_LotteryDraw "${lottery_creator_addr}"
lottery_GetLotteryCurrentInfo "$gID" 3 0
#游戏查询
lottery_GetLotteryHistoryLuckyNumber "$gID" 1 "${luckyNumber}"
lottery_GetLotteryRoundLuckyNumber "$gID" 1 "${luckyNumber}"
lottery_GetLotteryHistoryGainInfo "$gID" "${gameAddr1}" 1 2
lottery_GetLotteryHistoryGainInfo "$gID" "${gameAddr2}" 1 1
lottery_GetLotteryRoundGainInfo "$gID" "${gameAddr1}" 1 2
lottery_GetLotteryRoundGainInfo "$gID" "${gameAddr3}" 1 2
#关闭游戏
lottery_LotteryClose "${lottery_creator_addr}"
lottery_GetLotteryCurrentInfo "$gID" 4 0
}
function main() {
MAIN_HTTP="$1"
echo "main_ip=$MAIN_HTTP"
echo "=========== # lottery rpc test start============="
init
run_testcases
if [[ -n $CASE_ERR ]]; then
echo -e "${RED}=============Lottery Rpc Test Fail=============${NOC}"
exit 1
else
echo -e "${GRE}=============Lottery Rpc Test Pass==============${NOC}"
fi
echo "=========== # lottery rpc test end============="
}
main "$1"
...@@ -154,6 +154,7 @@ tokenApprs = [ ...@@ -154,6 +154,7 @@ tokenApprs = [
] ]
[exec.sub.paracross] [exec.sub.paracross]
#平行链自共识停止n个块后,超级账户可以直接参与投票
paraConsensusStopBlocks=100 paraConsensusStopBlocks=100
[pprof] [pprof]
......
...@@ -415,7 +415,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error ...@@ -415,7 +415,7 @@ func (a *action) Commit(commit *pt.ParacrossCommitAction) (*types.Receipt, error
saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus) saveTitle(a.db, calcTitleKey(commit.Status.Title), titleStatus)
clog.Info("paracross.Commit commit done", "height", commit.Status.Height, clog.Info("paracross.Commit commit done", "height", commit.Status.Height,
"cross tx bitmap", hex.EncodeToString(commit.Status.CrossTxResult), "statusBlockHash", hex.EncodeToString(titleStatus.BlockHash)) "cross tx bitmap", string(commit.Status.CrossTxResult), "statusBlockHash", hex.EncodeToString(titleStatus.BlockHash))
//parallel chain not need to process cross commit tx here //parallel chain not need to process cross commit tx here
if types.IsPara() { if types.IsPara() {
...@@ -491,7 +491,13 @@ func getCrossTxHashs(api client.QueueProtocolAPI, commit *pt.ParacrossCommitActi ...@@ -491,7 +491,13 @@ func getCrossTxHashs(api client.QueueProtocolAPI, commit *pt.ParacrossCommitActi
//只获取跨链tx //只获取跨链tx
crossTxHashs = paraCrossHashs crossTxHashs = paraCrossHashs
crossTxResult = commit.Status.CrossTxResult rst, err := hex.DecodeString(string(commit.Status.CrossTxResult))
if err != nil {
clog.Error("getCrossTxHashs decode string", "CrossTxResult", string(commit.Status.CrossTxResult),
"commit.height", commit.Status.Height)
return nil, nil, types.ErrInvalidParam
}
crossTxResult = rst
} }
return crossTxHashs, crossTxResult, nil return crossTxHashs, crossTxResult, nil
} }
......
...@@ -7,6 +7,8 @@ package executor ...@@ -7,6 +7,8 @@ package executor
import ( import (
"bytes" "bytes"
"encoding/hex"
"github.com/33cn/chain33/common" "github.com/33cn/chain33/common"
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util" "github.com/33cn/chain33/util"
...@@ -164,23 +166,44 @@ func setMinerTxResult(payload *pt.ParacrossMinerAction, txs []*types.Transaction ...@@ -164,23 +166,44 @@ func setMinerTxResult(payload *pt.ParacrossMinerAction, txs []*types.Transaction
return nil return nil
} }
func setMinerTxResultFork(payload *pt.ParacrossMinerAction, txs []*types.Transaction, receipts []*types.ReceiptData) { func setMinerTxResultFork(status *pt.ParacrossNodeStatus, txs []*types.Transaction, receipts []*types.ReceiptData) error {
isCommitTx := make(map[string]bool)
var curTxHashs [][]byte var curTxHashs [][]byte
for _, tx := range txs { for _, tx := range txs {
hash := tx.Hash() hash := tx.Hash()
curTxHashs = append(curTxHashs, hash) curTxHashs = append(curTxHashs, hash)
if types.IsMyParaExecName(string(tx.Execer)) && bytes.HasSuffix(tx.Execer, []byte(pt.ParaX)) {
var payload pt.ParacrossAction
err := types.Decode(tx.Payload, &payload)
if err != nil {
clog.Error("setMinerTxResultFork", "txHash", common.ToHex(hash))
return err
}
if payload.Ty == pt.ParacrossActionCommit {
isCommitTx[string(hash)] = true
}
}
} }
baseCrossTxHashs := FilterParaCrossTxHashes(types.GetTitle(), txs) status.TxCounts = uint32(len(curTxHashs))
//有tx且全部是user.p.x.paracross的commit tx时候设为0
status.NonCommitTxCounts = 1
if len(curTxHashs) != 0 && len(curTxHashs) == len(isCommitTx) {
status.NonCommitTxCounts = 0
}
crossTxHashs := FilterParaCrossTxHashes(types.GetTitle(), txs)
//主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map //主链自己过滤平行链tx, 对平行链执行失败的tx主链无法识别,主链和平行链需要获取相同的最初的tx map
//全部平行链tx结果 //全部平行链tx结果
payload.Status.TxResult = util.CalcBitMap(curTxHashs, curTxHashs, receipts) status.TxResult = []byte(hex.EncodeToString(util.CalcBitMap(curTxHashs, curTxHashs, receipts)))
//跨链tx结果 //跨链tx结果
payload.Status.CrossTxResult = util.CalcBitMap(baseCrossTxHashs, curTxHashs, receipts) status.CrossTxResult = []byte(hex.EncodeToString(util.CalcBitMap(crossTxHashs, curTxHashs, receipts)))
status.TxHashs = [][]byte{CalcTxHashsHash(curTxHashs)}
status.CrossTxHashs = [][]byte{CalcTxHashsHash(crossTxHashs)}
payload.Status.TxHashs = [][]byte{CalcTxHashsHash(curTxHashs)} return nil
payload.Status.CrossTxHashs = [][]byte{CalcTxHashsHash(baseCrossTxHashs)}
} }
//ExecLocal_Miner miner tx local db process //ExecLocal_Miner miner tx local db process
...@@ -196,7 +219,10 @@ func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types. ...@@ -196,7 +219,10 @@ func (e *Paracross) ExecLocal_Miner(payload *pt.ParacrossMinerAction, tx *types.
//removed the 0 vote tx //removed the 0 vote tx
if payload.Status.MainBlockHeight >= forkHeight { if payload.Status.MainBlockHeight >= forkHeight {
setMinerTxResultFork(payload, txs[1:], e.GetReceipt()[1:]) err := setMinerTxResultFork(payload.Status, txs[1:], e.GetReceipt()[1:])
if err != nil {
return nil, err
}
} else { } else {
err := setMinerTxResult(payload, txs[1:], e.GetReceipt()[1:]) err := setMinerTxResult(payload, txs[1:], e.GetReceipt()[1:])
if err != nil { if err != nil {
......
...@@ -620,8 +620,8 @@ func (s *VoteTestSuite) TestVoteTxFork() { ...@@ -620,8 +620,8 @@ func (s *VoteTestSuite) TestVoteTxFork() {
if bytes.Equal(key, kv.Key) { if bytes.Equal(key, kv.Key) {
var rst pt.ParacrossNodeStatus var rst pt.ParacrossNodeStatus
types.Decode(kv.GetValue(), &rst) types.Decode(kv.GetValue(), &rst)
s.Equal([]uint8([]byte{0x8e}), rst.TxResult) s.Equal([]byte("8e"), rst.TxResult)
s.Equal([]uint8([]byte{0x22}), rst.CrossTxResult) s.Equal([]byte("22"), rst.CrossTxResult)
s.Equal(1, len(rst.TxHashs)) s.Equal(1, len(rst.TxHashs))
s.Equal(1, len(rst.CrossTxHashs)) s.Equal(1, len(rst.CrossTxHashs))
......
...@@ -151,6 +151,7 @@ message ParacrossNodeStatus { ...@@ -151,6 +151,7 @@ message ParacrossNodeStatus {
repeated bytes txHashs = 11; repeated bytes txHashs = 11;
bytes crossTxResult = 12; bytes crossTxResult = 12;
repeated bytes crossTxHashs = 13; repeated bytes crossTxHashs = 13;
uint32 nonCommitTxCounts = 14;
} }
message ParacrossCommitAction { message ParacrossCommitAction {
......
...@@ -1136,6 +1136,7 @@ type ParacrossNodeStatus struct { ...@@ -1136,6 +1136,7 @@ type ParacrossNodeStatus struct {
TxHashs [][]byte `protobuf:"bytes,11,rep,name=txHashs,proto3" json:"txHashs,omitempty"` TxHashs [][]byte `protobuf:"bytes,11,rep,name=txHashs,proto3" json:"txHashs,omitempty"`
CrossTxResult []byte `protobuf:"bytes,12,opt,name=crossTxResult,proto3" json:"crossTxResult,omitempty"` CrossTxResult []byte `protobuf:"bytes,12,opt,name=crossTxResult,proto3" json:"crossTxResult,omitempty"`
CrossTxHashs [][]byte `protobuf:"bytes,13,rep,name=crossTxHashs,proto3" json:"crossTxHashs,omitempty"` CrossTxHashs [][]byte `protobuf:"bytes,13,rep,name=crossTxHashs,proto3" json:"crossTxHashs,omitempty"`
NonCommitTxCounts uint32 `protobuf:"varint,14,opt,name=nonCommitTxCounts,proto3" json:"nonCommitTxCounts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
...@@ -1257,6 +1258,13 @@ func (m *ParacrossNodeStatus) GetCrossTxHashs() [][]byte { ...@@ -1257,6 +1258,13 @@ func (m *ParacrossNodeStatus) GetCrossTxHashs() [][]byte {
return nil return nil
} }
func (m *ParacrossNodeStatus) GetNonCommitTxCounts() uint32 {
if m != nil {
return m.NonCommitTxCounts
}
return 0
}
type ParacrossCommitAction struct { type ParacrossCommitAction struct {
Status *ParacrossNodeStatus `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` Status *ParacrossNodeStatus `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
...@@ -2404,111 +2412,112 @@ func init() { ...@@ -2404,111 +2412,112 @@ func init() {
func init() { proto.RegisterFile("paracross.proto", fileDescriptor_6a397e38c9ea6747) } func init() { proto.RegisterFile("paracross.proto", fileDescriptor_6a397e38c9ea6747) }
var fileDescriptor_6a397e38c9ea6747 = []byte{ var fileDescriptor_6a397e38c9ea6747 = []byte{
// 1658 bytes of a gzipped FileDescriptorProto // 1679 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x18, 0xdb, 0x6e, 0x1b, 0xc7, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x58, 0xcd, 0x6e, 0x1b, 0x47,
0x95, 0xcb, 0xab, 0x78, 0x74, 0x1f, 0x5b, 0x32, 0xcd, 0xba, 0x2e, 0xb1, 0x70, 0x0b, 0xa1, 0x68, 0x12, 0xe6, 0xf0, 0x57, 0x2c, 0x49, 0x94, 0xd4, 0xb6, 0x64, 0x9a, 0xeb, 0xf5, 0x12, 0x03, 0xef,
0x65, 0x57, 0x2a, 0x5c, 0x14, 0x46, 0xd1, 0xca, 0xb2, 0x2d, 0x0a, 0xbe, 0xa0, 0x58, 0xa9, 0x97, 0x42, 0x58, 0x78, 0x65, 0xaf, 0xb4, 0xf0, 0x62, 0x61, 0x2c, 0x76, 0x65, 0xd9, 0x16, 0x05, 0xff,
0x97, 0x00, 0x59, 0x93, 0x23, 0x69, 0x11, 0x72, 0x77, 0xbd, 0x33, 0xb4, 0xa5, 0xbc, 0x05, 0x48, 0x20, 0x18, 0x29, 0x3f, 0x97, 0x00, 0x19, 0x0f, 0x5b, 0xd2, 0x20, 0xe4, 0xf4, 0x78, 0xba, 0x69,
0xf2, 0x23, 0xc9, 0x73, 0x5e, 0x02, 0xe4, 0x39, 0xc8, 0x63, 0xf2, 0x90, 0x8f, 0xc8, 0x07, 0xe4, 0x4b, 0xb9, 0x05, 0x48, 0xf2, 0x22, 0xc9, 0x39, 0xc7, 0x9c, 0x83, 0x1c, 0x93, 0x43, 0x9e, 0x21,
0x17, 0x82, 0x73, 0x66, 0x76, 0x76, 0x66, 0x49, 0x31, 0x8e, 0x10, 0x20, 0xc8, 0x1b, 0xcf, 0x99, 0xc8, 0x03, 0xe4, 0x15, 0x82, 0xae, 0xee, 0xe9, 0xe9, 0x1e, 0x52, 0x8c, 0x23, 0x04, 0x08, 0x72,
0x73, 0xbf, 0x73, 0x61, 0x35, 0x0d, 0xb3, 0x70, 0x90, 0x25, 0x42, 0x6c, 0xa7, 0x59, 0x22, 0x13, 0x63, 0x55, 0x57, 0xd7, 0xef, 0x57, 0x5d, 0xc5, 0x81, 0x95, 0x34, 0xcc, 0xc2, 0x28, 0x63, 0x9c,
0xd6, 0x90, 0x17, 0x29, 0x17, 0xdd, 0x75, 0x99, 0x85, 0xb1, 0x08, 0x07, 0x32, 0x4a, 0x62, 0xf5, 0x6f, 0xa5, 0x19, 0x13, 0x8c, 0x34, 0xc4, 0x79, 0x4a, 0x79, 0x6f, 0x4d, 0x64, 0x61, 0xc2, 0xc3,
0xd2, 0x5d, 0x1a, 0x24, 0xe3, 0xb1, 0x81, 0xd6, 0x5e, 0x8e, 0x92, 0xc1, 0x7b, 0x83, 0xb3, 0x30, 0x48, 0xc4, 0x2c, 0x51, 0x27, 0xbd, 0xa5, 0x88, 0x8d, 0xc7, 0x86, 0x5a, 0x7d, 0x31, 0x62, 0xd1,
0xca, 0x31, 0x2b, 0xfc, 0x9c, 0x0f, 0x26, 0x32, 0xc9, 0x14, 0xec, 0x3f, 0x83, 0xcd, 0x7f, 0xe7, 0x87, 0xd1, 0x69, 0x18, 0xe7, 0x9c, 0x0e, 0x3d, 0xa3, 0xd1, 0x44, 0xb0, 0x4c, 0xd1, 0xfe, 0x53,
0xc2, 0x8f, 0x64, 0x28, 0x27, 0xe2, 0x11, 0x97, 0x61, 0x34, 0x12, 0xec, 0x3a, 0x34, 0xc2, 0xe1, 0xd8, 0x78, 0x2b, 0x57, 0x7e, 0x28, 0x42, 0x31, 0xe1, 0x0f, 0xa9, 0x08, 0xe3, 0x11, 0x27, 0x57,
0x30, 0x13, 0x1d, 0xaf, 0x57, 0xdb, 0x6a, 0x07, 0x0a, 0x60, 0xb7, 0xa0, 0x4d, 0x32, 0xfb, 0xa1, 0xa1, 0x11, 0x0e, 0x87, 0x19, 0xef, 0x7a, 0xfd, 0xda, 0x66, 0x3b, 0x50, 0x04, 0xb9, 0x01, 0x6d,
0x38, 0xeb, 0x54, 0x7b, 0xb5, 0xad, 0xa5, 0xa0, 0x40, 0xf8, 0x5f, 0x78, 0xb0, 0x61, 0xc4, 0xf5, 0xd4, 0x39, 0x08, 0xf9, 0x69, 0xb7, 0xda, 0xaf, 0x6d, 0x2e, 0x05, 0x05, 0xc3, 0xff, 0xca, 0x83,
0x79, 0x74, 0x7a, 0x26, 0x95, 0x50, 0xb6, 0x09, 0x4d, 0x41, 0xbf, 0x3a, 0x5e, 0xcf, 0xdb, 0x6a, 0x75, 0xa3, 0x6e, 0x40, 0xe3, 0x93, 0x53, 0xa1, 0x94, 0x92, 0x0d, 0x68, 0x72, 0xfc, 0xd5, 0xf5,
0x04, 0x1a, 0x42, 0x2d, 0x32, 0x92, 0x23, 0xde, 0xa9, 0xf6, 0x3c, 0xd4, 0x42, 0x00, 0x52, 0x9f, 0xfa, 0xde, 0x66, 0x23, 0xd0, 0x94, 0xb4, 0x22, 0x62, 0x31, 0xa2, 0xdd, 0x6a, 0xdf, 0x93, 0x56,
0x11, 0x77, 0xa7, 0xd6, 0xf3, 0xb6, 0x6a, 0x81, 0x86, 0xd8, 0xdf, 0xa0, 0x35, 0x54, 0xe6, 0x75, 0x90, 0x90, 0xd2, 0xa7, 0x78, 0xbb, 0x5b, 0xeb, 0x7b, 0x9b, 0xb5, 0x40, 0x53, 0xe4, 0xdf, 0xd0,
0xea, 0x3d, 0x6f, 0x6b, 0x71, 0xe7, 0xb7, 0xdb, 0x14, 0x89, 0xed, 0xd9, 0x3e, 0x04, 0x39, 0x35, 0x1a, 0x2a, 0xf7, 0xba, 0xf5, 0xbe, 0xb7, 0xb9, 0xb8, 0xfd, 0xe7, 0x2d, 0xcc, 0xc4, 0xd6, 0xec,
0xbb, 0x0d, 0x30, 0x0e, 0xa3, 0x58, 0x99, 0xd4, 0x69, 0x90, 0x50, 0x0b, 0xe3, 0xbf, 0x03, 0xab, 0x18, 0x82, 0x5c, 0x9a, 0xdc, 0x04, 0x18, 0x87, 0x71, 0xa2, 0x5c, 0xea, 0x36, 0x50, 0xa9, 0xc5,
0x25, 0x11, 0x85, 0x65, 0xde, 0x6c, 0xcb, 0xaa, 0x8e, 0x65, 0x4e, 0x5c, 0xd0, 0x68, 0x27, 0x2e, 0xf1, 0xdf, 0x87, 0x95, 0x92, 0x8a, 0xc2, 0x33, 0x6f, 0xb6, 0x67, 0x55, 0xc7, 0x33, 0x27, 0x2f,
0x9f, 0x7a, 0xd0, 0x31, 0xf2, 0xf7, 0x93, 0x58, 0xf0, 0x58, 0x4c, 0xe6, 0x2b, 0xea, 0xc1, 0x22, 0xd2, 0x69, 0x27, 0x2f, 0x5f, 0x78, 0xd0, 0x35, 0xfa, 0xf7, 0x58, 0xc2, 0x69, 0xc2, 0x27, 0xf3,
0xe5, 0xad, 0x6f, 0x6b, 0xb3, 0x51, 0xec, 0x0e, 0x2c, 0x0f, 0x94, 0xa8, 0xbe, 0x1d, 0x2b, 0x17, 0x0d, 0xf5, 0x61, 0x11, 0xeb, 0x36, 0xb0, 0xad, 0xd9, 0x2c, 0x72, 0x0b, 0x96, 0x23, 0xa5, 0x6a,
0xc9, 0xfe, 0x08, 0x6b, 0x1a, 0xf1, 0xd0, 0xd8, 0x57, 0x27, 0x45, 0x53, 0x78, 0xff, 0x63, 0x0f, 0x60, 0xe7, 0xca, 0x65, 0x92, 0xbf, 0xc3, 0xaa, 0x66, 0x3c, 0x30, 0xfe, 0xd5, 0xd1, 0xd0, 0x14,
0x18, 0x9a, 0xf9, 0x22, 0x19, 0xf2, 0xbd, 0xe1, 0x30, 0xdb, 0x4f, 0xe2, 0x93, 0xe8, 0xf4, 0x12, 0xdf, 0xff, 0xcc, 0x03, 0x22, 0xdd, 0x7c, 0xce, 0x86, 0x74, 0x77, 0x38, 0xcc, 0xf6, 0x58, 0x72,
0x03, 0x57, 0xa0, 0x9a, 0xa4, 0x3a, 0x6d, 0xd5, 0x24, 0x65, 0x0c, 0xea, 0x58, 0x22, 0x64, 0x45, 0x1c, 0x9f, 0x5c, 0xe0, 0x60, 0x07, 0xaa, 0x2c, 0xd5, 0x65, 0xab, 0xb2, 0x94, 0x10, 0xa8, 0x4b,
0x3b, 0xa0, 0xdf, 0xc8, 0xf9, 0x3a, 0x1c, 0x4d, 0xb8, 0xd6, 0xa8, 0x00, 0x72, 0x2d, 0x89, 0x62, 0x88, 0xa0, 0x17, 0xed, 0x00, 0x7f, 0xcb, 0x9b, 0xaf, 0xc2, 0xd1, 0x84, 0x6a, 0x8b, 0x8a, 0xc0,
0xf1, 0x24, 0x4b, 0xde, 0xe7, 0xb1, 0xce, 0x86, 0x8d, 0xf2, 0xff, 0x55, 0xd8, 0xf1, 0xdf, 0x44, 0xd0, 0x58, 0x9c, 0xf0, 0xc7, 0x19, 0xfb, 0x88, 0x26, 0xba, 0x1a, 0x36, 0xcb, 0xff, 0x7f, 0xe1,
0x72, 0x95, 0xce, 0x4b, 0x2a, 0x12, 0x75, 0x24, 0x92, 0x0b, 0xaa, 0x46, 0xd4, 0x81, 0x80, 0xff, 0xc7, 0x3b, 0x4c, 0x50, 0x55, 0xce, 0x0b, 0x10, 0x29, 0x6d, 0x30, 0x41, 0x39, 0xa2, 0x51, 0xda,
0x6d, 0xc9, 0x95, 0x2b, 0x95, 0xe1, 0x2d, 0x68, 0x87, 0x69, 0x3a, 0xba, 0xd8, 0x2b, 0xfc, 0x2a, 0x90, 0x84, 0xff, 0x7d, 0x29, 0x94, 0x4b, 0xc1, 0xf0, 0x06, 0xb4, 0xc3, 0x34, 0x1d, 0x9d, 0xef,
0x10, 0x65, 0x37, 0xea, 0x53, 0x6e, 0xb0, 0xbb, 0xb9, 0x69, 0x0d, 0x2a, 0xd6, 0x9b, 0x56, 0xb1, 0x16, 0x71, 0x15, 0x8c, 0x72, 0x18, 0xf5, 0xa9, 0x30, 0xc8, 0x9d, 0xdc, 0xb5, 0x06, 0x82, 0xf5,
0xba, 0xae, 0x69, 0xab, 0x59, 0x17, 0x16, 0x4e, 0xb2, 0x64, 0x4c, 0xfa, 0x9a, 0xa4, 0xcf, 0xc0, 0xba, 0x05, 0x56, 0x37, 0x34, 0xed, 0x35, 0xe9, 0xc1, 0xc2, 0x71, 0xc6, 0xc6, 0x68, 0xaf, 0x89,
0xfe, 0x57, 0x1e, 0x6c, 0x04, 0x7c, 0xc0, 0xa3, 0x54, 0xe6, 0x02, 0x74, 0x7e, 0xf2, 0xc8, 0x7b, 0xf6, 0x0c, 0xed, 0x7f, 0xe3, 0xc1, 0x7a, 0x40, 0x23, 0x1a, 0xa7, 0x22, 0x57, 0xa0, 0xeb, 0x93,
0x56, 0xe4, 0xff, 0x02, 0xcd, 0x01, 0xbd, 0x92, 0x47, 0xd3, 0xba, 0x8b, 0xf4, 0x06, 0x9a, 0x90, 0x67, 0xde, 0xb3, 0x32, 0xff, 0x4f, 0x68, 0x46, 0x78, 0x8a, 0x11, 0x4d, 0xdb, 0x2e, 0xca, 0x1b,
0xfd, 0x19, 0xea, 0x69, 0xc6, 0x5f, 0x93, 0xa3, 0xb3, 0x19, 0x54, 0x10, 0x03, 0x22, 0x63, 0xbb, 0x68, 0x41, 0xf2, 0x0f, 0xa8, 0xa7, 0x19, 0x7d, 0x85, 0x81, 0xce, 0xbe, 0xa0, 0x92, 0x18, 0xa0,
0xd0, 0x1a, 0x4c, 0xb2, 0x8c, 0xc7, 0x52, 0xf7, 0xe2, 0x1c, 0x8e, 0x9c, 0xd2, 0x8f, 0xe0, 0x66, 0x18, 0xd9, 0x81, 0x56, 0x34, 0xc9, 0x32, 0x9a, 0x08, 0xdd, 0x8b, 0x73, 0x6e, 0xe4, 0x92, 0x7e,
0xc9, 0x07, 0x0c, 0x42, 0xc0, 0x07, 0x49, 0x36, 0x74, 0xbc, 0xf7, 0x5c, 0xef, 0xf1, 0x0d, 0x43, 0x0c, 0xd7, 0x4b, 0x31, 0xc8, 0x24, 0x04, 0x34, 0x62, 0xd9, 0xd0, 0x89, 0xde, 0x73, 0xa3, 0x97,
0x44, 0x6f, 0x2a, 0x47, 0x06, 0x2e, 0xaa, 0xac, 0x46, 0x39, 0x55, 0x80, 0xff, 0x9d, 0x07, 0x37, 0x67, 0x32, 0x45, 0x78, 0xa6, 0x6a, 0x64, 0xe8, 0x02, 0x65, 0x35, 0xac, 0xa9, 0x22, 0xfc, 0x1f,
0x66, 0xe8, 0x7a, 0x94, 0xc4, 0xfc, 0x92, 0x8a, 0xbe, 0x0d, 0x20, 0xc3, 0xec, 0x94, 0x4b, 0x4b, 0x3d, 0xb8, 0x36, 0xc3, 0xd6, 0x43, 0x96, 0xd0, 0x0b, 0x10, 0x7d, 0x13, 0x40, 0x84, 0xd9, 0x09,
0x8b, 0x85, 0xa1, 0xf7, 0x44, 0x86, 0x23, 0x14, 0x25, 0xb4, 0x32, 0x0b, 0x83, 0xe5, 0x42, 0x10, 0x15, 0x96, 0x15, 0x8b, 0x83, 0xe7, 0x4c, 0x84, 0x23, 0xa9, 0x8a, 0x6b, 0x63, 0x16, 0x47, 0xc2,
0xaa, 0xa1, 0x98, 0x34, 0x82, 0x02, 0x81, 0x1e, 0x8c, 0x13, 0x21, 0xe9, 0xb1, 0x41, 0x8f, 0x06, 0x05, 0x29, 0x69, 0x06, 0x73, 0xd2, 0x08, 0x0a, 0x86, 0x8c, 0x60, 0xcc, 0xb8, 0xc0, 0xc3, 0x06,
0x66, 0x1d, 0x68, 0xa1, 0x37, 0x81, 0x90, 0x3a, 0xed, 0x39, 0x88, 0x3a, 0x87, 0x49, 0xcc, 0x55, 0x1e, 0x1a, 0x9a, 0x74, 0xa1, 0x25, 0xa3, 0x09, 0xb8, 0xd0, 0x65, 0xcf, 0x49, 0x69, 0x73, 0xc8,
0x1c, 0x3b, 0x2d, 0xa5, 0xb3, 0xc0, 0xf8, 0x9f, 0x78, 0x70, 0x2d, 0x77, 0xef, 0x20, 0x4b, 0x26, 0x12, 0xaa, 0xf2, 0xd8, 0x6d, 0x29, 0x9b, 0x05, 0xc7, 0xff, 0xdc, 0x83, 0x2b, 0x79, 0x78, 0xfb,
0xe9, 0x5b, 0xf6, 0xec, 0x32, 0xf5, 0xac, 0xe9, 0x28, 0x55, 0xdc, 0xba, 0xa3, 0x7e, 0xbc, 0xb0, 0x19, 0x9b, 0xa4, 0x6f, 0xd8, 0xb3, 0xcb, 0xd8, 0xb3, 0xa6, 0xa3, 0x14, 0xb8, 0x75, 0x47, 0xfd,
0xb7, 0x81, 0xf1, 0x71, 0x2a, 0x2f, 0x68, 0x74, 0x1c, 0xc6, 0x92, 0x67, 0xaf, 0xc3, 0x11, 0x79, 0x32, 0xb0, 0xb7, 0x80, 0xd0, 0x71, 0x2a, 0xce, 0xf1, 0xe9, 0x38, 0x48, 0x04, 0xcd, 0x5e, 0x85,
0xb5, 0x1c, 0xcc, 0x78, 0xf1, 0xbf, 0x2f, 0x5b, 0xf9, 0x8b, 0xb4, 0xe3, 0x4f, 0xb4, 0xba, 0xb4, 0x23, 0x8c, 0x6a, 0x39, 0x98, 0x71, 0xe2, 0xff, 0x54, 0xf6, 0xf2, 0x77, 0x69, 0xc7, 0x5f, 0xe9,
0x34, 0x9a, 0xe5, 0xa5, 0xe1, 0xd4, 0x6b, 0xab, 0xd4, 0xad, 0x5f, 0x7b, 0xd0, 0x2d, 0x55, 0x9f, 0x75, 0x69, 0x68, 0x34, 0xcb, 0x43, 0xc3, 0xc1, 0x6b, 0xab, 0xd4, 0xad, 0xdf, 0x7a, 0xd0, 0x2b,
0x9d, 0x9e, 0x59, 0x2d, 0xbb, 0x53, 0x6a, 0xd9, 0x6e, 0xa9, 0x9f, 0x2c, 0x7e, 0xd3, 0xb3, 0xdb, 0xa1, 0xcf, 0x2e, 0xcf, 0xac, 0x96, 0xdd, 0x2e, 0xb5, 0x6c, 0xaf, 0xd4, 0x4f, 0xd6, 0x7d, 0xd3,
0x4e, 0xcf, 0xce, 0xe4, 0x70, 0x9a, 0xf6, 0xaf, 0xe5, 0xa6, 0x9d, 0xc7, 0x62, 0xba, 0xf6, 0xff, 0xb3, 0x5b, 0x4e, 0xcf, 0xce, 0xbc, 0xe1, 0x34, 0xed, 0xbf, 0xca, 0x4d, 0x3b, 0xef, 0x8a, 0xe9,
0x70, 0x3d, 0xe0, 0xaf, 0xcc, 0x02, 0x43, 0xba, 0xc3, 0xf8, 0x24, 0xb9, 0xa4, 0xc8, 0x72, 0xdf, 0xda, 0xf7, 0xe0, 0x6a, 0x40, 0x5f, 0x9a, 0x01, 0x26, 0xe5, 0x0e, 0x92, 0x63, 0x76, 0x01, 0xc8,
0xaa, 0x96, 0x6f, 0x45, 0xa2, 0x6b, 0x76, 0xa2, 0xfd, 0x43, 0xd8, 0x0c, 0xb8, 0x48, 0x1d, 0xd1, 0xf2, 0xd8, 0xaa, 0x56, 0x6c, 0x45, 0xa1, 0x6b, 0x76, 0xa1, 0xfd, 0x03, 0xd8, 0x08, 0x28, 0x4f,
0x7b, 0x54, 0x84, 0x77, 0xed, 0x61, 0x3f, 0x77, 0xb8, 0x28, 0x3a, 0xff, 0x29, 0xb6, 0x7b, 0x49, 0x1d, 0xd5, 0xbb, 0x08, 0xc2, 0x3b, 0xf6, 0x63, 0x3f, 0xf7, 0x71, 0x51, 0x72, 0xfe, 0x13, 0xd9,
0x14, 0x79, 0x23, 0xd8, 0x3d, 0x57, 0xd6, 0x3c, 0x9f, 0xb5, 0xb0, 0x8f, 0x3c, 0x58, 0xc7, 0x67, 0xee, 0x25, 0x55, 0x18, 0x0d, 0x27, 0x77, 0x5d, 0x5d, 0xf3, 0x62, 0xd6, 0xca, 0x3e, 0xf5, 0x60,
0x2a, 0x88, 0x9d, 0xe7, 0x61, 0x14, 0x3f, 0x0f, 0x53, 0x6b, 0xf9, 0x7b, 0x97, 0x2f, 0x7f, 0xe5, 0x4d, 0x1e, 0x23, 0x20, 0xb6, 0x9f, 0x85, 0x71, 0xf2, 0x2c, 0x4c, 0xad, 0xe1, 0xef, 0x5d, 0x3c,
0x76, 0x81, 0x28, 0x95, 0x51, 0x6d, 0x56, 0x19, 0x11, 0x54, 0x6c, 0x66, 0x03, 0xfb, 0x8f, 0xd4, 0xfc, 0x55, 0xd8, 0x05, 0xa3, 0x04, 0xa3, 0xda, 0x2c, 0x18, 0x21, 0x55, 0x4c, 0x66, 0x43, 0xfb,
0x16, 0x2b, 0xcc, 0xa0, 0xb8, 0x6f, 0x43, 0x23, 0x92, 0x7c, 0x9c, 0xfb, 0xd3, 0xb1, 0xfc, 0x71, 0x0f, 0xd5, 0x14, 0x2b, 0xdc, 0xc0, 0xbc, 0x6f, 0x41, 0x23, 0x16, 0x74, 0x9c, 0xc7, 0xd3, 0xb5,
0x0c, 0x0e, 0x14, 0x99, 0xff, 0x79, 0x4d, 0xb5, 0x9f, 0x89, 0x8b, 0x6e, 0xbf, 0x3b, 0xb0, 0x8c, 0xe2, 0x71, 0x1c, 0x0e, 0x94, 0x98, 0xff, 0x43, 0x4d, 0xb5, 0x9f, 0xc9, 0x8b, 0x6e, 0xbf, 0x5b,
0x9a, 0x8a, 0xc3, 0xc0, 0xa3, 0xc3, 0xc5, 0x45, 0xb2, 0x2d, 0x58, 0x2d, 0x10, 0xf6, 0x35, 0x52, 0xb0, 0x2c, 0x2d, 0x15, 0x8b, 0x81, 0x87, 0x8b, 0x8b, 0xcb, 0x24, 0x9b, 0xb0, 0x52, 0x30, 0xec,
0x46, 0x17, 0xf5, 0x50, 0x9b, 0x7d, 0x32, 0xd5, 0x9d, 0xa8, 0xf9, 0xb0, 0x94, 0x66, 0xbc, 0x50, 0x6d, 0xa4, 0xcc, 0x2e, 0xf0, 0x50, 0x9b, 0xbd, 0x32, 0xd5, 0x9d, 0xac, 0xf9, 0xb0, 0x94, 0x66,
0xde, 0x20, 0xe5, 0x0e, 0xce, 0x8d, 0x6c, 0xb3, 0x74, 0x56, 0x69, 0x09, 0xe8, 0x0c, 0x27, 0x82, 0xb4, 0x30, 0xde, 0x40, 0xe3, 0x0e, 0xcf, 0xcd, 0x6c, 0xb3, 0xb4, 0x56, 0x69, 0x0d, 0x32, 0x18,
0x96, 0x91, 0x60, 0x70, 0x28, 0x41, 0x18, 0x82, 0x05, 0x25, 0xc1, 0x20, 0x30, 0xf6, 0xf2, 0x7c, 0x8a, 0x02, 0x2d, 0xa3, 0xc1, 0xf0, 0xa4, 0x06, 0x6e, 0x04, 0x16, 0x94, 0x06, 0xc3, 0x90, 0xb9,
0x3f, 0x99, 0xc4, 0x52, 0x74, 0xda, 0x34, 0x08, 0x0c, 0xac, 0xde, 0x02, 0x2e, 0x26, 0x23, 0xd9, 0x17, 0x67, 0x7b, 0x6c, 0x92, 0x08, 0xde, 0x6d, 0xe3, 0x43, 0x60, 0x68, 0x75, 0x16, 0x50, 0x3e,
0x01, 0x62, 0x34, 0x30, 0x0e, 0x6c, 0x79, 0x8e, 0x12, 0x44, 0x67, 0x91, 0x8e, 0xe0, 0x1c, 0xa4, 0x19, 0x89, 0x2e, 0xe0, 0x45, 0x43, 0xcb, 0x07, 0x5b, 0x9c, 0x49, 0x0d, 0xbc, 0xbb, 0x88, 0x4b,
0xab, 0x0c, 0xc3, 0x7c, 0x9c, 0xb3, 0x2e, 0xa9, 0x98, 0x3a, 0x48, 0xb4, 0x5c, 0x23, 0x94, 0x90, 0x70, 0x4e, 0xe2, 0x56, 0x26, 0xd3, 0x7c, 0x94, 0x5f, 0x5d, 0x52, 0x39, 0x75, 0x98, 0xd2, 0x73,
0x65, 0x12, 0xe2, 0xe0, 0xfc, 0xa7, 0xd6, 0x2d, 0xbd, 0x9f, 0x8c, 0xc7, 0x91, 0xdc, 0xa3, 0x4b, 0xcd, 0x50, 0x4a, 0x96, 0x51, 0x89, 0xc3, 0x23, 0xb7, 0x61, 0x2d, 0x61, 0xc9, 0x1e, 0x1b, 0x8f,
0x1f, 0x07, 0x85, 0x35, 0x35, 0xdd, 0x7a, 0x2e, 0xa5, 0xd8, 0x34, 0x9a, 0x84, 0xeb, 0xe6, 0xf9, 0x63, 0x71, 0x94, 0x3b, 0xd9, 0x41, 0x27, 0xa7, 0x0f, 0xfc, 0x27, 0xd6, 0xe6, 0xad, 0x8e, 0x76,
0x79, 0x14, 0xf3, 0xec, 0xea, 0xb2, 0xb0, 0x20, 0x22, 0x71, 0xc4, 0x47, 0x27, 0xe6, 0x92, 0xa5, 0xf1, 0x7f, 0x81, 0x7c, 0x56, 0xac, 0x37, 0xd6, 0x45, 0x7f, 0x09, 0x10, 0xa6, 0x2d, 0x05, 0x5c,
0x82, 0x58, 0x08, 0xca, 0x68, 0xff, 0x9b, 0xba, 0x75, 0x57, 0x6b, 0x8d, 0xf7, 0x71, 0xcc, 0xa1, 0x35, 0xc7, 0xcf, 0xe2, 0x84, 0x66, 0x97, 0xd7, 0x25, 0xe1, 0x13, 0xf3, 0x43, 0x3a, 0x3a, 0x36,
0x37, 0x5a, 0xe3, 0xad, 0xb2, 0x46, 0xdb, 0xd7, 0x7e, 0x25, 0xd0, 0xd4, 0x6c, 0x17, 0x1a, 0x63, 0x7b, 0x2f, 0xc2, 0x67, 0x21, 0x28, 0xb3, 0xfd, 0xef, 0xea, 0xd6, 0x16, 0xae, 0x2d, 0xde, 0x93,
0x34, 0x5c, 0xcf, 0xba, 0xdf, 0x94, 0xd9, 0x2c, 0xaf, 0xfa, 0x95, 0x40, 0xd1, 0xb2, 0x7f, 0xc0, 0x8f, 0xa2, 0x8c, 0x46, 0x5b, 0xbc, 0x51, 0xb6, 0x68, 0xc7, 0x3a, 0xa8, 0x04, 0x5a, 0x9a, 0xec,
0x72, 0x28, 0x04, 0x97, 0xc7, 0xf8, 0x47, 0xe9, 0x84, 0x67, 0x7a, 0xea, 0x6d, 0x68, 0xe6, 0x3d, 0x40, 0x63, 0x2c, 0x1d, 0xd7, 0x2f, 0xe3, 0x9f, 0xca, 0xd7, 0xac, 0xa8, 0x06, 0x95, 0x40, 0xc9,
0x7c, 0x13, 0xf9, 0x63, 0xbf, 0x12, 0xb8, 0xd4, 0x86, 0xfd, 0x7f, 0x91, 0x3c, 0x1b, 0x66, 0xe1, 0x92, 0xff, 0xc2, 0x72, 0xc8, 0x39, 0x15, 0x47, 0xf2, 0x6f, 0xd5, 0x31, 0xcd, 0xf4, 0x1b, 0xb9,
0x1b, 0x7d, 0xc8, 0xb9, 0xec, 0xf9, 0xa3, 0x61, 0xcf, 0x11, 0x6c, 0x17, 0x16, 0x64, 0xae, 0xb8, 0xae, 0x2f, 0xef, 0xca, 0x33, 0x9e, 0x1f, 0x0e, 0x2a, 0x81, 0x2b, 0x6d, 0xae, 0xbf, 0x1b, 0x8b,
0x39, 0x5f, 0xb1, 0x21, 0x44, 0xa6, 0x37, 0xb9, 0xba, 0xd6, 0x7c, 0x75, 0x86, 0x90, 0x3d, 0x86, 0xd3, 0x61, 0x16, 0xbe, 0xd6, 0x6b, 0x9f, 0x7b, 0x3d, 0x3f, 0x34, 0xd7, 0x73, 0x06, 0xd9, 0x81,
0x95, 0x5c, 0xc0, 0x71, 0xf2, 0xf8, 0x9c, 0x0f, 0xa8, 0xd4, 0x8b, 0x28, 0xb9, 0xfa, 0x14, 0x49, 0x05, 0x91, 0x1b, 0x6e, 0xce, 0x37, 0x6c, 0x04, 0xe5, 0xa5, 0xd7, 0xb9, 0xb9, 0xd6, 0x7c, 0x73,
0xbf, 0x12, 0x94, 0x98, 0xd8, 0x03, 0x80, 0xd8, 0xdc, 0x95, 0xd4, 0x10, 0xf3, 0x2e, 0xc7, 0x7e, 0x46, 0x90, 0x3c, 0x82, 0x4e, 0xae, 0xe0, 0x88, 0x3d, 0x3a, 0xa3, 0x11, 0x36, 0x46, 0x91, 0x25,
0x25, 0xb0, 0xc8, 0xd9, 0x13, 0x58, 0x8d, 0xdd, 0x35, 0x45, 0x6d, 0x33, 0x77, 0x91, 0xf5, 0x2b, 0xd7, 0x9e, 0x12, 0x19, 0x54, 0x82, 0xd2, 0x25, 0x72, 0x1f, 0x20, 0x31, 0x5b, 0x28, 0xb6, 0xcf,
0x41, 0x99, 0x09, 0x8f, 0x14, 0x79, 0x41, 0x15, 0xd5, 0x08, 0xaa, 0xf2, 0xe2, 0x61, 0x4b, 0x9f, 0xbc, 0x3d, 0x73, 0x50, 0x09, 0x2c, 0x71, 0xf2, 0x18, 0x56, 0x12, 0x77, 0xa8, 0x61, 0x93, 0xcd,
0x77, 0xb8, 0x53, 0x37, 0xad, 0x9d, 0x6a, 0x15, 0xcb, 0x65, 0xfb, 0x54, 0x97, 0x76, 0xf5, 0xad, 0x1d, 0x7b, 0x83, 0x4a, 0x50, 0xbe, 0x24, 0x57, 0x1a, 0x71, 0x8e, 0x88, 0x6a, 0x04, 0x55, 0x71,
0x4b, 0xfb, 0x9e, 0xb3, 0x4f, 0xa7, 0x4a, 0xd3, 0xfe, 0x4b, 0xab, 0x37, 0xea, 0xfd, 0xf2, 0x46, 0xfe, 0xa0, 0xa5, 0x97, 0x41, 0x39, 0x81, 0x37, 0xac, 0x09, 0x6c, 0x81, 0xe5, 0xa2, 0xe9, 0xab,
0x9d, 0xcf, 0x64, 0x76, 0xea, 0x53, 0xe7, 0x9a, 0x2f, 0x2a, 0xf8, 0x4a, 0xdd, 0xfd, 0x61, 0x15, 0xa1, 0x5d, 0x7d, 0x63, 0x68, 0xdf, 0x75, 0xa6, 0xef, 0x14, 0x34, 0xed, 0x3f, 0xc0, 0x7a, 0xfe,
0x37, 0xb4, 0x2b, 0x8d, 0x0e, 0x5d, 0xf7, 0x64, 0xf5, 0xa6, 0x4e, 0xd6, 0x1e, 0x2c, 0x12, 0xa4, 0xde, 0x2b, 0xcf, 0xdf, 0xf9, 0x97, 0xcc, 0x04, 0x7e, 0xe2, 0xec, 0xfe, 0x05, 0x82, 0x2f, 0xd5,
0xc2, 0xa8, 0x83, 0x6e, 0xa3, 0xd8, 0x1f, 0x60, 0x05, 0xcf, 0xd4, 0xa3, 0x70, 0xcc, 0x35, 0x91, 0xdd, 0x9f, 0x54, 0xe5, 0x3c, 0x77, 0xb5, 0xe1, 0x5a, 0xec, 0x2e, 0xb8, 0xde, 0xd4, 0x82, 0xdb,
0xda, 0xe0, 0x25, 0x6c, 0x31, 0xfb, 0xeb, 0xb3, 0x67, 0x7f, 0xa3, 0xbc, 0x31, 0x8b, 0xa9, 0xdc, 0x87, 0x45, 0xa4, 0x54, 0x1a, 0x75, 0xd2, 0x6d, 0x16, 0xf9, 0x1b, 0x74, 0xe4, 0x52, 0x7b, 0x18,
0x9c, 0x37, 0x95, 0x5b, 0x73, 0xa6, 0xf2, 0x82, 0x3b, 0x95, 0xfd, 0x77, 0xa7, 0xeb, 0x43, 0xff, 0x8e, 0xa9, 0x16, 0x52, 0xf3, 0xbe, 0xc4, 0x2d, 0x26, 0x45, 0x7d, 0xf6, 0xa4, 0x68, 0x94, 0xe7,
0xb5, 0xf8, 0x99, 0xea, 0xc3, 0xff, 0x3d, 0x2c, 0x9a, 0xe7, 0xe3, 0x73, 0x74, 0x4f, 0xcd, 0x7d, 0x6b, 0xf1, 0x86, 0x37, 0xe7, 0xbd, 0xe1, 0xad, 0x39, 0x6f, 0xf8, 0x82, 0xfb, 0x86, 0xfb, 0x1f,
0x2d, 0x58, 0x43, 0xfe, 0x01, 0xde, 0x22, 0xc5, 0xc1, 0x74, 0x8c, 0xb1, 0x28, 0xef, 0xc8, 0xb7, 0x4c, 0xe3, 0x43, 0xff, 0x11, 0xf9, 0x8d, 0xf0, 0xe1, 0xff, 0x15, 0x16, 0xcd, 0xf1, 0xd1, 0x99,
0xf9, 0xac, 0xe0, 0x7f, 0x50, 0x85, 0x75, 0xe7, 0xaa, 0xf9, 0x75, 0x65, 0xb5, 0x7d, 0xd5, 0xac, 0x0c, 0x4f, 0x4d, 0x09, 0xad, 0x58, 0x53, 0xfe, 0xbe, 0xdc, 0x5c, 0x8a, 0xf5, 0xea, 0x48, 0xe6,
0xb6, 0xad, 0xac, 0x1e, 0xc0, 0x35, 0x27, 0x04, 0x14, 0x4d, 0x6c, 0xd5, 0x26, 0x59, 0x53, 0xbe, 0xa2, 0x3c, 0x51, 0xdf, 0xe4, 0x23, 0x84, 0xff, 0x71, 0x15, 0xd6, 0x9c, 0x1d, 0xe8, 0x8f, 0x55,
0x82, 0xa6, 0xc2, 0x15, 0x68, 0x3a, 0xd5, 0x72, 0xe5, 0xac, 0xa0, 0x65, 0xb3, 0x73, 0x32, 0x75, 0xd5, 0xf6, 0x65, 0xab, 0xda, 0xb6, 0xaa, 0xba, 0x0f, 0x57, 0x9c, 0x14, 0x60, 0x36, 0x65, 0xab,
0xd5, 0x39, 0x9f, 0x74, 0x3e, 0xab, 0xc2, 0x4a, 0xb1, 0xda, 0x70, 0xbc, 0x62, 0x91, 0xe1, 0xfd, 0x36, 0xd1, 0x9b, 0xf2, 0xce, 0x34, 0x95, 0xae, 0x40, 0xcb, 0xa9, 0x96, 0x2b, 0x57, 0x45, 0x7a,
0x9f, 0x17, 0x19, 0xfe, 0xa6, 0x61, 0x96, 0xe4, 0x5f, 0x49, 0x64, 0x82, 0xa9, 0x8b, 0xcc, 0x08, 0x36, 0xbb, 0x26, 0x53, 0x3b, 0xa0, 0xf3, 0x01, 0xe8, 0xcb, 0x2a, 0x74, 0x8a, 0xd1, 0x26, 0x9f,
0xa7, 0xa0, 0x2f, 0x04, 0x16, 0xc6, 0xaa, 0xa8, 0x3a, 0x69, 0xd4, 0x10, 0xe2, 0xc3, 0x31, 0xc6, 0x57, 0x09, 0x32, 0xf9, 0x6f, 0x21, 0x07, 0x99, 0xfc, 0x8d, 0x8f, 0x19, 0xcb, 0xbf, 0xa9, 0x08,
0x2a, 0x0f, 0xb9, 0x82, 0x50, 0x27, 0xc7, 0x71, 0xaf, 0xa2, 0x4d, 0xbf, 0xe9, 0xd8, 0xbe, 0x18, 0x26, 0x4b, 0x17, 0x9b, 0x27, 0x1c, 0x93, 0xbe, 0x10, 0x58, 0x1c, 0x0b, 0x51, 0x75, 0xb4, 0xa8,
0xbf, 0x4c, 0x46, 0xfa, 0x5f, 0x89, 0x86, 0xac, 0xb4, 0x81, 0x93, 0x36, 0xfa, 0x44, 0x84, 0xe9, 0x29, 0xc9, 0x0f, 0xc7, 0x32, 0x57, 0x79, 0xca, 0x15, 0x25, 0x6d, 0x52, 0xf9, 0xdc, 0xab, 0x6c,
0xc6, 0x68, 0xe9, 0x0b, 0x6f, 0x83, 0x28, 0xa6, 0xf0, 0x68, 0x7f, 0x1a, 0x66, 0xa1, 0xa6, 0xda, 0xe3, 0x6f, 0x5c, 0xcd, 0xcf, 0xc7, 0x2f, 0xd8, 0x48, 0xff, 0x87, 0xd1, 0x94, 0x55, 0x36, 0x70,
0x54, 0xc7, 0x6c, 0x81, 0xc1, 0xc3, 0x48, 0x4c, 0x06, 0x03, 0x2e, 0x44, 0xe7, 0x06, 0x39, 0x97, 0xca, 0x86, 0x1f, 0x94, 0x64, 0xb9, 0x65, 0xb6, 0xf4, 0x3e, 0xb8, 0x8e, 0x12, 0x53, 0x7c, 0xe9,
0x83, 0x3b, 0x5f, 0x56, 0xa1, 0x6d, 0xbe, 0x63, 0xb2, 0x7f, 0xc2, 0xc2, 0x01, 0x97, 0x94, 0x02, 0x7f, 0x1a, 0x66, 0xa1, 0x96, 0xda, 0x50, 0xab, 0x6f, 0xc1, 0x91, 0x6b, 0x14, 0x9f, 0x44, 0x11,
0xb6, 0x66, 0x32, 0xf7, 0xea, 0x48, 0x66, 0x51, 0x7c, 0xda, 0xfd, 0xdd, 0xf4, 0x4d, 0xe0, 0x7c, 0xe5, 0xbc, 0x7b, 0x0d, 0x83, 0xcb, 0xc9, 0xed, 0xaf, 0xab, 0xd0, 0x36, 0x5f, 0x3d, 0xc9, 0xff,
0x33, 0xf3, 0x2b, 0xec, 0xef, 0x00, 0xcf, 0x22, 0x21, 0x75, 0x31, 0x2c, 0x17, 0x22, 0x5e, 0x44, 0x60, 0x61, 0x9f, 0x0a, 0x2c, 0x01, 0x59, 0x35, 0x95, 0x7b, 0x79, 0x28, 0xb2, 0x38, 0x39, 0xe9,
0xa3, 0x6e, 0x77, 0x56, 0x2d, 0x28, 0x52, 0xbf, 0xc2, 0x9e, 0xc1, 0x4a, 0xae, 0x3b, 0xf7, 0xaa, 0xfd, 0x65, 0x7a, 0x27, 0x70, 0xbe, 0xb0, 0xf9, 0x15, 0xf2, 0x1f, 0x80, 0xa7, 0x31, 0x17, 0x1a,
0x60, 0x9f, 0xd5, 0xb4, 0xdd, 0x4b, 0x6b, 0xcb, 0xaf, 0xb0, 0x07, 0xb0, 0x76, 0xc0, 0x25, 0x55, 0x0c, 0xcb, 0x85, 0x8a, 0xe7, 0xf1, 0xa8, 0xd7, 0x9b, 0x85, 0x05, 0x25, 0xea, 0x57, 0xc8, 0x53,
0x80, 0x39, 0xef, 0x56, 0x0a, 0x79, 0x98, 0xbd, 0xee, 0x46, 0xd9, 0x1f, 0x22, 0xf7, 0x2b, 0xec, 0xe8, 0xe4, 0xb6, 0xf3, 0xa8, 0x8a, 0xeb, 0xb3, 0x9a, 0xb6, 0x77, 0x21, 0xb6, 0xfc, 0x0a, 0xb9,
0x4f, 0xd0, 0x3c, 0x14, 0x47, 0x17, 0xf1, 0xa0, 0xec, 0xc1, 0xba, 0x06, 0x0f, 0xc5, 0x7e, 0x38, 0x0f, 0xab, 0xfb, 0x54, 0x20, 0x02, 0xcc, 0x32, 0xd8, 0x29, 0xf4, 0xc9, 0xea, 0xf5, 0xd6, 0xcb,
0x39, 0x3d, 0x93, 0xff, 0x49, 0xfd, 0xca, 0xcb, 0x26, 0x7d, 0xb3, 0xdd, 0xfd, 0x21, 0x00, 0x00, 0xf1, 0xa0, 0xb8, 0x5f, 0x21, 0xb7, 0xa1, 0x79, 0xc0, 0x0f, 0xcf, 0x93, 0xa8, 0x1c, 0xc1, 0x9a,
0xff, 0xff, 0x3c, 0x99, 0x53, 0x18, 0x10, 0x16, 0x00, 0x00, 0x26, 0x0f, 0xf8, 0x5e, 0x38, 0x39, 0x39, 0x15, 0x6f, 0xa7, 0x7e, 0xe5, 0x45, 0x13, 0xbf, 0xf0,
0xee, 0xfc, 0x1c, 0x00, 0x00, 0xff, 0xff, 0x16, 0xa8, 0xae, 0xc0, 0x3e, 0x16, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
......
...@@ -61,7 +61,7 @@ func DisableLog() { ...@@ -61,7 +61,7 @@ func DisableLog() {
func init() { func init() {
drivers.Reg("kvmvccmavl", New) drivers.Reg("kvmvccmavl", New)
types.RegisterDappFork("store-kvmvccmavl", "ForkKvmvccmavl", 186*10000) types.RegisterDappFork("store-kvmvccmavl", "ForkKvmvccmavl", 187*10000)
} }
// KVmMavlStore provide kvmvcc and mavl store interface implementation // KVmMavlStore provide kvmvcc and mavl store interface implementation
......
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