Commit b8d027e4 authored by kingwang's avatar kingwang Committed by 33cn

update chain33 07/31

parent 23143d09
......@@ -14,6 +14,7 @@ import (
"github.com/33cn/chain33/types"
jsty "github.com/33cn/plugin/plugin/dapp/js/types"
"github.com/33cn/plugin/plugin/dapp/js/types/jsproto"
//"github.com/gojson"
"github.com/spf13/cobra"
)
......
......@@ -189,12 +189,16 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
requestblock.End = end
}
var cb func()
var timeoutcb func(height int64)
if syncOrfork {
//还有区块需要请求,挂接钩子回调函数
if requestblock.End < chain.downLoadInfo.EndHeight {
cb = func() {
chain.ReqDownLoadBlocks()
}
timeoutcb = func(height int64) {
chain.DownLoadTimeOutProc(height)
}
chain.UpdateDownLoadStartHeight(requestblock.End + 1)
//快速下载时需要及时更新bestpeer,防止下载侧链的block
if chain.GetDownloadSyncStatus() {
......@@ -203,7 +207,7 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
} else { // 所有DownLoad block已请求结束,恢复DownLoadInfo为默认值
chain.DefaultDownLoadInfo()
}
err = chain.downLoadTask.Start(requestblock.Start, requestblock.End, cb)
err = chain.downLoadTask.Start(requestblock.Start, requestblock.End, cb, timeoutcb)
if err != nil {
return err
}
......@@ -213,7 +217,7 @@ func (chain *BlockChain) FetchBlock(start int64, end int64, pid []string, syncOr
chain.SynBlocksFromPeers()
}
}
err = chain.syncTask.Start(requestblock.Start, requestblock.End, cb)
err = chain.syncTask.Start(requestblock.Start, requestblock.End, cb, timeoutcb)
if err != nil {
return err
}
......@@ -570,6 +574,12 @@ func (chain *BlockChain) SynBlocksFromPeers() {
synlog.Info("chain syncTask InProgress")
return
}
//如果此时系统正在处理回滚,不启动同步的任务。
//等分叉回滚处理结束之后再启动同步任务继续同步
if chain.downLoadTask.InProgress() {
synlog.Info("chain downLoadTask InProgress")
return
}
//获取peers的最新高度.处理没有收到广播block的情况
if curheight+1 < peerMaxBlkHeight {
synlog.Info("SynBlocksFromPeers", "curheight", curheight, "LastCastBlkHeight", RcvLastCastBlkHeight, "peerMaxBlkHeight", peerMaxBlkHeight)
......@@ -590,7 +600,6 @@ func (chain *BlockChain) SynBlocksFromPeers() {
//请求bestchain.Height -BackBlockNum -- bestchain.Height的header
//需要考虑收不到分叉之后的第一个广播block,这样就会导致后面的广播block都在孤儿节点中了。
func (chain *BlockChain) CheckHeightNoIncrease() {
synlog.Debug("CheckHeightNoIncrease")
defer chain.tickerwg.Done()
//获取当前主链的最新高度
......@@ -609,8 +618,9 @@ func (chain *BlockChain) CheckHeightNoIncrease() {
chain.UpdatesynBlkHeight(tipheight)
return
}
//一个检测周期bestchain的tip高度没有变化。并且远远落后于peer的最新高度
//本节点可能在侧链上,需要从最新的peer上向后取BackBlockNum个headers
//一个检测周期发现本节点bestchain的tip高度没有变化。
//远远落后于高度的peer节点并且最高peer节点不是最优链,本节点可能在侧链上,
//需要从最新的peer上向后取BackBlockNum个headers
maxpeer := chain.GetMaxPeerInfo()
if maxpeer == nil {
......@@ -620,8 +630,9 @@ func (chain *BlockChain) CheckHeightNoIncrease() {
peermaxheight := maxpeer.Height
pid := maxpeer.Name
var err error
if peermaxheight > tipheight && (peermaxheight-tipheight) > BackwardBlockNum {
//从指定peer 请求BackBlockNum个blockheaders
if peermaxheight > tipheight && (peermaxheight-tipheight) > BackwardBlockNum && !chain.isBestChainPeer(pid) {
//从指定peer向后请求BackBlockNum个blockheaders
synlog.Debug("CheckHeightNoIncrease", "tipheight", tipheight, "pid", pid)
if tipheight > BackBlockNum {
err = chain.FetchBlockHeaders(tipheight-BackBlockNum, tipheight, pid)
} else {
......@@ -765,7 +776,13 @@ func (chain *BlockChain) ProcBlockHeaders(headers *types.Headers, pid string) er
return nil
}
//在快速下载block阶段不处理fork的处理
//如果在普通同步阶段出现了分叉
//需要暂定同步解决分叉回滚之后再继续开启普通同步
if !chain.GetDownloadSyncStatus() {
if chain.syncTask.InProgress() {
err = chain.syncTask.Cancel()
synlog.Info("ProcBlockHeaders: cancel syncTask start fork process downLoadTask!", "err", err)
}
go chain.ProcDownLoadBlocks(ForkHeight, peermaxheight, []string{pid})
}
return nil
......@@ -951,6 +968,17 @@ func (chain *BlockChain) GetBestChainPeer(pid string) *BestPeerInfo {
return chain.bestChainPeerList[pid]
}
//isBestChainPeer 指定peer是不是最优链
func (chain *BlockChain) isBestChainPeer(pid string) bool {
chain.bestpeerlock.Lock()
defer chain.bestpeerlock.Unlock()
peer := chain.bestChainPeerList[pid]
if peer != nil && peer.IsBestChain {
return true
}
return false
}
//GetBestChainPids 定时确保本节点在最优链上,定时向peer请求指定高度的header
func (chain *BlockChain) GetBestChainPids() []string {
var PeerPids []string
......
......@@ -1088,6 +1088,7 @@ func testReadBlockToExec(t *testing.T, chain *blockchain.BlockChain) {
chainlog.Info("testReadBlockToExec begin ---------------------")
curheight := chain.GetBlockHeight()
chain.ReadBlockToExec(curheight+1, false)
chain.DownLoadTimeOutProc(curheight - 1)
chainlog.Info("testReadBlockToExec end ---------------------")
}
func testWriteBlockToDbTemp(t *testing.T, chain *blockchain.BlockChain) {
......
......@@ -331,3 +331,22 @@ func (chain *BlockChain) ReqDownLoadBlocks() {
}
}
}
//DownLoadTimeOutProc 快速下载模式下载区块超时的处理函数
func (chain *BlockChain) DownLoadTimeOutProc(height int64) {
info := chain.GetDownLoadInfo()
synlog.Info("DownLoadTimeOutProc", "timeoutheight", height, "StartHeight", info.StartHeight, "EndHeight", info.EndHeight)
if info.StartHeight != -1 && info.EndHeight != -1 && info.Pids != nil {
//从超时的高度继续下载区块
if info.StartHeight > height {
chain.UpdateDownLoadStartHeight(height)
info.StartHeight = height
}
synlog.Info("DownLoadTimeOutProc:FetchBlock", "StartHeight", info.StartHeight, "EndHeight", info.EndHeight, "pids", len(info.Pids))
err := chain.FetchBlock(info.StartHeight, info.EndHeight, info.Pids, true)
if err != nil {
synlog.Error("DownLoadTimeOutProc:FetchBlock", "err", err)
}
}
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blockchain
import (
"strings"
"github.com/33cn/chain33/types"
)
var (
filterlog = chainlog.New("submodule", "filter")
)
//GetParaTxByTitle 通过seq以及title获取对应平行连的交易
func (chain *BlockChain) GetParaTxByTitle(seq *types.ReqParaTxByTitle) (*types.ParaTxDetails, error) {
//入参数校验
err := chain.checkInputParam(seq)
if err != nil {
return nil, err
}
//获取区块的seq信息
req := &types.ReqBlocks{Start: seq.Start, End: seq.End, IsDetail: false, Pid: []string{}}
sequences, err := chain.GetBlockSequences(req)
if err != nil {
filterlog.Error("GetParaTxByTitle:GetBlockSequences", "err", err.Error())
return nil, err
}
//通过区块hash获取区块信息
var reqHashes types.ReqHashes
for _, item := range sequences.Items {
if item != nil {
reqHashes.Hashes = append(reqHashes.Hashes, item.GetHash())
}
}
blocks, err := chain.GetBlockByHashes(reqHashes.Hashes)
if err != nil {
filterlog.Error("GetParaTxByTitle:GetBlockByHashes", "err", err)
return nil, err
}
//通过指定的title过滤对应平行链的交易
var paraTxs types.ParaTxDetails
var paraTx *types.ParaTxDetail
for i, block := range blocks.Items {
if block != nil {
paraTx = block.FilterParaTxsByTitle(seq.Title)
paraTx.Type = sequences.Items[i].GetType()
} else {
paraTx = nil
}
paraTxs.Items = append(paraTxs.Items, paraTx)
}
return &paraTxs, err
}
//checkInputParam 入参检测,主要检测seq的end的值已经title是否合法
func (chain *BlockChain) checkInputParam(seq *types.ReqParaTxByTitle) error {
//入参数校验
blockLastSeq, err := chain.blockStore.LoadBlockLastSequence()
if err != nil || seq.End > blockLastSeq || blockLastSeq < 0 || !strings.HasPrefix(seq.Title, types.ParaKeyX) {
filterlog.Error("checkInputParam", "blockLastSeq", blockLastSeq, "seq", seq, "err", err)
return types.ErrInvalidParam
}
return nil
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package blockchain_test
import (
"bytes"
"errors"
"strings"
"testing"
"time"
"github.com/33cn/chain33/blockchain"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/common/merkle"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"github.com/33cn/chain33/util/testnode"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func init() {
types.Init("local", nil)
}
func addMainTx(priv crypto.PrivKey, api client.QueueProtocolAPI) (string, error) {
txs := util.GenCoinsTxs(priv, 1)
hash := common.ToHex(txs[0].Hash())
reply, err := api.SendTx(txs[0])
if err != nil {
return hash, err
}
if !reply.GetIsOk() {
return hash, errors.New("sendtx unknow error")
}
return hash, nil
}
//构造单笔para交易
func addSingleParaTx(priv crypto.PrivKey, api client.QueueProtocolAPI) (string, error) {
tx := util.CreateTxWithExecer(priv, "user.p.hyb.none")
hash := common.ToHex(tx.Hash())
reply, err := api.SendTx(tx)
if err != nil {
return hash, err
}
if !reply.GetIsOk() {
return hash, errors.New("sendtx unknow error")
}
return hash, nil
}
//构造para交易组
func addGroupParaTx(priv crypto.PrivKey, api client.QueueProtocolAPI, haveMainTx bool) (string, *types.ReplyStrings, error) {
var tx0 *types.Transaction
if haveMainTx {
tx0 = util.CreateTxWithExecer(priv, "coins")
} else {
tx0 = util.CreateTxWithExecer(priv, "user.p.hyb.coins")
}
tx1 := util.CreateTxWithExecer(priv, "user.p.hyb.token")
tx2 := util.CreateTxWithExecer(priv, "user.p.hyb.trade")
tx3 := util.CreateTxWithExecer(priv, "user.p.hyb.evm")
tx4 := util.CreateTxWithExecer(priv, "user.p.hyb.none")
var txs types.Transactions
txs.Txs = append(txs.Txs, tx0)
txs.Txs = append(txs.Txs, tx1)
txs.Txs = append(txs.Txs, tx2)
txs.Txs = append(txs.Txs, tx3)
txs.Txs = append(txs.Txs, tx4)
feeRate := types.GInt("MinFee")
group, err := types.CreateTxGroup(txs.Txs, feeRate)
if err != nil {
chainlog.Error("addGroupParaTx", "err", err.Error())
return "", nil, err
}
var txHashs types.ReplyStrings
for i, tx := range group.Txs {
group.SignN(i, int32(types.SECP256K1), priv)
txhash := common.ToHex(tx.Hash())
txHashs.Datas = append(txHashs.Datas, txhash)
}
newtx := group.Tx()
hash := common.ToHex(newtx.Hash())
reply, err := api.SendTx(newtx)
if err != nil {
return "", nil, err
}
if !reply.GetIsOk() {
return "", nil, errors.New("sendtx unknow error")
}
return hash, &txHashs, nil
}
func TestGetParaTxByTitle(t *testing.T) {
//log.SetLogLevel("crit")
mock33 := testnode.New("", nil)
defer mock33.Close()
blockchain := mock33.GetBlockChain()
chainlog.Info("TestGetParaTxByTitle begin --------------------")
//构造十个区块
curheight := blockchain.GetBlockHeight()
addblockheight := curheight + 10
_, err := blockchain.GetBlock(curheight)
if err != nil {
require.NoError(t, err)
}
for {
_, err = addMainTx(mock33.GetGenesisKey(), mock33.GetAPI())
require.NoError(t, err)
_, err = addSingleParaTx(mock33.GetGenesisKey(), mock33.GetAPI())
require.NoError(t, err)
//_, _, err = addGroupParaTx(mock33.GetGenesisKey(), mock33.GetAPI(), true)
//require.NoError(t, err)
_, _, err = addGroupParaTx(mock33.GetGenesisKey(), mock33.GetAPI(), false)
require.NoError(t, err)
curheight = blockchain.GetBlockHeight()
_, err = blockchain.GetBlock(curheight)
require.NoError(t, err)
if curheight >= addblockheight {
break
}
time.Sleep(sendTxWait)
}
var req types.ReqParaTxByTitle
req.Start = 0
req.End = curheight
req.Title = "user.p.hyb."
testgetParaTxByTitle(t, blockchain, &req, false, false, nil)
chainlog.Info("TestGetParaTxByTitle end --------------------")
}
func testgetParaTxByTitle(t *testing.T, blockchain *blockchain.BlockChain, req *types.ReqParaTxByTitle, isGroup bool, haveMainTx bool, hashs []string) {
ParaTxDetails, err := blockchain.GetParaTxByTitle(req)
require.NoError(t, err)
for i, txDetail := range ParaTxDetails.Items {
if txDetail != nil {
assert.Equal(t, txDetail.Header.Height, req.Start+int64(i))
//chainlog.Info("testgetParaTxByTitle:", "Height", txDetail.Header.Height)
for _, tx := range txDetail.TxDetails {
if tx != nil {
execer := string(tx.Tx.Execer)
if !strings.HasPrefix(execer, "user.p.hyb.") && tx.Tx.GetGroupCount() != 0 {
//chainlog.Info("testgetParaTxByTitle:maintxingroup", "tx", tx)
assert.Equal(t, tx.Receipt.Ty, int32(types.ExecOk))
} else {
assert.Equal(t, tx.Receipt.Ty, int32(types.ExecPack))
}
if tx.Proofs != nil {
roothash := merkle.GetMerkleRootFromBranch(tx.Proofs, tx.Tx.Hash(), tx.Index)
ok := bytes.Equal(roothash, txDetail.Header.GetHash())
assert.Equal(t, ok, false)
}
}
}
}
}
}
......@@ -101,6 +101,9 @@ func (chain *BlockChain) ProcRecvMsg() {
case types.EventGetValueByKey:
go chain.processMsg(msg, reqnum, chain.getValueByKey)
//通过平行链title获取平行链的交易
case types.EventGetParaTxByTitle:
go chain.processMsg(msg, reqnum, chain.getParaTxByTitle)
default:
go chain.processMsg(msg, reqnum, chain.unknowMsg)
}
......@@ -586,3 +589,15 @@ func (chain *BlockChain) getValueByKey(msg *queue.Message) {
values := chain.GetValueByKey(keys)
msg.Reply(chain.client.NewMessage("", types.EventLocalReplyValue, values))
}
//getParaTxByTitle //通过平行链title获取平行链的交易
func (chain *BlockChain) getParaTxByTitle(msg *queue.Message) {
req := (msg.Data).(*types.ReqParaTxByTitle)
reply, err := chain.GetParaTxByTitle(req)
if err != nil {
chainlog.Error("getParaTxByTitle", "req", req, "err", err.Error())
msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, err))
return
}
msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, reply))
}
......@@ -15,14 +15,15 @@ import (
//Task 任务
type Task struct {
sync.Mutex
cond *sync.Cond
start int64
end int64
isruning bool
ticker *time.Timer
timeout time.Duration
cb func()
donelist map[int64]struct{}
cond *sync.Cond
start int64
end int64
isruning bool
ticker *time.Timer
timeout time.Duration
cb func()
donelist map[int64]struct{}
timeoutcb func(height int64)
}
func newTask(timeout time.Duration) *Task {
......@@ -43,12 +44,15 @@ func (t *Task) tick() {
t.cond.L.Unlock()
_, ok := <-t.ticker.C
if !ok {
chainlog.Error("task is done", "timer is stop", t.start)
chainlog.Error("task is done", "timer ticker is stop", t.start)
continue
}
t.Lock()
if err := t.stop(false); err == nil {
chainlog.Debug("task is done", "timer is stop", t.start)
if t.timeoutcb != nil {
go t.timeoutcb(t.start)
}
chainlog.Debug("task is done", "timer timeout is stop", t.start)
}
t.Unlock()
}
......@@ -78,7 +82,7 @@ func (t *Task) TimerStop() {
}
//Start 计时器启动
func (t *Task) Start(start, end int64, cb func()) error {
func (t *Task) Start(start, end int64, cb func(), timeoutcb func(height int64)) error {
t.Lock()
defer t.Unlock()
if t.isruning {
......@@ -93,6 +97,7 @@ func (t *Task) Start(start, end int64, cb func()) error {
t.start = start
t.end = end
t.cb = cb
t.timeoutcb = timeoutcb
t.donelist = make(map[int64]struct{})
t.cond.Signal()
return nil
......
......@@ -17,7 +17,7 @@ func TestTask(t *testing.T) {
t.Log("task not start")
return
}
task.Start(1, 10, nil)
task.Start(1, 10, nil, nil)
perm := rand.Perm(10)
for i := 0; i < len(perm); i++ {
time.Sleep(time.Millisecond * 5)
......@@ -43,7 +43,7 @@ func TestTasks(t *testing.T) {
t.Log("task not start")
return
}
task.Start(1, 10, nil)
task.Start(1, 10, nil, nil)
perm := rand.Perm(10)
for i := 0; i < len(perm); i++ {
time.Sleep(time.Millisecond / 10)
......@@ -61,3 +61,35 @@ func TestTasks(t *testing.T) {
}
}
}
func TestTaskTimeOut(t *testing.T) {
task := newTask(time.Millisecond * 10)
if task.InProgress() {
task.Cancel()
t.Log("task not start")
return
}
timeoutcb := func(height int64) {
timeOutProc(height)
}
task.Start(1, 10, nil, timeoutcb)
perm := rand.Perm(10)
for i := 0; i < len(perm); i++ {
time.Sleep(time.Millisecond * 10)
task.Done(int64(perm[i]) + 1)
if i < len(perm)-1 && !task.InProgress() {
task.Cancel()
t.Log("task not done, but InProgress is false")
return
}
if i == len(perm)-1 && task.InProgress() {
task.Cancel()
t.Log("task is done, but InProgress is true")
return
}
}
}
func timeOutProc(height int64) {
chainlog.Info("timeOutProc", "height", height)
}
......@@ -3,7 +3,7 @@ FROM ubuntu:16.04
WORKDIR /root
COPY chain33 chain33
COPY chain33-cli chain33-cli
COPY chain33.toml ./
COPY chain33.toml chain33-solo.toml ./
RUN ./chain33-cli cert --host=127.0.0.1
......
......@@ -70,6 +70,7 @@ echo "CLI=$CLI"
####################
testtoml=chain33.toml
testtomlsolo=chain33-solo.toml
function base_init() {
......@@ -93,6 +94,7 @@ function base_init() {
# wallet
sed -i $sedfix 's/^minerdisable=.*/minerdisable=false/g' ${testtoml}
cp ${testtoml} ${testtomlsolo}
#consens
consens_init "solo"
......@@ -103,6 +105,9 @@ function consens_init() {
if [ "$1" == "solo" ]; then
sed -i $sedfix 's/^name="ticket"/name="solo"/g' ${testtoml}
sed -i $sedfix 's/^singleMode=false/singleMode=true/g' ${testtoml}
# only one node miner for solo miner
sed -i $sedfix 's/^minerstart=true/minerstart=false/g' ${testtomlsolo}
fi
}
......
......@@ -8,19 +8,24 @@ services:
chain32:
build:
context: .
command: ["/root/chain33", "-f", "/root/chain33-solo.toml"]
chain31:
build:
context: .
command: ["/root/chain33", "-f", "/root/chain33-solo.toml"]
chain30:
build:
context: .
command: ["/root/chain33", "-f", "/root/chain33-solo.toml"]
chain29:
build:
context: .
command: ["/root/chain33", "-f", "/root/chain33-solo.toml"]
chain28:
build:
context: .
command: ["/root/chain33", "-f", "/root/chain33-solo.toml"]
......@@ -174,6 +174,17 @@ func (m *mockBlockChain) SetQueueClient(q queue.Queue) {
} else {
msg.ReplyErr("request must be nil", types.ErrInvalidParam)
}
case types.EventGetParaTxByTitle:
if req, ok := msg.GetData().(*types.ReqParaTxByTitle); ok {
// just for cover
if req.Title == "user" {
msg.Reply(client.NewMessage(blockchainKey, types.EventReplyParaTxByTitle, &types.Reply{IsOk: false, Msg: []byte("not support")}))
} else {
msg.Reply(client.NewMessage(blockchainKey, types.EventReplyParaTxByTitle, &types.ParaTxDetails{}))
}
}
default:
msg.ReplyErr("Do not support", types.ErrNotSupport)
}
......
......@@ -522,6 +522,29 @@ func (_m *QueueProtocolAPI) GetNetInfo() (*types.NodeNetInfo, error) {
return r0, r1
}
// GetParaTxByTitle provides a mock function with given fields: param
func (_m *QueueProtocolAPI) GetParaTxByTitle(param *types.ReqParaTxByTitle) (*types.ParaTxDetails, error) {
ret := _m.Called(param)
var r0 *types.ParaTxDetails
if rf, ok := ret.Get(0).(func(*types.ReqParaTxByTitle) *types.ParaTxDetails); ok {
r0 = rf(param)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ParaTxDetails)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(*types.ReqParaTxByTitle) error); ok {
r1 = rf(param)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetProperFee provides a mock function with given fields: req
func (_m *QueueProtocolAPI) GetProperFee(req *types.ReqProperFee) (*types.ReplyProperFee, error) {
ret := _m.Called(req)
......
......@@ -1277,3 +1277,22 @@ func (q *QueueProtocol) GetMainSequenceByHash(param *types.ReqHash) (*types.Int6
}
return nil, types.ErrTypeAsset
}
//GetParaTxByTitle 通过seq以及title获取对应平行连的交易
func (q *QueueProtocol) GetParaTxByTitle(param *types.ReqParaTxByTitle) (*types.ParaTxDetails, error) {
if param == nil {
err := types.ErrInvalidParam
log.Error("GetParaTxByTitle", "Error", err)
return nil, err
}
msg, err := q.send(blockchainKey, types.EventGetParaTxByTitle, param)
if err != nil {
log.Error("GetParaTxByTitle", "Error", err.Error())
return nil, err
}
if reply, ok := msg.GetData().(*types.ParaTxDetails); ok {
return reply, nil
}
return nil, types.ErrTypeAsset
}
......@@ -938,6 +938,7 @@ func TestGRPC(t *testing.T) {
testIsSyncGRPC(t, &grpcMock)
testIsNtpClockSyncGRPC(t, &grpcMock)
testNetInfoGRPC(t, &grpcMock)
testGetParaTxByTitleGRPC(t, &grpcMock)
}
......@@ -1302,3 +1303,25 @@ func TestGetMainSeq(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, int64(9999), seq1.Data)
}
func testGetParaTxByTitleGRPC(t *testing.T, rpc *mockGRPCSystem) {
var res types.ParaTxDetails
var req types.ReqParaTxByTitle
req.Start = 0
req.End = 0
req.Title = "user"
err := rpc.newRpcCtx("GetParaTxByTitle", &req, &res)
assert.NotNil(t, err)
req.Title = "user.p.para."
err = rpc.newRpcCtx("GetParaTxByTitle", &req, &res)
assert.Nil(t, err)
}
func TestGetParaTxByTitle(t *testing.T) {
q := client.QueueProtocol{}
_, err := q.GetParaTxByTitle(nil)
assert.NotNil(t, err)
}
......@@ -158,4 +158,6 @@ type QueueProtocolAPI interface {
ListSeqCallBack() (*types.BlockSeqCBs, error)
// types.EventGetSeqCBLastNum
GetSeqCallBackLastNum(param *types.ReqString) (*types.Int64, error)
// types.EventGetParaTxByTitle
GetParaTxByTitle(param *types.ReqParaTxByTitle) (*types.ParaTxDetails, error)
}
......@@ -327,6 +327,13 @@ func (c *GrpcCtx) Run() (err error) {
*c.Res.(*types.BlockSeq) = *reply
}
errRet = err
case "GetParaTxByTitle":
reply, err := rpc.GetParaTxByTitle(context.Background(), c.Params.(*types.ReqParaTxByTitle))
if err == nil {
*c.Res.(*types.ParaTxDetails) = *reply
}
errRet = err
default:
errRet = errors.New(fmt.Sprintf("Unsupport method %v", c.Method))
}
......
......@@ -233,8 +233,11 @@ func (d *DownloadJob) syncDownloadBlock(peer *Peer, inv *pb.Inventory, bchan cha
var p2pdata pb.P2PGetData
p2pdata.Version = d.p2pcli.network.node.nodeInfo.channelVersion
p2pdata.Invs = []*pb.Inventory{inv}
ctx, cancel := context.WithCancel(context.Background())
//主动取消grpc流, 即时释放资源
defer cancel()
beg := pb.Now()
resp, err := peer.mconn.gcli.GetData(context.Background(), &p2pdata, grpc.FailFast(true))
resp, err := peer.mconn.gcli.GetData(ctx, &p2pdata, grpc.FailFast(true))
P2pComm.CollectPeerStat(err, peer)
if err != nil {
log.Error("syncDownloadBlock", "GetData err", err.Error())
......
......@@ -116,8 +116,8 @@ func Test_processP2P(t *testing.T) {
<-subChan //query block
for !ltBlockCache.contains(blockHash) {
}
ltBlock := ltBlockCache.get(blockHash).(*types.Block)
assert.True(t, bytes.Equal(rootHash, merkle.CalcMerkleRoot(ltBlock.Txs)))
cpBlock := *ltBlockCache.get(blockHash).(*types.Block)
assert.True(t, bytes.Equal(rootHash, merkle.CalcMerkleRoot(cpBlock.Txs)))
//query tx
sendChan <- &versionData{rawData: &types.P2PQueryData{Value: &types.P2PQueryData_TxReq{TxReq: &types.P2PTxReq{TxHash: tx.Hash()}}}}
......@@ -147,7 +147,7 @@ func Test_processP2P(t *testing.T) {
<-subChan
assert.True(t, ltBlockCache.contains(blockHash))
ltBlock.TxHash = rootHash
cpBlock.TxHash = rootHash
sendChan <- &versionData{rawData: &types.P2PBlockTxReply{
BlockHash: blockHash,
Txs: txList[0:],
......
......@@ -386,3 +386,8 @@ func (g *Grpc) GetFork(ctx context.Context, in *pb.ReqKey) (*pb.Int64, error) {
}
return &pb.Int64{Data: pb.GetFork(string(in.Key))}, nil
}
// GetParaTxByTitle 通过seq以及title获取对应平行连的交易
func (g *Grpc) GetParaTxByTitle(ctx context.Context, in *pb.ReqParaTxByTitle) (*pb.ParaTxDetails, error) {
return g.cli.GetParaTxByTitle(in)
}
......@@ -5,6 +5,7 @@
package types
import (
"bytes"
"runtime"
"sync"
......@@ -63,6 +64,7 @@ func (block *Block) GetHeader() *Header {
head.Difficulty = block.Difficulty
head.StateHash = block.StateHash
head.TxCount = int64(len(block.Txs))
head.Hash = block.Hash()
return head
}
......@@ -186,3 +188,59 @@ func CheckSign(data []byte, execer string, sign *Signature) bool {
}
return pub.VerifyBytes(data, signbytes)
}
//FilterParaTxsByTitle 过滤指定title的平行链交易
//1,单笔平行连交易
//2,交易组中的平行连交易,需要将整个交易组都过滤出来
//目前暂时不返回单个交易的proof证明路径,
//后面会将平行链的交易组装到一起,构成一个子roothash。会返回子roothash的proof证明路径
func (blockDetail *BlockDetail) FilterParaTxsByTitle(title string) *ParaTxDetail {
var paraTx ParaTxDetail
paraTx.Header = blockDetail.Block.GetHeader()
for i := 0; i < len(blockDetail.Block.Txs); i++ {
tx := blockDetail.Block.Txs[i]
if IsSpecificParaExecName(title, string(tx.Execer)) {
//过滤交易组中的para交易,需要将整个交易组都过滤出来
if tx.GroupCount >= 2 {
txDetails, endIdx := blockDetail.filterParaTxGroup(tx, i)
paraTx.TxDetails = append(paraTx.TxDetails, txDetails...)
i = endIdx - 1
continue
}
//单笔para交易
var txDetail TxDetail
txDetail.Tx = tx
txDetail.Receipt = blockDetail.Receipts[i]
txDetail.Index = uint32(i)
paraTx.TxDetails = append(paraTx.TxDetails, &txDetail)
}
}
return &paraTx
}
//filterParaTxGroup 获取para交易所在交易组信息
func (blockDetail *BlockDetail) filterParaTxGroup(tx *Transaction, index int) ([]*TxDetail, int) {
var headIdx int
var txDetails []*TxDetail
for i := index; i >= 0; i-- {
if bytes.Equal(tx.Header, blockDetail.Block.Txs[i].Hash()) {
headIdx = i
break
}
}
endIdx := headIdx + int(tx.GroupCount)
for i := headIdx; i < endIdx; i++ {
var txDetail TxDetail
txDetail.Tx = blockDetail.Block.Txs[i]
txDetail.Receipt = blockDetail.Receipts[i]
txDetail.Index = uint32(i)
txDetails = append(txDetails, &txDetail)
}
return txDetails, endIdx
}
......@@ -2,9 +2,12 @@ package types
import (
"encoding/hex"
"strings"
"testing"
"github.com/33cn/chain33/common/address"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestBlock(t *testing.T) {
......@@ -28,3 +31,84 @@ func TestBlock(t *testing.T) {
b.Txs = append(b.Txs, &Transaction{})
assert.Equal(t, false, b.CheckSign())
}
func TestFilterParaTxsByTitle(t *testing.T) {
to := "14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
//构造一个主链交易
maintx := &Transaction{Execer: []byte("coins"), Payload: []byte("none")}
maintx.To = to
maintx, err := FormatTx("coins", maintx)
require.NoError(t, err)
//构造一个平行链交易
execer := "user.p.hyb.none"
paratx := &Transaction{Execer: []byte(execer), Payload: []byte("none")}
paratx.To = address.ExecAddress(execer)
paratx, err = FormatTx(execer, paratx)
require.NoError(t, err)
//构造一个平行链交易组
execer1 := "user.p.hyb.coins"
tx1 := &Transaction{Execer: []byte(execer1), Payload: []byte("none")}
tx1.To = address.ExecAddress(execer1)
tx1, err = FormatTx(execer1, tx1)
require.NoError(t, err)
execer2 := "user.p.hyb.token"
tx2 := &Transaction{Execer: []byte(execer2), Payload: []byte("none")}
tx2.To = address.ExecAddress(execer2)
tx2, err = FormatTx(execer2, tx2)
require.NoError(t, err)
execer3 := "user.p.hyb.trade"
tx3 := &Transaction{Execer: []byte(execer3), Payload: []byte("none")}
tx3.To = address.ExecAddress(execer3)
tx3, err = FormatTx(execer3, tx3)
require.NoError(t, err)
var txs Transactions
txs.Txs = append(txs.Txs, tx1)
txs.Txs = append(txs.Txs, tx2)
txs.Txs = append(txs.Txs, tx3)
feeRate := GInt("MinFee")
group, err := CreateTxGroup(txs.Txs, feeRate)
require.NoError(t, err)
//构造一个有平行链交易的区块
block := &Block{}
block.Version = 0
block.Height = 0
block.BlockTime = 1
block.Difficulty = 1
block.Txs = append(block.Txs, maintx)
block.Txs = append(block.Txs, paratx)
block.Txs = append(block.Txs, group.Txs...)
blockdetal := &BlockDetail{}
blockdetal.Block = block
maintxreceipt := &ReceiptData{Ty: ExecOk}
paratxreceipt := &ReceiptData{Ty: ExecPack}
grouppara1receipt := &ReceiptData{Ty: ExecPack}
grouppara2receipt := &ReceiptData{Ty: ExecPack}
grouppara3receipt := &ReceiptData{Ty: ExecPack}
blockdetal.Receipts = append(blockdetal.Receipts, maintxreceipt)
blockdetal.Receipts = append(blockdetal.Receipts, paratxreceipt)
blockdetal.Receipts = append(blockdetal.Receipts, grouppara1receipt)
blockdetal.Receipts = append(blockdetal.Receipts, grouppara2receipt)
blockdetal.Receipts = append(blockdetal.Receipts, grouppara3receipt)
txDetail := blockdetal.FilterParaTxsByTitle("user.p.hyb.")
for _, tx := range txDetail.TxDetails {
if tx != nil {
execer := string(tx.Tx.Execer)
if !strings.HasPrefix(execer, "user.p.hyb.") && tx.Tx.GetGroupCount() != 0 {
assert.Equal(t, tx.Receipt.Ty, int32(ExecOk))
} else {
assert.Equal(t, tx.Receipt.Ty, int32(ExecPack))
}
}
}
}
......@@ -1578,6 +1578,228 @@ func (m *ParaChainBlockDetail) GetSequence() int64 {
return 0
}
// 定义para交易结构
type ParaTxDetails struct {
Items []*ParaTxDetail `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ParaTxDetails) Reset() { *m = ParaTxDetails{} }
func (m *ParaTxDetails) String() string { return proto.CompactTextString(m) }
func (*ParaTxDetails) ProtoMessage() {}
func (*ParaTxDetails) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{29}
}
func (m *ParaTxDetails) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ParaTxDetails.Unmarshal(m, b)
}
func (m *ParaTxDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ParaTxDetails.Marshal(b, m, deterministic)
}
func (m *ParaTxDetails) XXX_Merge(src proto.Message) {
xxx_messageInfo_ParaTxDetails.Merge(m, src)
}
func (m *ParaTxDetails) XXX_Size() int {
return xxx_messageInfo_ParaTxDetails.Size(m)
}
func (m *ParaTxDetails) XXX_DiscardUnknown() {
xxx_messageInfo_ParaTxDetails.DiscardUnknown(m)
}
var xxx_messageInfo_ParaTxDetails proto.InternalMessageInfo
func (m *ParaTxDetails) GetItems() []*ParaTxDetail {
if m != nil {
return m.Items
}
return nil
}
// type:平行链交易所在区块add/del操作,方便平行链回滚
// header:平行链交易所在区块头信息
// txDetails:本区块中指定title平行链的所有交易
type ParaTxDetail struct {
Type int64 `protobuf:"varint,1,opt,name=type,proto3" json:"type,omitempty"`
Header *Header `protobuf:"bytes,2,opt,name=header,proto3" json:"header,omitempty"`
TxDetails []*TxDetail `protobuf:"bytes,3,rep,name=txDetails,proto3" json:"txDetails,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ParaTxDetail) Reset() { *m = ParaTxDetail{} }
func (m *ParaTxDetail) String() string { return proto.CompactTextString(m) }
func (*ParaTxDetail) ProtoMessage() {}
func (*ParaTxDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{30}
}
func (m *ParaTxDetail) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ParaTxDetail.Unmarshal(m, b)
}
func (m *ParaTxDetail) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ParaTxDetail.Marshal(b, m, deterministic)
}
func (m *ParaTxDetail) XXX_Merge(src proto.Message) {
xxx_messageInfo_ParaTxDetail.Merge(m, src)
}
func (m *ParaTxDetail) XXX_Size() int {
return xxx_messageInfo_ParaTxDetail.Size(m)
}
func (m *ParaTxDetail) XXX_DiscardUnknown() {
xxx_messageInfo_ParaTxDetail.DiscardUnknown(m)
}
var xxx_messageInfo_ParaTxDetail proto.InternalMessageInfo
func (m *ParaTxDetail) GetType() int64 {
if m != nil {
return m.Type
}
return 0
}
func (m *ParaTxDetail) GetHeader() *Header {
if m != nil {
return m.Header
}
return nil
}
func (m *ParaTxDetail) GetTxDetails() []*TxDetail {
if m != nil {
return m.TxDetails
}
return nil
}
//交易的详情:
// index:本交易在block中索引值,用于proof的证明
// tx:本交易内容
// receipt:本交易在主链的执行回执
// proofs:本交易hash在block中merkel中的路径
type TxDetail struct {
Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
Tx *Transaction `protobuf:"bytes,2,opt,name=tx,proto3" json:"tx,omitempty"`
Receipt *ReceiptData `protobuf:"bytes,3,opt,name=receipt,proto3" json:"receipt,omitempty"`
Proofs [][]byte `protobuf:"bytes,4,rep,name=proofs,proto3" json:"proofs,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TxDetail) Reset() { *m = TxDetail{} }
func (m *TxDetail) String() string { return proto.CompactTextString(m) }
func (*TxDetail) ProtoMessage() {}
func (*TxDetail) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{31}
}
func (m *TxDetail) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_TxDetail.Unmarshal(m, b)
}
func (m *TxDetail) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_TxDetail.Marshal(b, m, deterministic)
}
func (m *TxDetail) XXX_Merge(src proto.Message) {
xxx_messageInfo_TxDetail.Merge(m, src)
}
func (m *TxDetail) XXX_Size() int {
return xxx_messageInfo_TxDetail.Size(m)
}
func (m *TxDetail) XXX_DiscardUnknown() {
xxx_messageInfo_TxDetail.DiscardUnknown(m)
}
var xxx_messageInfo_TxDetail proto.InternalMessageInfo
func (m *TxDetail) GetIndex() uint32 {
if m != nil {
return m.Index
}
return 0
}
func (m *TxDetail) GetTx() *Transaction {
if m != nil {
return m.Tx
}
return nil
}
func (m *TxDetail) GetReceipt() *ReceiptData {
if m != nil {
return m.Receipt
}
return nil
}
func (m *TxDetail) GetProofs() [][]byte {
if m != nil {
return m.Proofs
}
return nil
}
//通过seq区间和title请求平行链的交易
type ReqParaTxByTitle struct {
Start int64 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
End int64 `protobuf:"varint,2,opt,name=end,proto3" json:"end,omitempty"`
Title string `protobuf:"bytes,3,opt,name=title,proto3" json:"title,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReqParaTxByTitle) Reset() { *m = ReqParaTxByTitle{} }
func (m *ReqParaTxByTitle) String() string { return proto.CompactTextString(m) }
func (*ReqParaTxByTitle) ProtoMessage() {}
func (*ReqParaTxByTitle) Descriptor() ([]byte, []int) {
return fileDescriptor_e9ac6287ce250c9a, []int{32}
}
func (m *ReqParaTxByTitle) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReqParaTxByTitle.Unmarshal(m, b)
}
func (m *ReqParaTxByTitle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReqParaTxByTitle.Marshal(b, m, deterministic)
}
func (m *ReqParaTxByTitle) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReqParaTxByTitle.Merge(m, src)
}
func (m *ReqParaTxByTitle) XXX_Size() int {
return xxx_messageInfo_ReqParaTxByTitle.Size(m)
}
func (m *ReqParaTxByTitle) XXX_DiscardUnknown() {
xxx_messageInfo_ReqParaTxByTitle.DiscardUnknown(m)
}
var xxx_messageInfo_ReqParaTxByTitle proto.InternalMessageInfo
func (m *ReqParaTxByTitle) GetStart() int64 {
if m != nil {
return m.Start
}
return 0
}
func (m *ReqParaTxByTitle) GetEnd() int64 {
if m != nil {
return m.End
}
return 0
}
func (m *ReqParaTxByTitle) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func init() {
proto.RegisterType((*Header)(nil), "types.Header")
proto.RegisterType((*Block)(nil), "types.Block")
......@@ -1608,82 +1830,95 @@ func init() {
proto.RegisterType((*BlockSequence)(nil), "types.BlockSequence")
proto.RegisterType((*BlockSequences)(nil), "types.BlockSequences")
proto.RegisterType((*ParaChainBlockDetail)(nil), "types.ParaChainBlockDetail")
proto.RegisterType((*ParaTxDetails)(nil), "types.ParaTxDetails")
proto.RegisterType((*ParaTxDetail)(nil), "types.ParaTxDetail")
proto.RegisterType((*TxDetail)(nil), "types.TxDetail")
proto.RegisterType((*ReqParaTxByTitle)(nil), "types.ReqParaTxByTitle")
}
func init() { proto.RegisterFile("blockchain.proto", fileDescriptor_e9ac6287ce250c9a) }
var fileDescriptor_e9ac6287ce250c9a = []byte{
// 1151 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x56, 0xdd, 0x6e, 0x1b, 0x45,
0x14, 0xd6, 0xfa, 0x2f, 0xf6, 0xf1, 0x0f, 0xe9, 0xc8, 0x20, 0x2b, 0x02, 0xea, 0x0e, 0x55, 0xb1,
0x42, 0xe5, 0xa0, 0x04, 0x95, 0x5e, 0x80, 0x04, 0x71, 0x90, 0x92, 0xa6, 0x94, 0x30, 0x49, 0x73,
0xc1, 0xdd, 0x64, 0x3d, 0xc9, 0xae, 0xe2, 0xfd, 0xc9, 0xce, 0xac, 0xf1, 0xf2, 0x0e, 0x3c, 0x02,
0x2f, 0x80, 0x78, 0x27, 0x5e, 0x05, 0xcd, 0x99, 0x59, 0xef, 0xae, 0x49, 0x8a, 0x7a, 0xc9, 0xdd,
0x9c, 0xff, 0xef, 0x9c, 0x33, 0x73, 0xce, 0xc0, 0xf6, 0xd5, 0x22, 0x72, 0x6f, 0x5d, 0x8f, 0xfb,
0xe1, 0x34, 0x4e, 0x22, 0x15, 0x91, 0xa6, 0xca, 0x62, 0x21, 0x77, 0x1e, 0xa9, 0x84, 0x87, 0x92,
0xbb, 0xca, 0x8f, 0xac, 0x64, 0xa7, 0xe7, 0x46, 0x41, 0x90, 0x53, 0xf4, 0xaf, 0x1a, 0xb4, 0x8e,
0x05, 0x9f, 0x8b, 0x84, 0x8c, 0x60, 0x6b, 0x29, 0x12, 0xe9, 0x47, 0xe1, 0xc8, 0x19, 0x3b, 0x93,
0x3a, 0xcb, 0x49, 0xf2, 0x29, 0x40, 0xcc, 0x13, 0x11, 0xaa, 0x63, 0x2e, 0xbd, 0x51, 0x6d, 0xec,
0x4c, 0x7a, 0xac, 0xc4, 0x21, 0x1f, 0x41, 0x4b, 0xad, 0x50, 0x56, 0x47, 0x99, 0xa5, 0xc8, 0xc7,
0xd0, 0x91, 0x8a, 0x2b, 0x81, 0xa2, 0x06, 0x8a, 0x0a, 0x86, 0xb6, 0xf2, 0x84, 0x7f, 0xe3, 0xa9,
0x51, 0x13, 0xc3, 0x59, 0x4a, 0x5b, 0x61, 0x3a, 0x17, 0x7e, 0x20, 0x46, 0x2d, 0x14, 0x15, 0x0c,
0x8d, 0x52, 0xad, 0x66, 0x51, 0x1a, 0xaa, 0x51, 0xc7, 0xa0, 0xb4, 0x24, 0x21, 0xd0, 0xf0, 0x74,
0x20, 0xc0, 0x40, 0x78, 0xd6, 0xc8, 0xe7, 0xfe, 0xf5, 0xb5, 0xef, 0xa6, 0x0b, 0x95, 0x8d, 0xba,
0x63, 0x67, 0xd2, 0x67, 0x25, 0x0e, 0x99, 0x42, 0x47, 0xfa, 0x37, 0x21, 0x57, 0x69, 0x22, 0x46,
0xed, 0xb1, 0x33, 0xe9, 0xee, 0x6f, 0x4f, 0xb1, 0x74, 0xd3, 0xf3, 0x9c, 0xcf, 0x0a, 0x15, 0xfa,
0x77, 0x0d, 0x9a, 0x87, 0x1a, 0xcb, 0xff, 0xa4, 0x5a, 0xff, 0x95, 0xff, 0x0e, 0xb4, 0x03, 0xee,
0x87, 0x18, 0xb2, 0x87, 0x21, 0xd7, 0xb4, 0xb6, 0xc5, 0xb3, 0x89, 0xda, 0x47, 0xd7, 0x25, 0xce,
0xfb, 0xd6, 0x8e, 0x3c, 0x85, 0xba, 0x5a, 0xc9, 0xd1, 0xd6, 0xb8, 0x3e, 0xe9, 0xee, 0x13, 0xab,
0x79, 0x51, 0xdc, 0x4f, 0xa6, 0xc5, 0xf4, 0x39, 0xb4, 0xb0, 0xc0, 0x92, 0x50, 0x68, 0xfa, 0x4a,
0x04, 0x72, 0xe4, 0xa0, 0x45, 0xcf, 0x5a, 0xa0, 0x94, 0x19, 0x11, 0x7d, 0x05, 0x80, 0xf4, 0xb9,
0xb8, 0x9b, 0x1d, 0xea, 0x1b, 0x10, 0xf2, 0x40, 0x60, 0x43, 0x3a, 0x0c, 0xcf, 0x64, 0x1b, 0xea,
0x6f, 0xd9, 0x6b, 0x6c, 0x43, 0x87, 0xe9, 0xa3, 0xae, 0xa4, 0x08, 0xdd, 0x68, 0x2e, 0xb0, 0xfe,
0x1d, 0x66, 0x29, 0xfa, 0x02, 0xba, 0x85, 0x2f, 0x49, 0x3e, 0xaf, 0x86, 0x7f, 0x54, 0x0e, 0x8f,
0x2a, 0x39, 0x86, 0x18, 0xda, 0x39, 0x53, 0x47, 0x0b, 0xd3, 0xc0, 0xde, 0x08, 0x7d, 0x24, 0xcf,
0xa0, 0x2e, 0xc5, 0x1d, 0xc6, 0xef, 0xee, 0x0f, 0x37, 0x9c, 0xa4, 0x22, 0x74, 0x05, 0xd3, 0x0a,
0x64, 0x17, 0x5a, 0x73, 0xa1, 0xb8, 0xbf, 0x40, 0x54, 0x45, 0x81, 0x50, 0xf5, 0x08, 0x25, 0xcc,
0x6a, 0xd0, 0x2f, 0xa1, 0x93, 0x7b, 0x90, 0xe4, 0x33, 0x68, 0x48, 0x71, 0x97, 0xc3, 0xfc, 0x60,
0x23, 0x02, 0x43, 0x21, 0xfd, 0xce, 0x62, 0x3c, 0xf3, 0xe7, 0x1a, 0x63, 0xec, 0xcf, 0x6d, 0x91,
0xf4, 0x51, 0x57, 0x1a, 0xaf, 0x8c, 0x45, 0xb9, 0x51, 0x69, 0x14, 0xd1, 0x97, 0xd0, 0x2b, 0x41,
0x91, 0x64, 0x52, 0x2d, 0xcf, 0x7d, 0x70, 0x6d, 0x7d, 0xa6, 0xb0, 0x65, 0x26, 0x8c, 0xc6, 0x5a,
0x31, 0xea, 0x5b, 0x23, 0x23, 0xce, 0xf5, 0x8f, 0x01, 0xac, 0xfe, 0xfd, 0x68, 0x27, 0xb0, 0xe5,
0x19, 0xb9, 0xc5, 0x3b, 0xa8, 0xb8, 0x91, 0x2c, 0x17, 0x53, 0x0f, 0xfa, 0x88, 0xe7, 0xa7, 0xa5,
0x48, 0x96, 0xbe, 0xf8, 0x95, 0x3c, 0x81, 0x86, 0x96, 0xa1, 0xb7, 0x7f, 0x85, 0x47, 0x51, 0x79,
0xbe, 0xd4, 0xaa, 0xf3, 0x65, 0x07, 0xda, 0xe6, 0xa5, 0x0a, 0x39, 0xaa, 0x8f, 0xeb, 0xfa, 0xad,
0xe4, 0x34, 0xfd, 0xd3, 0xb1, 0x97, 0xc7, 0xa4, 0x5e, 0x54, 0xd4, 0x79, 0xb0, 0xa2, 0x64, 0x0a,
0xed, 0x44, 0xb8, 0xc2, 0x8f, 0x95, 0x4e, 0xa4, 0x5c, 0x44, 0x66, 0xd8, 0x47, 0x5c, 0x71, 0xb6,
0xd6, 0x21, 0x8f, 0xa1, 0x76, 0x7a, 0x89, 0x91, 0x8b, 0x36, 0x9f, 0x8a, 0xec, 0x92, 0x2f, 0x52,
0xc1, 0x6a, 0xa7, 0x97, 0xe4, 0x19, 0x0c, 0xe2, 0x44, 0x2c, 0xcf, 0x15, 0x57, 0xa9, 0x2c, 0x4d,
0x91, 0x0d, 0x2e, 0x7d, 0x01, 0x6d, 0x96, 0x3b, 0xdd, 0x2d, 0x81, 0x30, 0x4d, 0x19, 0x54, 0x41,
0x14, 0x00, 0xe8, 0x2b, 0xe8, 0x9c, 0x25, 0xfe, 0x92, 0xbb, 0xd9, 0xe9, 0x25, 0xf9, 0x56, 0x07,
0xb3, 0xc4, 0x45, 0x74, 0x2b, 0x42, 0x6b, 0xfe, 0xa1, 0x35, 0x3f, 0xab, 0x08, 0xd9, 0x86, 0x32,
0xcd, 0x60, 0x50, 0xd5, 0x20, 0x43, 0x68, 0x2a, 0xeb, 0x47, 0xb7, 0xda, 0x10, 0xa6, 0x1d, 0x27,
0xe1, 0x5c, 0xac, 0xb0, 0x1d, 0x4d, 0x96, 0x93, 0x66, 0x8c, 0x7a, 0x95, 0x31, 0x8a, 0x23, 0xdf,
0x94, 0xa9, 0xf1, 0x60, 0x99, 0xa8, 0x84, 0x61, 0x9e, 0xfe, 0xf7, 0xe1, 0xbc, 0xc8, 0xe8, 0x8b,
0x4a, 0x29, 0x9c, 0x92, 0x79, 0xae, 0x5e, 0x6a, 0xc6, 0x14, 0x3a, 0xeb, 0x8c, 0xec, 0x35, 0xdc,
0xde, 0xcc, 0x9c, 0x15, 0x2a, 0x74, 0x02, 0xc4, 0x7a, 0x99, 0x79, 0xc2, 0xbd, 0xbd, 0x58, 0xbd,
0xf6, 0x25, 0xae, 0x2c, 0x91, 0x24, 0xa6, 0xf2, 0x1d, 0x86, 0x67, 0x9a, 0x41, 0x77, 0xa6, 0x17,
0xb9, 0x69, 0x18, 0x79, 0x0a, 0x7d, 0x37, 0x4d, 0x70, 0x79, 0x98, 0x41, 0x6c, 0x66, 0x4b, 0x95,
0x49, 0xc6, 0xd0, 0x0d, 0x44, 0x10, 0x47, 0xd1, 0xe2, 0xdc, 0xff, 0x4d, 0xd8, 0x9b, 0x5b, 0x66,
0x11, 0x0a, 0xbd, 0x40, 0xde, 0xfc, 0x9c, 0x8a, 0x54, 0xa0, 0x4a, 0x1d, 0x55, 0x2a, 0x3c, 0xca,
0xa1, 0xc3, 0xc4, 0x9d, 0x1d, 0xbf, 0x43, 0x68, 0x4a, 0xc5, 0x93, 0x3c, 0xa0, 0x21, 0xf4, 0x73,
0x14, 0xe1, 0xdc, 0x06, 0xd0, 0x47, 0xfd, 0x2c, 0x7c, 0x79, 0x54, 0x8c, 0xae, 0x36, 0x5b, 0xd3,
0xf9, 0xe3, 0x6d, 0x60, 0x7a, 0xfa, 0x48, 0x9f, 0x40, 0xf7, 0xc7, 0x12, 0x2a, 0x02, 0x0d, 0xa9,
0xd1, 0x98, 0x18, 0x78, 0xa6, 0xbb, 0xb0, 0xcd, 0x44, 0xbc, 0xc8, 0x10, 0x87, 0xcd, 0xaf, 0xd8,
0x7e, 0x4e, 0x79, 0xfb, 0xd1, 0x3f, 0x1c, 0x3b, 0x0a, 0x0f, 0xa3, 0x79, 0x96, 0x6f, 0x18, 0xe7,
0x9d, 0x1b, 0xe6, 0xbd, 0xdf, 0x5d, 0x79, 0x47, 0xd6, 0xdf, 0xb9, 0x23, 0x1b, 0x9b, 0x3b, 0x92,
0x3e, 0x07, 0x38, 0x91, 0x33, 0x9e, 0xde, 0x78, 0xea, 0x6d, 0xac, 0xb5, 0x4f, 0xa4, 0x8b, 0x54,
0x1a, 0x63, 0x26, 0x6d, 0x56, 0xe2, 0xd0, 0x97, 0x30, 0x38, 0x91, 0x6f, 0x54, 0x3c, 0xc3, 0xe1,
0x9d, 0x85, 0xae, 0x7e, 0xd2, 0xbe, 0x0c, 0x55, 0xec, 0x62, 0x4f, 0xb2, 0xd0, 0xb5, 0x56, 0x1b,
0x5c, 0xfa, 0xbb, 0x03, 0x7d, 0xbc, 0x35, 0x3f, 0xac, 0x84, 0x9b, 0xaa, 0x28, 0xd1, 0x15, 0x9b,
0x27, 0xfe, 0x52, 0x24, 0xf6, 0x3d, 0x59, 0x4a, 0x67, 0x73, 0x9d, 0x86, 0xee, 0x1b, 0xbd, 0x27,
0xcd, 0x52, 0x5c, 0xd3, 0xd5, 0x1f, 0x48, 0x7d, 0xf3, 0x07, 0x32, 0x84, 0x66, 0xcc, 0x13, 0x1e,
0xd8, 0xa9, 0x62, 0x08, 0xcd, 0x15, 0x2b, 0x95, 0x70, 0xfc, 0x96, 0xf4, 0x98, 0x21, 0xe8, 0xd7,
0x76, 0xf2, 0xe6, 0x3b, 0x4e, 0x37, 0x1a, 0xbd, 0x3a, 0xe6, 0x73, 0x86, 0x0e, 0x09, 0x34, 0x2e,
0xb2, 0x38, 0xbf, 0xad, 0x78, 0xa6, 0xdf, 0xc0, 0xa0, 0x62, 0xa8, 0x27, 0x54, 0x65, 0x67, 0xdc,
0xbf, 0x42, 0xed, 0xea, 0xf0, 0x60, 0x78, 0xc6, 0x13, 0x8e, 0x95, 0x28, 0x8f, 0xe3, 0xaf, 0xa0,
0x8b, 0x33, 0xd7, 0x6e, 0x58, 0xe7, 0xc1, 0x0d, 0x5b, 0x56, 0xd3, 0xa5, 0x92, 0x36, 0x80, 0xc5,
0xb8, 0xa6, 0x0f, 0x1f, 0xff, 0xf2, 0xc9, 0x8d, 0xaf, 0xbc, 0xf4, 0x6a, 0xea, 0x46, 0xc1, 0xde,
0xc1, 0x81, 0x1b, 0xee, 0xe1, 0xf7, 0xfb, 0xe0, 0x60, 0x0f, 0xbd, 0x5e, 0xb5, 0xf0, 0x7f, 0x7d,
0xf0, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4b, 0xd8, 0x21, 0x5f, 0x9b, 0x0b, 0x00, 0x00,
// 1287 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xdd, 0x6e, 0x1b, 0xc5,
0x17, 0xd7, 0xfa, 0x23, 0xb1, 0x8f, 0xed, 0xfc, 0xd3, 0xf9, 0x1b, 0x64, 0x45, 0x40, 0xdd, 0xa1,
0x14, 0x53, 0x8a, 0x8b, 0x1a, 0x54, 0x2a, 0x04, 0x12, 0x24, 0x45, 0x6a, 0x9a, 0x52, 0xc2, 0xc4,
0xcd, 0x05, 0x77, 0xdb, 0xf5, 0x24, 0x5e, 0xd5, 0xde, 0xdd, 0xec, 0xcc, 0x1a, 0x9b, 0x47, 0x40,
0xe2, 0x11, 0x78, 0x01, 0xc4, 0x3b, 0xf1, 0x2a, 0xe8, 0x9c, 0x99, 0xf1, 0x7e, 0x90, 0x14, 0x7a,
0xc9, 0xdd, 0x9c, 0xaf, 0x39, 0xbf, 0xf9, 0xcd, 0x9c, 0x73, 0x76, 0x61, 0xf7, 0xe5, 0x3c, 0x0e,
0x5e, 0x05, 0x33, 0x3f, 0x8c, 0xc6, 0x49, 0x1a, 0xeb, 0x98, 0x35, 0xf5, 0x3a, 0x91, 0x6a, 0xef,
0x86, 0x4e, 0xfd, 0x48, 0xf9, 0x81, 0x0e, 0x63, 0x6b, 0xd9, 0xeb, 0x06, 0xf1, 0x62, 0xe1, 0x24,
0xfe, 0x47, 0x0d, 0xb6, 0x9e, 0x48, 0x7f, 0x2a, 0x53, 0x36, 0x80, 0xed, 0xa5, 0x4c, 0x55, 0x18,
0x47, 0x03, 0x6f, 0xe8, 0x8d, 0xea, 0xc2, 0x89, 0xec, 0x3d, 0x80, 0xc4, 0x4f, 0x65, 0xa4, 0x9f,
0xf8, 0x6a, 0x36, 0xa8, 0x0d, 0xbd, 0x51, 0x57, 0x14, 0x34, 0xec, 0x6d, 0xd8, 0xd2, 0x2b, 0xb2,
0xd5, 0xc9, 0x66, 0x25, 0xf6, 0x0e, 0xb4, 0x95, 0xf6, 0xb5, 0x24, 0x53, 0x83, 0x4c, 0xb9, 0x02,
0xa3, 0x66, 0x32, 0xbc, 0x98, 0xe9, 0x41, 0x93, 0xd2, 0x59, 0x09, 0xa3, 0xe8, 0x38, 0x93, 0x70,
0x21, 0x07, 0x5b, 0x64, 0xca, 0x15, 0x88, 0x52, 0xaf, 0x0e, 0xe3, 0x2c, 0xd2, 0x83, 0xb6, 0x41,
0x69, 0x45, 0xc6, 0xa0, 0x31, 0xc3, 0x44, 0x40, 0x89, 0x68, 0x8d, 0xc8, 0xa7, 0xe1, 0xf9, 0x79,
0x18, 0x64, 0x73, 0xbd, 0x1e, 0x74, 0x86, 0xde, 0xa8, 0x27, 0x0a, 0x1a, 0x36, 0x86, 0xb6, 0x0a,
0x2f, 0x22, 0x5f, 0x67, 0xa9, 0x1c, 0xb4, 0x86, 0xde, 0xa8, 0xf3, 0x60, 0x77, 0x4c, 0xd4, 0x8d,
0x4f, 0x9d, 0x5e, 0xe4, 0x2e, 0xfc, 0xcf, 0x1a, 0x34, 0x0f, 0x10, 0xcb, 0x7f, 0x84, 0xad, 0x7f,
0x3a, 0xff, 0x1e, 0xb4, 0x16, 0x7e, 0x18, 0x51, 0xca, 0x2e, 0xa5, 0xdc, 0xc8, 0x18, 0x4b, 0x6b,
0x93, 0xb5, 0x47, 0x5b, 0x17, 0x34, 0x6f, 0xca, 0x1d, 0xbb, 0x0d, 0x75, 0xbd, 0x52, 0x83, 0xed,
0x61, 0x7d, 0xd4, 0x79, 0xc0, 0xac, 0xe7, 0x24, 0x7f, 0x9f, 0x02, 0xcd, 0xfc, 0x1e, 0x6c, 0x11,
0xc1, 0x8a, 0x71, 0x68, 0x86, 0x5a, 0x2e, 0xd4, 0xc0, 0xa3, 0x88, 0xae, 0x8d, 0x20, 0xab, 0x30,
0x26, 0xfe, 0x14, 0x80, 0xe4, 0x53, 0x79, 0x79, 0x78, 0x80, 0x2f, 0x20, 0xf2, 0x17, 0x92, 0x2e,
0xa4, 0x2d, 0x68, 0xcd, 0x76, 0xa1, 0xfe, 0x42, 0x3c, 0xa3, 0x6b, 0x68, 0x0b, 0x5c, 0x22, 0x93,
0x32, 0x0a, 0xe2, 0xa9, 0x24, 0xfe, 0xdb, 0xc2, 0x4a, 0xfc, 0x21, 0x74, 0xf2, 0xbd, 0x14, 0xfb,
0xb0, 0x9c, 0xfe, 0x46, 0x31, 0x3d, 0xb9, 0x38, 0x0c, 0x09, 0xb4, 0x9c, 0x12, 0xb3, 0x45, 0xd9,
0xc2, 0xbe, 0x08, 0x5c, 0xb2, 0x3b, 0x50, 0x57, 0xf2, 0x92, 0xf2, 0x77, 0x1e, 0xf4, 0x2b, 0x9b,
0x64, 0x32, 0x0a, 0xa4, 0x40, 0x07, 0x76, 0x17, 0xb6, 0xa6, 0x52, 0xfb, 0xe1, 0x9c, 0x50, 0xe5,
0x04, 0x91, 0xeb, 0x63, 0xb2, 0x08, 0xeb, 0xc1, 0x3f, 0x85, 0xb6, 0xdb, 0x41, 0xb1, 0xf7, 0xa1,
0xa1, 0xe4, 0xa5, 0x83, 0xf9, 0xbf, 0x4a, 0x06, 0x41, 0x46, 0xfe, 0xb5, 0xc5, 0x78, 0x12, 0x4e,
0x11, 0x63, 0x12, 0x4e, 0x2d, 0x49, 0xb8, 0x44, 0xa6, 0xe9, 0xc9, 0x58, 0x94, 0x15, 0xa6, 0xc9,
0xc4, 0x1f, 0x41, 0xb7, 0x00, 0x45, 0xb1, 0x51, 0x99, 0x9e, 0xab, 0xe0, 0x5a, 0x7e, 0xc6, 0xb0,
0x6d, 0x3a, 0x0c, 0x62, 0x2d, 0x05, 0xf5, 0x6c, 0x90, 0x31, 0x3b, 0xff, 0x27, 0x00, 0xd6, 0xff,
0x6a, 0xb4, 0x23, 0xd8, 0x9e, 0x19, 0xbb, 0xc5, 0xbb, 0x53, 0xda, 0x46, 0x09, 0x67, 0xe6, 0x33,
0xe8, 0x11, 0x9e, 0xef, 0x97, 0x32, 0x5d, 0x86, 0xf2, 0x27, 0x76, 0x0b, 0x1a, 0x68, 0xa3, 0xdd,
0xfe, 0x96, 0x9e, 0x4c, 0xc5, 0xfe, 0x52, 0x2b, 0xf7, 0x97, 0x3d, 0x68, 0x99, 0x4a, 0x95, 0x6a,
0x50, 0x1f, 0xd6, 0xb1, 0x56, 0x9c, 0xcc, 0x7f, 0xf7, 0xec, 0xe3, 0x31, 0x47, 0xcf, 0x19, 0xf5,
0xae, 0x65, 0x94, 0x8d, 0xa1, 0x95, 0xca, 0x40, 0x86, 0x89, 0xc6, 0x83, 0x14, 0x49, 0x14, 0x46,
0xfd, 0xd8, 0xd7, 0xbe, 0xd8, 0xf8, 0xb0, 0x9b, 0x50, 0x3b, 0x3e, 0xa3, 0xcc, 0xf9, 0x35, 0x1f,
0xcb, 0xf5, 0x99, 0x3f, 0xcf, 0xa4, 0xa8, 0x1d, 0x9f, 0xb1, 0x3b, 0xb0, 0x93, 0xa4, 0x72, 0x79,
0xaa, 0x7d, 0x9d, 0xa9, 0x42, 0x17, 0xa9, 0x68, 0xf9, 0x43, 0x68, 0x09, 0xb7, 0xe9, 0xdd, 0x02,
0x08, 0x73, 0x29, 0x3b, 0x65, 0x10, 0x39, 0x00, 0xfe, 0x14, 0xda, 0x27, 0x69, 0xb8, 0xf4, 0x83,
0xf5, 0xf1, 0x19, 0xfb, 0x0a, 0x93, 0x59, 0x61, 0x12, 0xbf, 0x92, 0x91, 0x0d, 0x7f, 0xcb, 0x86,
0x9f, 0x94, 0x8c, 0xa2, 0xe2, 0xcc, 0xd7, 0xb0, 0x53, 0xf6, 0x60, 0x7d, 0x68, 0x6a, 0xbb, 0x0f,
0x5e, 0xb5, 0x11, 0xcc, 0x75, 0x1c, 0x45, 0x53, 0xb9, 0xa2, 0xeb, 0x68, 0x0a, 0x27, 0x9a, 0x36,
0x3a, 0x2b, 0xb5, 0x51, 0x6a, 0xf9, 0x86, 0xa6, 0xc6, 0xb5, 0x34, 0x71, 0x05, 0x7d, 0x77, 0xfc,
0x6f, 0xa2, 0x69, 0x7e, 0xa2, 0x8f, 0x4b, 0x54, 0x78, 0x85, 0x70, 0xe7, 0x5e, 0xb8, 0x8c, 0x31,
0xb4, 0x37, 0x27, 0xb2, 0xcf, 0x70, 0xb7, 0x7a, 0x72, 0x91, 0xbb, 0xf0, 0x11, 0x30, 0xbb, 0xcb,
0xe1, 0x4c, 0x06, 0xaf, 0x26, 0xab, 0x67, 0xa1, 0xa2, 0x91, 0x25, 0xd3, 0xd4, 0x30, 0xdf, 0x16,
0xb4, 0xe6, 0x6b, 0xe8, 0x1c, 0xe2, 0x20, 0x37, 0x17, 0xc6, 0x6e, 0x43, 0x2f, 0xc8, 0x52, 0x1a,
0x1e, 0xa6, 0x11, 0x9b, 0xde, 0x52, 0x56, 0xb2, 0x21, 0x74, 0x16, 0x72, 0x91, 0xc4, 0xf1, 0xfc,
0x34, 0xfc, 0x59, 0xda, 0x97, 0x5b, 0x54, 0x31, 0x0e, 0xdd, 0x85, 0xba, 0xf8, 0x21, 0x93, 0x99,
0x24, 0x97, 0x3a, 0xb9, 0x94, 0x74, 0xdc, 0x87, 0xb6, 0x90, 0x97, 0xb6, 0xfd, 0xf6, 0xa1, 0xa9,
0xb4, 0x9f, 0xba, 0x84, 0x46, 0xc0, 0x72, 0x94, 0xd1, 0xd4, 0x26, 0xc0, 0x25, 0x96, 0x45, 0xa8,
0x1e, 0xe7, 0xad, 0xab, 0x25, 0x36, 0xb2, 0x2b, 0xde, 0x06, 0x1d, 0x0f, 0x97, 0xfc, 0x16, 0x74,
0xbe, 0x2b, 0xa0, 0x62, 0xd0, 0x50, 0x88, 0xc6, 0xe4, 0xa0, 0x35, 0xbf, 0x0b, 0xbb, 0x42, 0x26,
0xf3, 0x35, 0xe1, 0xb0, 0xe7, 0xcb, 0xa7, 0x9f, 0x57, 0x9c, 0x7e, 0xfc, 0x37, 0xcf, 0xb6, 0xc2,
0x83, 0x78, 0xba, 0x76, 0x13, 0xc6, 0x7b, 0xed, 0x84, 0x79, 0xe3, 0xba, 0x2b, 0xce, 0xc8, 0xfa,
0x6b, 0x67, 0x64, 0xa3, 0x3a, 0x23, 0xf9, 0x3d, 0x80, 0x23, 0x75, 0xe8, 0x67, 0x17, 0x33, 0xfd,
0x22, 0x41, 0xef, 0x23, 0x15, 0x90, 0x94, 0x25, 0x74, 0x92, 0x96, 0x28, 0x68, 0xf8, 0x23, 0xd8,
0x39, 0x52, 0xcf, 0x75, 0x72, 0x48, 0xcd, 0x7b, 0x1d, 0x05, 0x58, 0xd2, 0xa1, 0x8a, 0x74, 0x12,
0xd0, 0x9d, 0xac, 0xa3, 0xc0, 0x46, 0x55, 0xb4, 0xfc, 0x57, 0x0f, 0x7a, 0xf4, 0x6a, 0xbe, 0x5d,
0xc9, 0x20, 0xd3, 0x71, 0x8a, 0x8c, 0x4d, 0xd3, 0x70, 0x29, 0x53, 0x5b, 0x4f, 0x56, 0xc2, 0xd3,
0x9c, 0x67, 0x51, 0xf0, 0x1c, 0xe7, 0xa4, 0x19, 0x8a, 0x1b, 0xb9, 0xfc, 0x05, 0x52, 0xaf, 0x7e,
0x81, 0xf4, 0xa1, 0x99, 0xf8, 0xa9, 0xbf, 0xb0, 0x5d, 0xc5, 0x08, 0xa8, 0x95, 0x2b, 0x9d, 0xfa,
0xf4, 0x59, 0xd2, 0x15, 0x46, 0xe0, 0x9f, 0xdb, 0xce, 0xeb, 0x66, 0x1c, 0x5e, 0x34, 0xed, 0xea,
0x99, 0x8f, 0x33, 0xda, 0x90, 0x41, 0x63, 0xb2, 0x4e, 0xdc, 0x6b, 0xa5, 0x35, 0xff, 0x12, 0x76,
0x4a, 0x81, 0xd8, 0xa1, 0x4a, 0x33, 0xe3, 0xea, 0x11, 0x6a, 0x47, 0xc7, 0x0c, 0xfa, 0x27, 0x7e,
0xea, 0x13, 0x13, 0xc5, 0x76, 0xfc, 0x19, 0x74, 0xa8, 0xe7, 0xda, 0x09, 0xeb, 0x5d, 0x3b, 0x61,
0x8b, 0x6e, 0x48, 0x95, 0xb2, 0x09, 0x2c, 0xc6, 0x8d, 0xcc, 0xbf, 0x80, 0x1e, 0x66, 0x9a, 0xac,
0xdc, 0x3c, 0xfc, 0xa8, 0x0c, 0xf3, 0xff, 0xae, 0x19, 0x14, 0x9c, 0x1c, 0xca, 0x15, 0x74, 0x8b,
0x6a, 0xe4, 0x01, 0x9d, 0x5d, 0x11, 0xe0, 0x9a, 0x7d, 0x80, 0x0f, 0x1e, 0xc7, 0x92, 0x6d, 0x2e,
0x95, 0x59, 0x65, 0x8d, 0xec, 0x13, 0x68, 0x6b, 0x07, 0xa1, 0x32, 0x1a, 0x36, 0x59, 0x73, 0x0f,
0xfe, 0x8b, 0x07, 0xad, 0x4d, 0xda, 0x3e, 0x34, 0x43, 0x6a, 0xac, 0x1e, 0x7d, 0x16, 0x1a, 0x81,
0x71, 0xa8, 0xe9, 0x95, 0x4d, 0x7a, 0x55, 0x09, 0xd5, 0xf4, 0x8a, 0xdd, 0x83, 0x6d, 0x5b, 0x1d,
0x95, 0x8f, 0x95, 0x62, 0x01, 0x39, 0x17, 0x7c, 0x89, 0x49, 0x1a, 0xc7, 0xe7, 0x8a, 0xfa, 0x40,
0x57, 0x58, 0x89, 0x9f, 0x60, 0x9d, 0x5f, 0x1a, 0x26, 0x0e, 0xd6, 0x93, 0x50, 0xcf, 0xe5, 0xbf,
0x6e, 0x3a, 0x38, 0x2c, 0x30, 0xc0, 0x7e, 0xc2, 0x19, 0xe1, 0xe0, 0xe6, 0x8f, 0xef, 0x5e, 0x84,
0x7a, 0x96, 0xbd, 0x1c, 0x07, 0xf1, 0xe2, 0xfe, 0xfe, 0x7e, 0x10, 0xdd, 0xa7, 0x7f, 0xa2, 0xfd,
0xfd, 0xfb, 0x84, 0xef, 0xe5, 0x16, 0xfd, 0xf4, 0xec, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0x00,
0x7f, 0xd3, 0xa9, 0x30, 0x0d, 0x00, 0x00,
}
......@@ -165,6 +165,9 @@ const (
//其他模块读写blockchain db事件
EventSetValueByKey = 304
EventGetValueByKey = 305
//通过平行链title获取平行链的交易
EventGetParaTxByTitle = 306
EventReplyParaTxByTitle = 307
)
var eventName = map[int]string{
......@@ -318,4 +321,6 @@ var eventName = map[int]string{
EventReplyMainSeqByHash: "EventReplyMainSeqByHash",
EventSetValueByKey: "EventSetValueByKey",
EventGetValueByKey: "EventGetValueByKey",
EventGetParaTxByTitle: "EventGetParaTxByTitle",
EventReplyParaTxByTitle: "EventReplyParaTxByTitle",
}
......@@ -732,6 +732,36 @@ func (_m *Chain33Client) GetMemPool(ctx context.Context, in *types.ReqGetMempool
return r0, r1
}
// GetParaTxByTitle provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetParaTxByTitle(ctx context.Context, in *types.ReqParaTxByTitle, opts ...grpc.CallOption) (*types.ParaTxDetails, error) {
_va := make([]interface{}, len(opts))
for _i := range opts {
_va[_i] = opts[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, in)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
var r0 *types.ParaTxDetails
if rf, ok := ret.Get(0).(func(context.Context, *types.ReqParaTxByTitle, ...grpc.CallOption) *types.ParaTxDetails); ok {
r0 = rf(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*types.ParaTxDetails)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *types.ReqParaTxByTitle, ...grpc.CallOption) error); ok {
r1 = rf(ctx, in, opts...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetPeerInfo provides a mock function with given fields: ctx, in, opts
func (_m *Chain33Client) GetPeerInfo(ctx context.Context, in *types.ReqNil, opts ...grpc.CallOption) (*types.PeerList, error) {
_va := make([]interface{}, len(opts))
......
......@@ -206,4 +206,37 @@ message BlockSequences {
message ParaChainBlockDetail {
BlockDetail blockdetail = 1;
int64 sequence = 2;
}
\ No newline at end of file
}
// 定义para交易结构
message ParaTxDetails {
repeated ParaTxDetail items = 1;
}
// type:平行链交易所在区块add/del操作,方便平行链回滚
// header:平行链交易所在区块头信息
// txDetails:本区块中指定title平行链的所有交易
message ParaTxDetail {
int64 type = 1;
Header header = 2;
repeated TxDetail txDetails = 3;
}
//交易的详情:
// index:本交易在block中索引值,用于proof的证明
// tx:本交易内容
// receipt:本交易在主链的执行回执
// proofs:本交易hash在block中merkel中的路径
message TxDetail {
uint32 index = 1;
Transaction tx = 2;
ReceiptData receipt = 3;
repeated bytes proofs = 4;
}
//通过seq区间和title请求平行链的交易
message ReqParaTxByTitle {
int64 start = 1;
int64 end = 2;
string title = 3;
}
......@@ -147,4 +147,6 @@ service chain33 {
// 获取是否达到fork高度
rpc GetFork(ReqKey) returns (Int64) {}
//通过seq以及title获取对应平行连的交易
rpc GetParaTxByTitle(ReqParaTxByTitle) returns (ParaTxDetails) {}
}
......@@ -26,74 +26,76 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
func init() { proto.RegisterFile("rpc.proto", fileDescriptor_77a6da22d6a3feb1) }
var fileDescriptor_77a6da22d6a3feb1 = []byte{
// 1070 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xdf, 0x6f, 0xdb, 0x36,
0x10, 0xd6, 0xc3, 0xd6, 0x34, 0xac, 0x93, 0x38, 0x4c, 0x1a, 0xb4, 0xc2, 0x8a, 0x02, 0x02, 0x86,
0x0d, 0x18, 0x6a, 0xb7, 0xf6, 0x9a, 0xfd, 0xe8, 0x36, 0x20, 0x4e, 0x66, 0xc7, 0x58, 0xea, 0xb9,
0x91, 0xbb, 0x01, 0x7b, 0xa3, 0xe5, 0x9b, 0x23, 0x44, 0x26, 0x65, 0x92, 0x8a, 0xed, 0x3f, 0x7c,
0xef, 0x03, 0x29, 0x51, 0xbf, 0x9d, 0xe4, 0x4d, 0xfc, 0xee, 0xbe, 0xe3, 0x91, 0xfc, 0xee, 0x4e,
0x68, 0x97, 0x87, 0x5e, 0x2b, 0xe4, 0x4c, 0x32, 0xfc, 0xa5, 0xdc, 0x84, 0x20, 0xec, 0x86, 0xc7,
0x16, 0x0b, 0x46, 0x63, 0xd0, 0x3e, 0x94, 0x9c, 0x50, 0x41, 0x3c, 0xe9, 0xa7, 0x50, 0x73, 0x1a,
0x30, 0xef, 0xd6, 0xbb, 0x21, 0xbe, 0x41, 0x1a, 0x2b, 0x12, 0x04, 0x20, 0x93, 0xd5, 0x6e, 0xd8,
0x09, 0x93, 0xcf, 0x3d, 0xe2, 0x79, 0x2c, 0xa2, 0xc6, 0xb2, 0x0f, 0x6b, 0xf0, 0x22, 0xc9, 0x78,
0xbc, 0xee, 0xfc, 0x77, 0x82, 0x76, 0x74, 0x9c, 0x6e, 0x17, 0xbf, 0x41, 0xbb, 0x03, 0x90, 0x3d,
0x15, 0x5a, 0xe0, 0x66, 0x4b, 0xe7, 0xd2, 0xba, 0x86, 0x65, 0x8c, 0xd8, 0x8d, 0x14, 0x09, 0x83,
0x8d, 0x63, 0xe1, 0x36, 0xda, 0x1b, 0x80, 0xbc, 0x22, 0x42, 0x5e, 0x02, 0x99, 0x01, 0xc7, 0x7b,
0x19, 0x65, 0xe4, 0x07, 0xb6, 0x59, 0xc6, 0x56, 0xc7, 0xc2, 0x3f, 0xa3, 0xe3, 0x73, 0x0e, 0x44,
0xc2, 0x35, 0x59, 0x4d, 0xb2, 0x33, 0xe1, 0x83, 0xc4, 0x31, 0x36, 0x4e, 0xd6, 0xb6, 0x01, 0x3e,
0x53, 0xe1, 0xcf, 0xe9, 0x64, 0xed, 0x58, 0xf8, 0x02, 0x35, 0x33, 0xee, 0x7a, 0xc0, 0x59, 0x14,
0xe2, 0x57, 0x45, 0x5e, 0x16, 0x51, 0x9b, 0xeb, 0xa2, 0xfc, 0x86, 0x9a, 0x9f, 0x22, 0xe0, 0x9b,
0xfc, 0xee, 0xfb, 0x59, 0xd6, 0x97, 0x44, 0xdc, 0xd8, 0x2f, 0x92, 0x75, 0xce, 0xe7, 0x02, 0x24,
0xf1, 0x03, 0xc7, 0xc2, 0xef, 0xd1, 0x81, 0x0b, 0x74, 0x96, 0xa7, 0xe3, 0xaa, 0x7b, 0xe5, 0xa6,
0x7e, 0x45, 0xc7, 0x03, 0x90, 0x39, 0x8f, 0xde, 0xe6, 0x6c, 0x36, 0xe3, 0xf9, 0xad, 0xd5, 0xda,
0x3e, 0xca, 0xf3, 0x26, 0xeb, 0x21, 0xfd, 0x97, 0x09, 0xc7, 0xc2, 0x03, 0x74, 0x52, 0xa6, 0xab,
0x4c, 0xa1, 0xf0, 0x48, 0x31, 0x62, 0xbf, 0xdc, 0x96, 0xbd, 0x0a, 0xf4, 0x23, 0x42, 0x03, 0x90,
0x1f, 0x61, 0x31, 0x66, 0x2c, 0xc0, 0xc7, 0x19, 0x39, 0x46, 0x43, 0xc6, 0x02, 0x1b, 0x17, 0x73,
0xb8, 0xf2, 0x85, 0xd4, 0x07, 0x7f, 0x36, 0x00, 0x79, 0x16, 0x4b, 0x49, 0x94, 0x5f, 0xfa, 0x79,
0xb2, 0xfc, 0x5b, 0x6b, 0xd0, 0x78, 0xe9, 0x17, 0x47, 0x23, 0x58, 0x25, 0x40, 0x7e, 0xc3, 0x0c,
0xb5, 0x8f, 0xeb, 0xc8, 0x8e, 0x85, 0xaf, 0xd1, 0xf3, 0x18, 0xca, 0x1d, 0x45, 0x65, 0x83, 0x5f,
0x67, 0x61, 0x6a, 0x1d, 0xec, 0x93, 0x42, 0xc4, 0xc9, 0x3a, 0xbb, 0x80, 0x3e, 0xda, 0x1b, 0x2e,
0x42, 0xc6, 0xe5, 0x98, 0xfb, 0x77, 0xb7, 0xb0, 0x49, 0x25, 0x94, 0xc6, 0x2a, 0x98, 0xb7, 0xe6,
0xd6, 0x43, 0x7b, 0x5a, 0x07, 0x4c, 0x3d, 0x1b, 0x08, 0x51, 0x8d, 0x53, 0x30, 0xdb, 0xcd, 0xfc,
0xa5, 0xaa, 0x97, 0x72, 0x2c, 0xdc, 0x41, 0x4f, 0x5d, 0x95, 0x5d, 0x1f, 0x00, 0x9f, 0x54, 0xe9,
0xb2, 0x0f, 0x50, 0x11, 0xd2, 0x07, 0xb4, 0xe3, 0xaa, 0x92, 0x9b, 0x06, 0xf8, 0x45, 0x0d, 0xe5,
0x8a, 0x4c, 0x21, 0xb8, 0x27, 0xe9, 0xc6, 0x47, 0xe0, 0x73, 0xe8, 0x91, 0x80, 0x50, 0x0f, 0xf0,
0x57, 0xe5, 0x08, 0x79, 0x6b, 0x51, 0x07, 0xb1, 0xb8, 0x1c, 0x0b, 0x9f, 0xa2, 0x5d, 0x17, 0xe4,
0x98, 0x08, 0xb1, 0x9a, 0xe1, 0x97, 0x35, 0x29, 0xc4, 0xa6, 0x4a, 0xe2, 0x5f, 0xa3, 0x2f, 0xae,
0x98, 0x77, 0x5b, 0x16, 0x4e, 0xd9, 0xed, 0x0d, 0x7a, 0xf2, 0x99, 0x6a, 0xc7, 0xa3, 0xc2, 0x21,
0x62, 0xb0, 0xa6, 0x03, 0x29, 0x55, 0x8e, 0x01, 0xb8, 0x2a, 0x95, 0x72, 0x70, 0x53, 0xff, 0xca,
0x9e, 0xca, 0x78, 0x3f, 0x69, 0x59, 0xa6, 0x08, 0x4a, 0x9c, 0x7a, 0xf5, 0xff, 0x82, 0x1a, 0x6a,
0x1f, 0xce, 0x42, 0xe0, 0xea, 0xb9, 0xb2, 0x3a, 0x5d, 0xa6, 0x60, 0x5a, 0x04, 0x9a, 0x9a, 0xc2,
0x8e, 0x85, 0x7f, 0x40, 0x07, 0x03, 0x90, 0xc9, 0x0d, 0x49, 0x22, 0xa3, 0x4a, 0xfd, 0x14, 0x0f,
0x1b, 0xfb, 0xe8, 0xea, 0x69, 0x9a, 0x7e, 0xfc, 0xe7, 0x1d, 0xf0, 0x3b, 0x1f, 0x56, 0x95, 0x6e,
0x65, 0x1e, 0xbb, 0xe0, 0xa5, 0x4b, 0x5d, 0x6d, 0xaa, 0xf4, 0x57, 0x47, 0x2d, 0x74, 0x9b, 0xbc,
0x93, 0x63, 0xe1, 0x77, 0xfa, 0xb0, 0x3a, 0x9e, 0xda, 0x21, 0x9f, 0xeb, 0x90, 0xca, 0x5a, 0x29,
0xbf, 0x43, 0x3b, 0x03, 0xa0, 0x2e, 0xc0, 0x2c, 0x6d, 0x87, 0xc9, 0xfa, 0x8a, 0xd0, 0x79, 0x91,
0xa2, 0x50, 0x43, 0x91, 0x25, 0x8a, 0x5e, 0xf7, 0x36, 0xe3, 0x55, 0x2d, 0xa5, 0x8d, 0x9e, 0xba,
0xe4, 0x0e, 0x34, 0xc7, 0xe4, 0x6e, 0x00, 0x4d, 0x2a, 0xcb, 0xa3, 0xa3, 0xdb, 0x9d, 0x91, 0xfb,
0x61, 0x6e, 0xa0, 0x25, 0x1a, 0x37, 0x0a, 0xc9, 0x75, 0xac, 0x0e, 0x42, 0x7a, 0x42, 0x9c, 0xab,
0x99, 0x98, 0x76, 0x2c, 0xbd, 0xfa, 0x3d, 0x99, 0x9c, 0x75, 0xfb, 0x28, 0x5b, 0xfc, 0x7a, 0x8f,
0xe4, 0x9c, 0xa2, 0xfd, 0x78, 0x1f, 0x46, 0x05, 0x50, 0x11, 0x89, 0x47, 0xf2, 0x7e, 0x42, 0x87,
0x95, 0x71, 0x97, 0x1e, 0xcd, 0x0c, 0xd0, 0x21, 0xad, 0x1b, 0x7e, 0x6f, 0xb5, 0xf8, 0x2f, 0x61,
0x3d, 0x59, 0xc7, 0x03, 0xa4, 0x22, 0xa6, 0x46, 0x3a, 0xb1, 0xd7, 0x9a, 0xf1, 0x1e, 0x3d, 0xbb,
0x88, 0x16, 0xa1, 0x69, 0x96, 0xb9, 0x69, 0xe3, 0x4a, 0xee, 0xd3, 0x79, 0xb1, 0x5c, 0x62, 0xcc,
0xb1, 0x70, 0x0b, 0xed, 0xfc, 0x05, 0x5c, 0xa8, 0xcc, 0xb6, 0x94, 0x57, 0x62, 0x56, 0x55, 0xeb,
0x58, 0xf8, 0x1b, 0xf4, 0x64, 0x28, 0xdc, 0x0d, 0xf5, 0x1e, 0x6a, 0x0f, 0x6d, 0xb4, 0x3f, 0x14,
0x23, 0x19, 0x9e, 0x2b, 0x71, 0x3e, 0x86, 0xd0, 0x42, 0x3b, 0x23, 0x90, 0x75, 0xcd, 0xc1, 0x64,
0x32, 0x62, 0x33, 0x48, 0x5c, 0xf4, 0x15, 0xa9, 0xaa, 0xe9, 0x13, 0x49, 0x82, 0x3e, 0xf1, 0x83,
0x88, 0xc3, 0xb6, 0x1d, 0x86, 0x54, 0x76, 0x3b, 0xfa, 0x8a, 0x8e, 0x93, 0x8e, 0xa2, 0x2b, 0xc6,
0x85, 0x65, 0x04, 0x4a, 0x6d, 0xdb, 0x69, 0xa7, 0xdf, 0x3b, 0x16, 0xee, 0xa2, 0x43, 0x2d, 0xf7,
0xd8, 0xfb, 0x81, 0xe7, 0x30, 0xa4, 0x0f, 0x59, 0x3f, 0xb8, 0xe7, 0x0f, 0xe0, 0x28, 0xdf, 0x11,
0xb2, 0xd1, 0xf7, 0x56, 0xff, 0xad, 0x25, 0x64, 0x17, 0x96, 0xb8, 0x10, 0x3d, 0xd5, 0x8b, 0x39,
0x85, 0x63, 0xe1, 0xef, 0x10, 0x3a, 0x0f, 0x98, 0x80, 0x4f, 0x11, 0x44, 0xf0, 0xd0, 0x4d, 0xf7,
0xf5, 0x81, 0xce, 0x82, 0x40, 0x29, 0xd7, 0x94, 0x5c, 0x6e, 0x46, 0x15, 0x2d, 0x69, 0xb3, 0x2c,
0xc2, 0x5a, 0xdf, 0xbb, 0xae, 0x3f, 0xa7, 0xfa, 0x2f, 0x2f, 0xdf, 0x67, 0x53, 0xb0, 0xd8, 0x67,
0x53, 0xd8, 0xb1, 0xf0, 0x10, 0xd9, 0x71, 0x01, 0x8c, 0x58, 0x12, 0xaf, 0xee, 0x3f, 0x2d, 0x33,
0xde, 0x13, 0xea, 0x14, 0x35, 0x74, 0x75, 0x5e, 0x13, 0x3a, 0x1b, 0x45, 0x0b, 0x9c, 0xe9, 0x7c,
0xa9, 0x20, 0xfd, 0x3a, 0x75, 0x8d, 0xf0, 0x5b, 0xdd, 0xd5, 0xfa, 0x8c, 0x17, 0x26, 0xdd, 0x1f,
0xb0, 0x29, 0xbf, 0x65, 0xef, 0xf5, 0x3f, 0xaf, 0xe6, 0xbe, 0xbc, 0x89, 0xa6, 0x2d, 0x8f, 0x2d,
0xda, 0xdd, 0xae, 0x47, 0xdb, 0xc9, 0x6f, 0x78, 0x5b, 0x3b, 0x4e, 0x9f, 0xe8, 0xff, 0xf3, 0xee,
0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb4, 0xda, 0xdc, 0x43, 0x1e, 0x0c, 0x00, 0x00,
// 1095 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0x6d, 0x6f, 0xdb, 0x36,
0x10, 0xd6, 0x87, 0x2d, 0x69, 0x58, 0x27, 0x71, 0x98, 0x34, 0x6d, 0x85, 0x15, 0x05, 0x04, 0x0c,
0x1b, 0x30, 0xd4, 0x6e, 0xed, 0x35, 0x7b, 0xe9, 0x36, 0x20, 0x4e, 0x66, 0xc7, 0x58, 0xea, 0xb9,
0x91, 0xbb, 0x01, 0xfb, 0xc6, 0xc8, 0x37, 0x47, 0x88, 0x4c, 0x2a, 0x14, 0x15, 0xdb, 0x7f, 0x6d,
0xbf, 0x6e, 0x20, 0x29, 0x4a, 0x94, 0xa5, 0xbc, 0x7c, 0x13, 0x9f, 0xe3, 0x73, 0x3c, 0xf2, 0x9e,
0xbb, 0x13, 0xda, 0xe2, 0x71, 0xd0, 0x8a, 0x39, 0x13, 0x0c, 0x7f, 0x29, 0x56, 0x31, 0x24, 0x6e,
0x23, 0x60, 0xf3, 0x39, 0xa3, 0x1a, 0x74, 0xf7, 0x04, 0x27, 0x34, 0x21, 0x81, 0x08, 0x73, 0xa8,
0x79, 0x19, 0xb1, 0xe0, 0x3a, 0xb8, 0x22, 0xa1, 0x41, 0x1a, 0x0b, 0x12, 0x45, 0x20, 0xb2, 0xd5,
0x56, 0xdc, 0x89, 0xb3, 0xcf, 0x6d, 0x12, 0x04, 0x2c, 0xa5, 0xc6, 0xb2, 0x03, 0x4b, 0x08, 0x52,
0xc1, 0xb8, 0x5e, 0x77, 0xfe, 0x7b, 0x8e, 0x36, 0x95, 0x9f, 0x6e, 0x17, 0xbf, 0x41, 0x5b, 0x03,
0x10, 0x3d, 0xe9, 0x3a, 0xc1, 0xcd, 0x96, 0x8a, 0xa5, 0x75, 0x01, 0x37, 0x1a, 0x71, 0x1b, 0x39,
0x12, 0x47, 0x2b, 0xcf, 0xc1, 0x6d, 0xb4, 0x3d, 0x00, 0x71, 0x4e, 0x12, 0x71, 0x06, 0x64, 0x0a,
0x1c, 0x6f, 0x17, 0x94, 0x51, 0x18, 0xb9, 0x66, 0xa9, 0xad, 0x9e, 0x83, 0x7f, 0x46, 0x07, 0x27,
0x1c, 0x88, 0x80, 0x0b, 0xb2, 0x98, 0x14, 0x77, 0xc2, 0xbb, 0xd9, 0x46, 0x6d, 0x9c, 0x2c, 0x5d,
0x03, 0x7c, 0xa6, 0x49, 0x38, 0xa3, 0x93, 0xa5, 0xe7, 0xe0, 0x53, 0xd4, 0x2c, 0xb8, 0xcb, 0x01,
0x67, 0x69, 0x8c, 0x5f, 0x95, 0x79, 0x85, 0x47, 0x65, 0xae, 0xf3, 0xf2, 0x1b, 0x6a, 0x7e, 0x4a,
0x81, 0xaf, 0xec, 0xd3, 0x77, 0x8a, 0xa8, 0xcf, 0x48, 0x72, 0xe5, 0xbe, 0xc8, 0xd6, 0xd6, 0x9e,
0x53, 0x10, 0x24, 0x8c, 0x3c, 0x07, 0xbf, 0x47, 0xbb, 0x3e, 0xd0, 0xa9, 0x4d, 0xc7, 0xd5, 0xed,
0x95, 0x97, 0xfa, 0x15, 0x1d, 0x0c, 0x40, 0x58, 0x3b, 0x7a, 0xab, 0xe3, 0xe9, 0x94, 0xdb, 0x47,
0xcb, 0xb5, 0xbb, 0x6f, 0xf3, 0x26, 0xcb, 0x21, 0xfd, 0x97, 0x25, 0x9e, 0x83, 0x07, 0xe8, 0x70,
0x9d, 0x2e, 0x23, 0x85, 0x52, 0x92, 0x34, 0xe2, 0xbe, 0xbc, 0x2b, 0x7a, 0xe9, 0xe8, 0x47, 0x84,
0x06, 0x20, 0x3e, 0xc2, 0x7c, 0xcc, 0x58, 0x84, 0x0f, 0x0a, 0xb2, 0x46, 0x63, 0xc6, 0x22, 0x17,
0x97, 0x63, 0x38, 0x0f, 0x13, 0xa1, 0x2e, 0xfe, 0x74, 0x00, 0xe2, 0x58, 0x4b, 0x29, 0x59, 0xcf,
0xf4, 0xb3, 0x6c, 0xf9, 0xb7, 0xd2, 0xa0, 0xd9, 0xa5, 0x32, 0x8e, 0x46, 0xb0, 0xc8, 0x00, 0xfb,
0xc0, 0x02, 0x75, 0x0f, 0xea, 0xc8, 0x9e, 0x83, 0x2f, 0xd0, 0x33, 0x0d, 0x59, 0x57, 0x91, 0xd1,
0xe0, 0xd7, 0x85, 0x9b, 0xda, 0x0d, 0xee, 0x61, 0xc9, 0xe3, 0x64, 0x59, 0x3c, 0x40, 0x1f, 0x6d,
0x0f, 0xe7, 0x31, 0xe3, 0x62, 0xcc, 0xc3, 0xdb, 0x6b, 0x58, 0xe5, 0x12, 0xca, 0x7d, 0x95, 0xcc,
0x77, 0xc6, 0xd6, 0x43, 0xdb, 0x4a, 0x07, 0x4c, 0xa6, 0x0d, 0x92, 0xa4, 0xea, 0xa7, 0x64, 0x76,
0x9b, 0xf6, 0xa3, 0xca, 0x4c, 0x79, 0x0e, 0xee, 0xa0, 0x27, 0xbe, 0x8c, 0xae, 0x0f, 0x80, 0x0f,
0xab, 0x74, 0xd1, 0x07, 0xa8, 0x08, 0xe9, 0x03, 0xda, 0xf4, 0x65, 0xc9, 0x5d, 0x46, 0xf8, 0x45,
0x0d, 0xe5, 0x9c, 0x5c, 0x42, 0x74, 0x4f, 0xd0, 0x8d, 0x8f, 0xc0, 0x67, 0xd0, 0x23, 0x11, 0xa1,
0x01, 0xe0, 0xaf, 0xd6, 0x3d, 0xd8, 0xd6, 0xb2, 0x0e, 0xb4, 0xb8, 0x3c, 0x07, 0x1f, 0xa1, 0x2d,
0x1f, 0xc4, 0x98, 0x24, 0xc9, 0x62, 0x8a, 0x5f, 0xd6, 0x84, 0xa0, 0x4d, 0x95, 0xc0, 0xbf, 0x46,
0x5f, 0x9c, 0xb3, 0xe0, 0x7a, 0x5d, 0x38, 0xeb, 0xdb, 0xde, 0xa0, 0x8d, 0xcf, 0x54, 0x6d, 0xdc,
0x2f, 0x5d, 0x42, 0x83, 0x35, 0x1d, 0x48, 0xaa, 0x72, 0x0c, 0xc0, 0x65, 0xa9, 0xac, 0x3b, 0x37,
0xf5, 0x2f, 0xed, 0xb9, 0x8c, 0x77, 0xb2, 0x96, 0x65, 0x8a, 0x60, 0x8d, 0x53, 0xaf, 0xfe, 0x5f,
0x50, 0x43, 0x9e, 0xc3, 0x59, 0x0c, 0x5c, 0xa6, 0xab, 0xa8, 0xd3, 0x9b, 0x1c, 0xcc, 0x8b, 0x40,
0x51, 0x73, 0xd8, 0x73, 0xf0, 0x0f, 0x68, 0x77, 0x00, 0x22, 0x7b, 0x21, 0x41, 0x44, 0x5a, 0xa9,
0x9f, 0xf2, 0x65, 0xf5, 0x1e, 0x55, 0x3d, 0x4d, 0xd3, 0x8f, 0xff, 0xbc, 0x05, 0x7e, 0x1b, 0xc2,
0xa2, 0xd2, 0xad, 0x4c, 0xb2, 0x4b, 0xbb, 0x54, 0xa9, 0xcb, 0x43, 0xa5, 0xfe, 0xea, 0xa8, 0xa5,
0x6e, 0x63, 0x6f, 0xf2, 0x1c, 0xfc, 0x4e, 0x5d, 0x56, 0xf9, 0x93, 0x27, 0xd8, 0xb1, 0x0e, 0xa9,
0xa8, 0x95, 0xf2, 0x3b, 0xb4, 0x39, 0x00, 0xea, 0x03, 0x4c, 0xf3, 0x76, 0x98, 0xad, 0xcf, 0x09,
0x9d, 0x95, 0x29, 0x12, 0x35, 0x14, 0xb1, 0x46, 0x51, 0xeb, 0xde, 0x6a, 0xbc, 0xa8, 0xa5, 0xb4,
0xd1, 0x13, 0x9f, 0xdc, 0x82, 0xe2, 0x98, 0xd8, 0x0d, 0xa0, 0x48, 0xeb, 0xf2, 0xe8, 0xa8, 0x76,
0x67, 0xe4, 0xbe, 0x67, 0x0d, 0xb4, 0x4c, 0xe3, 0x46, 0x21, 0x56, 0xc7, 0xea, 0x20, 0xa4, 0x26,
0xc4, 0x89, 0x9c, 0x89, 0x79, 0xc7, 0x52, 0xab, 0xdf, 0xb3, 0xc9, 0x59, 0x77, 0x8e, 0xb4, 0xe9,
0xec, 0x3d, 0x92, 0x73, 0x84, 0x76, 0xf4, 0x39, 0x8c, 0x26, 0x40, 0x93, 0x34, 0x79, 0x24, 0xef,
0x27, 0xb4, 0x57, 0x19, 0x77, 0xf9, 0xd5, 0xcc, 0x00, 0x1d, 0xd2, 0xba, 0xe1, 0xf7, 0x56, 0x89,
0xff, 0x0c, 0x96, 0x93, 0xa5, 0x1e, 0x20, 0x15, 0x31, 0x35, 0xf2, 0x89, 0xbd, 0x54, 0x8c, 0xf7,
0xe8, 0xe9, 0x69, 0x3a, 0x8f, 0x4d, 0xb3, 0xb4, 0xa6, 0x8d, 0x2f, 0x78, 0x48, 0x67, 0xe5, 0x72,
0xd1, 0x98, 0xe7, 0xe0, 0x16, 0xda, 0xfc, 0x0b, 0x78, 0x22, 0x23, 0xbb, 0xa3, 0xbc, 0x32, 0xb3,
0xac, 0x5a, 0xcf, 0xc1, 0xdf, 0xa0, 0x8d, 0x61, 0xe2, 0xaf, 0x68, 0xf0, 0x50, 0x7b, 0x68, 0xa3,
0x9d, 0x61, 0x32, 0x12, 0xf1, 0x89, 0x14, 0xe7, 0x63, 0x08, 0x2d, 0xb4, 0x39, 0x02, 0x51, 0xd7,
0x1c, 0x4c, 0x24, 0x23, 0x36, 0x85, 0x6c, 0x8b, 0x7a, 0x22, 0x59, 0x35, 0x7d, 0x22, 0x48, 0xd4,
0x27, 0x61, 0x94, 0x72, 0xb8, 0xeb, 0x84, 0x21, 0x15, 0xdd, 0x8e, 0x7a, 0xa2, 0x83, 0xac, 0xa3,
0xa8, 0x8a, 0xf1, 0xe1, 0x26, 0x05, 0xa9, 0xb6, 0xbb, 0x69, 0x47, 0xdf, 0x7b, 0x0e, 0xee, 0xa2,
0x3d, 0x25, 0x77, 0xbd, 0xfb, 0x81, 0x74, 0x18, 0xd2, 0x87, 0xa2, 0x1f, 0xdc, 0xf3, 0x07, 0xb0,
0x6f, 0x77, 0x84, 0x62, 0xf4, 0xbd, 0x55, 0x7f, 0x6b, 0x19, 0xd9, 0x87, 0x1b, 0x5c, 0xf2, 0x9e,
0xeb, 0xc5, 0xdc, 0xc2, 0x73, 0xf0, 0x77, 0x08, 0x9d, 0x44, 0x2c, 0x81, 0x4f, 0x29, 0xa4, 0xf0,
0xd0, 0x4b, 0xf7, 0xd5, 0x85, 0x8e, 0xa3, 0x48, 0x2a, 0xd7, 0x94, 0x9c, 0x35, 0xa3, 0xca, 0x96,
0xbc, 0x59, 0x96, 0x61, 0xa5, 0xef, 0x2d, 0x3f, 0x9c, 0x51, 0xf5, 0x97, 0x67, 0xf7, 0xd9, 0x1c,
0x2c, 0xf7, 0xd9, 0x1c, 0xf6, 0x1c, 0x3c, 0x44, 0xae, 0x2e, 0x80, 0x11, 0xcb, 0xfc, 0xd5, 0xfd,
0xa7, 0x15, 0xc6, 0x7b, 0x5c, 0x1d, 0xa1, 0x86, 0xaa, 0xce, 0x0b, 0x42, 0xa7, 0xa3, 0x74, 0x8e,
0x0b, 0x9d, 0xdf, 0x48, 0x48, 0x65, 0xa7, 0xae, 0x11, 0x7e, 0xab, 0xba, 0x5a, 0x9f, 0xf1, 0xd2,
0xa4, 0xfb, 0x03, 0x56, 0x95, 0x5c, 0x9e, 0xa8, 0x5c, 0x8e, 0x09, 0x27, 0xb2, 0x1a, 0x27, 0xa1,
0x88, 0x00, 0x3f, 0xb7, 0xc6, 0x8a, 0x6d, 0xc8, 0x9b, 0xbc, 0x46, 0xf3, 0x9c, 0xf6, 0x5e, 0xff,
0xf3, 0x6a, 0x16, 0x8a, 0xab, 0xf4, 0xb2, 0x15, 0xb0, 0x79, 0xbb, 0xdb, 0x0d, 0x68, 0x3b, 0xfb,
0x97, 0x6f, 0x2b, 0xc2, 0xe5, 0x86, 0xfa, 0xc9, 0xef, 0xfe, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x4e,
0xa4, 0x9c, 0x0d, 0x63, 0x0c, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
......@@ -208,6 +210,8 @@ type Chain33Client interface {
QueryRandNum(ctx context.Context, in *ReqRandHash, opts ...grpc.CallOption) (*ReplyHash, error)
// 获取是否达到fork高度
GetFork(ctx context.Context, in *ReqKey, opts ...grpc.CallOption) (*Int64, error)
//通过seq以及title获取对应平行连的交易
GetParaTxByTitle(ctx context.Context, in *ReqParaTxByTitle, opts ...grpc.CallOption) (*ParaTxDetails, error)
}
type chain33Client struct {
......@@ -686,6 +690,15 @@ func (c *chain33Client) GetFork(ctx context.Context, in *ReqKey, opts ...grpc.Ca
return out, nil
}
func (c *chain33Client) GetParaTxByTitle(ctx context.Context, in *ReqParaTxByTitle, opts ...grpc.CallOption) (*ParaTxDetails, error) {
out := new(ParaTxDetails)
err := c.cc.Invoke(ctx, "/types.chain33/GetParaTxByTitle", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Chain33Server is the server API for Chain33 service.
type Chain33Server interface {
// chain33 对外提供服务的接口
......@@ -788,6 +801,8 @@ type Chain33Server interface {
QueryRandNum(context.Context, *ReqRandHash) (*ReplyHash, error)
// 获取是否达到fork高度
GetFork(context.Context, *ReqKey) (*Int64, error)
//通过seq以及title获取对应平行连的交易
GetParaTxByTitle(context.Context, *ReqParaTxByTitle) (*ParaTxDetails, error)
}
func RegisterChain33Server(s *grpc.Server, srv Chain33Server) {
......@@ -1730,6 +1745,24 @@ func _Chain33_GetFork_Handler(srv interface{}, ctx context.Context, dec func(int
return interceptor(ctx, in, info, handler)
}
func _Chain33_GetParaTxByTitle_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ReqParaTxByTitle)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(Chain33Server).GetParaTxByTitle(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/types.chain33/GetParaTxByTitle",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(Chain33Server).GetParaTxByTitle(ctx, req.(*ReqParaTxByTitle))
}
return interceptor(ctx, in, info, handler)
}
var _Chain33_serviceDesc = grpc.ServiceDesc{
ServiceName: "types.chain33",
HandlerType: (*Chain33Server)(nil),
......@@ -1942,6 +1975,10 @@ var _Chain33_serviceDesc = grpc.ServiceDesc{
MethodName: "GetFork",
Handler: _Chain33_GetFork_Handler,
},
{
MethodName: "GetParaTxByTitle",
Handler: _Chain33_GetParaTxByTitle_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "rpc.proto",
......
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