Commit 8b3cd529 authored by harrylee's avatar harrylee

add test cases

parent bd668bac
......@@ -11,13 +11,13 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/golang/protobuf/proto"
"io/ioutil"
"net/http"
"strconv"
"strings"
"time"
"github.com/golang/protobuf/proto"
sdk "gitlab.33.cn/link33/chain33-sdk-go"
"gitlab.33.cn/link33/chain33-sdk-go/crypto"
"gitlab.33.cn/link33/chain33-sdk-go/dapp/broker"
......@@ -301,15 +301,26 @@ func (client *JSONClient) QueryBlockInfo(start, end int64, isDetail bool) (*Bloc
return &res, nil
}
// 发布跨链事件
func (client *JSONClient) EmitDataSwapInterchainEvent(dstServiceID, args, argscb, argsrb string, privateKey string) (*Response, error) {
// FIXME 这里需完善 funcName="interchainGet,interchainSet," txType=0 表示是存在类数据交换
tx, err := broker.EmitInterchainEvent("", dstServiceID, "interchainGet,interchainSet,", args, argsrb, argsrb, 0)
// k V明文存证
func (client *JSONClient) KVStore(key, value, privateKey string) (*Response, error) {
tx, err := storage.CreateContentStorageTx("", storage.OpCreate, key, nil, value)
if err != nil {
return nil, err
}
return client.SendTransactionSync(privateKey, tx)
}
// 初始化broker
func (client *JSONClient) InitBroker(bxhId, appChainId, privateKey string) (*Response, error) {
tx := broker.InitBroker(bxhId, appChainId)
return client.SendTransactionSync(privateKey, tx)
}
// 发布跨链事件
func (client *JSONClient) EmitDataSwapInterchainEvent(dstServiceID, args, argscb, argsrb string, privateKey string) (*Response, error) {
// FIXME 这里需完善 funcName="interchainGet,interchainSet," txType=0 表示是存在类数据交换
tx := broker.EmitInterchainEvent("", dstServiceID, "interchainGet,interchainSet,", args, argsrb, argsrb, 0)
return client.SendTransactionSync(privateKey, tx)
}
// TODO 执行请求
func (client *JSONClient) Execute(requst *Request, privateKey string) (*Response, error) {
......@@ -327,45 +338,62 @@ func (client *JSONClient) Execute(requst *Request, privateKey string) (*Response
return nil, fmt.Errorf("cannot parse %s to uint64", string(requst.Args[3]))
}
if tx, err := broker.UpdateIndex("", srcChainServiceID, targetCID, sequenceNum, reqType, nil); err == nil {
// reqType==0 表示跨入交易, reqType==1 表示跨出交易,响应更新
if reqType != 0 {
tx := broker.UpdateIndex("", srcChainServiceID, targetCID, sequenceNum, reqType, 0)
resp, err := client.SendTransactionSync(privateKey, tx)
if err != nil {
return resp, err
}
//splitedCID[1]就是合约名称
splitedCID := strings.Split(targetCID, "&")
if len(splitedCID) != 2 {
return nil, fmt.Errorf("Target chaincode id %s is not valid", targetCID)
}
}
callFunc := &CallFunc{}
if err := json.Unmarshal(requst.Args[4], callFunc); err != nil {
return nil, fmt.Errorf("unmarshal call func failed for %s", requst.Args[4])
}
// 调用相应链码, (链码名称,参数,通道名称)
if splitedCID[1] == storage.StorageX {
//interchainGet方法是在sdk封装的,用于支持跨链之前数据的查询
switch callFunc.Func {
case "interchainGet":
response, err := client.InterChainGet(string(callFunc.Args[0]))
//splitedCID[1]就是合约名称
splitedCID := strings.Split(targetCID, "&")
if len(splitedCID) != 2 {
return nil, fmt.Errorf("Target chaincode id %s is not valid", targetCID)
}
callFunc := &CallFunc{}
if err := json.Unmarshal(requst.Args[4], callFunc); err != nil {
return nil, fmt.Errorf("unmarshal call func failed for %s", requst.Args[4])
}
// 调用相应链码, (链码名称,参数,通道名称)
if splitedCID[1] == storage.StorageX {
//interchainGet方法是在sdk封装的,用于支持跨链之前数据的查询
switch callFunc.Func {
case "interchainGet":
response, err := client.InterChainGet(string(callFunc.Args[0]))
if err != nil {
return response, err
}
//携带TXhash
//response.Message = resp.Message
return response, err
case "interchainSet":
//跨链set kv
status := 1
response, err := client.InterChainSet(string(callFunc.Args[0]), string(callFunc.Args[1]), privateKey)
if err != nil {
status = 0
}
//TODO 这里的处理不是事务机制
if reqType != 0 {
tx := broker.UpdateIndex("", srcChainServiceID, targetCID, sequenceNum, reqType, int32(status))
resp, err := client.SendTransactionSync(privateKey, tx)
if err != nil {
return resp, err
}
//携带TXhash
response.Message = resp.Message
return response, err
case "interchainSet":
//跨链set kv
return client.InterChainSet(string(callFunc.Args[0]), string(callFunc.Args[1]), privateKey)
}
} else {
return nil, fmt.Errorf("can't support exec %s", splitedCID[1])
return response,nil
}
} else {
return nil, fmt.Errorf("can't support exec %s", splitedCID[1])
}
}
}
return nil, fmt.Errorf("not matching execution or method!")
}
......@@ -489,12 +517,17 @@ func (client *JSONClient) QueryInnerMeta() (*types.Meta, error) {
FuncName: broker.FuncNameQueryInnerMeta,
Payload: jsonraw,
}
var meta types.Meta
err = client.Call("Chain33.Query", query, &meta)
//var meta types.Meta
//err = client.Call("Chain33.Query", query, &meta)
//if err != nil {
// return nil, err
//}
//return &meta, nil
data,err:=client.CallBack("Chain33.Query", query,ParseMeta)
if err != nil {
return nil, err
}
return &meta, nil
return data.(*types.Meta),nil
}
func (client *JSONClient) QueryOutterMeta() (*types.Meta, error) {
......@@ -507,12 +540,17 @@ func (client *JSONClient) QueryOutterMeta() (*types.Meta, error) {
FuncName: broker.FuncNameQueryOutterMeta,
Payload: jsonraw,
}
var meta types.Meta
err = client.Call("Chain33.Query", query, &meta)
//var meta types.Meta
//err = client.Call("Chain33.Query", query, &meta)
//if err != nil {
// return nil, err
//}
//return &meta, nil
data,err:=client.CallBack("Chain33.Query", query,ParseMeta)
if err != nil {
return nil, err
}
return &meta, nil
return data.(*types.Meta),nil
}
func (client *JSONClient) QueryCallBackMeta() (*types.Meta, error) {
......@@ -533,7 +571,7 @@ func (client *JSONClient) QueryCallBackMeta() (*types.Meta, error) {
return &meta, nil
}
func (client *JSONClient) QueryOutMessage(inServicePair string, index uint64) (*types.Response, error) {
func (client *JSONClient) QueryOutMessage(inServicePair string, index uint64) (*types.InterchainEvent, error) {
jsonraw, err := json.Marshal(&types.QueryOutMessage{InServicePair: inServicePair, SequenceNum: index})
if err != nil {
return nil, err
......@@ -543,12 +581,17 @@ func (client *JSONClient) QueryOutMessage(inServicePair string, index uint64) (*
FuncName: broker.FuncNameQueryOutMessage,
Payload: jsonraw,
}
var resp types.Response
err = client.Call("Chain33.Query", query, &resp)
//var event types.InterchainEvent
//err = client.Call("Chain33.Query", query, &event)
//if err != nil {
// return nil, err
//}
//return &event, nil
data,err:=client.CallBack("Chain33.Query", query, ParseInterChainEvent)
if err != nil {
return nil, err
}
return &resp, nil
return data.(*types.InterchainEvent),nil
}
func (client *JSONClient) QueryInMessage(inServicePair string, index uint64) (*types.Response, error) {
......
package client
import (
"gitlab.33.cn/link33/chain33-sdk-go/dapp/broker"
//"gitlab.33.cn/link33/chain33-sdk-go/dapp/broker"
"testing"
"time"
)
var (
GenesisPriv = "cc38546e9e659d15e6b4893f0ab32a06d103931a8230b0bde71459d2b27d6944"
)
func Test_InitBroker(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
resp, err :=client.InitBroker("bxhv1","chain33",GenesisPriv)
if err != nil {
t.Error(err)
}
t.Log(resp.Message)
}
func Test_EmitDataSwapInterchainEvent(t *testing.T) {
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
// 第一次存储
resp, err := client.KVStore("test", "hello", GenesisPriv)
if err != nil {
t.Error(err)
}
time.Sleep(time.Second)
resp, err = client.EmitDataSwapInterchainEvent("fabric&broker", "test", "test", "", GenesisPriv)
if err != nil {
t.Error(err)
}
t.Log(resp.Data)
}
func Test_InterChainGet(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
resp,err:=client.InterChainGet("test")
if err != nil {
t.Error(err)
}
t.Log(string(resp.Data))
}
func Test_QueryBrokerInfo(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
info,err:=client.QueryBrokerInfo()
if err != nil {
t.Error(err)
}
t.Logf("appid:%s,version:%s",info.GetAppChainId(),info.GetBxhId())
meta,err:=client.QueryOutterMeta()
if err != nil {
t.Error(err)
}
t.Log(meta.Meta)
}
func Test_PollEvent(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
registerCh,eventCh,errCh:=client.RegisterTxEvent(0,"broker","EmitInterchainEvent")
go func() {
select {
case event:=<-eventCh:
t.Log(event)
case err:=<-errCh:
t.Error(err)
}
}()
time.Sleep(5*time.Second)
registerCh<- struct {}{}
}
func Test_UpdateIndex(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
event,err:=client.QueryOutMessage("bxhv1:chain33:local&broker-fabric&broker",1)
if err !=nil {
t.Error(err)
}
tx := broker.UpdateIndex("", event.SrcServiceID, event.GetDstServiceID(), event.GetIndex(), 0, 1)
resp, err := client.SendTransactionSync(GenesisPriv, tx)
if err != nil {
t.Error(err)
}
t.Log(resp.Message)
}
func Test_QueryMeta(t *testing.T){
client, err := NewJSONClient("", "http://localhost:8901")
if err != nil {
t.Error(err)
}
resp,err:=client.QueryOutMessage("bxhv1:chain33:local&broker-fabric&broker",1)
if err !=nil {
t.Error(err)
}
t.Log(resp)
respon,err:=client.QueryInMessage("bxhv1:chain33:local&broker-fabric&broker",1)
if err !=nil {
t.Error(err)
}
t.Logf("status:%d",respon.Status)
meta,err:=client.QueryOutterMeta()
if err !=nil {
t.Error(err)
}
t.Log(meta.Meta)
}
......@@ -3,9 +3,10 @@ package client
import (
"encoding/json"
"fmt"
. "github.com/bitly/go-simplejson"
"gitlab.33.cn/link33/chain33-sdk-go/dapp/storage"
"gitlab.33.cn/link33/chain33-sdk-go/types"
. "github.com/bitly/go-simplejson"
"strconv"
)
// 回调解析函数
......@@ -106,3 +107,45 @@ func ParseStorage(raw json.RawMessage) (interface{}, error) {
}
return nil, fmt.Errorf("unknow type!")
}
//FIXME 解析跨链事件,系统json序列化有问题,非string字段全部转化为string字段了
func ParseInterChainEvent(raw json.RawMessage)(interface{}, error){
js, err := NewJson(raw)
if err != nil {
return nil, err
}
index,err:= strconv.ParseUint(js.Get("index").MustString(),10,64)
if err != nil {
return nil, err
}
ty,err:=strconv.ParseUint(js.Get("type").MustString(),10,64)
if err != nil {
return nil, err
}
event:=&types.InterchainEvent{
Index:index,
DstServiceID:js.Get("dstServiceID").MustString(),
SrcServiceID:js.Get("srcServiceID").MustString(),
Type:ty,
Func:js.Get("func").MustString(),
Args:js.Get("args").MustString(),
Argsrb:js.Get("argsrb").MustString(),
Argscb:js.Get("argscb").MustString(),
}
return event,nil
}
func ParseMeta(raw json.RawMessage)(interface{}, error){
js, err := NewJson(raw)
if err != nil {
return nil, err
}
m :=js.Get("meta").MustMap()
mk :=make(map[string]uint64)
for k,v :=range m{
value,_:=strconv.ParseUint(v.(string),10,64)
mk[k]=value
}
//移除broker键值
delete(mk,"broker")
return &types.Meta{Meta:mk},nil
}
......@@ -9,26 +9,34 @@ import (
)
// 构造发布跨链交易事件交易
func EmitInterchainEvent(paraName, dstServiceID, funcName string, args,argscb,argsrb string, txType uint64) (*types.Transaction, error) {
payload := &types.BrokerAction{Ty: TyEmitInterchainEventAction, Value: &types.BrokerAction_EmitInterchainEvent{EmitInterchainEvent: &types.InterchainEvent{DstServiceID: dstServiceID, Type: txType, Func: funcName, Args: args,Argscb:argscb,Argsrb:argsrb}}}
func EmitInterchainEvent(paraName, dstServiceID, funcName string, args, argscb, argsrb string, txType uint64) *types.Transaction {
payload := &types.BrokerAction{Ty: TyEmitInterchainEventAction, Value: &types.BrokerAction_EmitInterchainEvent{EmitInterchainEvent: &types.InterchainEvent{DstServiceID: dstServiceID, Type: txType, Func: funcName, Args: args, Argscb: argscb, Argsrb: argsrb}}}
if paraName == "" {
tx := &types.Transaction{Execer: []byte(BrokerX), Payload: types.Encode(payload), Fee: 1e5, Nonce: rand.Int63n(time.Now().UnixNano()), To: Addr}
return tx, nil
return tx
} else {
tx := &types.Transaction{Execer: []byte(paraName + BrokerX), Payload: types.Encode(payload), Fee: 1e5, Nonce: rand.Int63n(time.Now().UnixNano()), To: crypto.GetExecAddress(paraName + BrokerX)}
return tx, nil
return tx
}
}
// 构造更新Index交易
func UpdateIndex(paraName, srcServiceID, dstServiceID string, sequenceNum, reqType uint64, response *types.Response) (*types.Transaction, error) {
payload := &types.BrokerAction{Ty: TyUpdateIndexAction, Value: &types.BrokerAction_UpdateIndex{UpdateIndex: &types.UpdateIndex{DstServiceID: dstServiceID, SrcServiceID: srcServiceID, ReqType: reqType, SequenceNum: sequenceNum, Response: response}}}
func UpdateIndex(paraName, srcServiceID, dstServiceID string, sequenceNum, reqType uint64, status int32) *types.Transaction {
payload := &types.BrokerAction{Ty: TyUpdateIndexAction, Value: &types.BrokerAction_UpdateIndex{UpdateIndex: &types.UpdateIndex{DstServiceID: dstServiceID, SrcServiceID: srcServiceID, ReqType: reqType, SequenceNum: sequenceNum, Response: &types.Response{Status:status}}}}
if paraName == "" {
tx := &types.Transaction{Execer: []byte(BrokerX), Payload: types.Encode(payload), Fee: 1e5, Nonce: rand.Int63n(time.Now().UnixNano()), To: Addr}
return tx, nil
return tx
} else {
tx := &types.Transaction{Execer: []byte(paraName + BrokerX), Payload: types.Encode(payload), Fee: 1e5, Nonce: rand.Int63n(time.Now().UnixNano()), To: crypto.GetExecAddress(paraName + BrokerX)}
return tx, nil
return tx
}
}
func InitBroker(bxhId, appChainId string) *types.Transaction {
payload := &types.BrokerAction{Ty: TyInitAction, Value: &types.BrokerAction_Init{Init: &types.Init{
BxhId: bxhId,
AppChainId: appChainId,
}}}
tx := &types.Transaction{Execer: []byte(BrokerX), Payload: types.Encode(payload), Fee: 1e5, Nonce: rand.Int63n(time.Now().UnixNano()), To: Addr}
return tx
}
......@@ -19,7 +19,7 @@ var (
func TestCreateContentStorageTx(t *testing.T) {
// 第一次存储
tx, err := CreateContentStorageTx("", OpCreate, "", []byte("hello"), "")
tx, err := CreateContentStorageTx("", OpCreate, "test", nil,"hello")
assert.Nil(t, err)
hexbytes, _ := types.FromHex(privkey)
sdk.Sign(tx, hexbytes, crypto.SECP256K1, nil)
......@@ -35,9 +35,9 @@ func TestCreateContentStorageTx(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, types.ExecOk, int(detail.Receipt.Ty))
// 查询
storage, err := QueryStorageByKey("", url, txhash)
storage, err := QueryStorageByKey("", url, "test")
assert.Nil(t, err)
assert.Equal(t, []byte("hello"), storage.GetContentStorage().Content)
assert.Equal(t, "hello", storage.GetContentStorage().Value)
//第二次追加 老版本不支持
//tx,err=CreateContentStorageTx("",OpAdd,txhash,[]byte("world"),"")
//assert.Nil(t,err)
......@@ -52,6 +52,8 @@ func TestCreateContentStorageTx(t *testing.T) {
//assert.Equal(t,[]byte("hello,world"),storage.GetContentStorage().Content)
}
// hash,or link 存证
func TestCreateHashStorageTx(t *testing.T) {
tx, err := CreateHashStorageTx("", "", []byte("123456harrylee"), "")
......
......@@ -49,7 +49,7 @@ message UpdateIndex {
string srcServiceID = 3;
//请求类型 0表示信息流入 1表示信息流出 2表示回滚
uint64 reqType =4;
//响应信息
//跨入交易执行结果
Response response = 5;
}
// 跨链事件
......@@ -150,10 +150,6 @@ message Meta {
message Response{
// A status code that should follow the HTTP status codes.
int32 status = 1;
// A message associated with the response code.
string message = 2;
// A payload that can be used to include metadata with this response.
bytes payload = 3;
//状态 0表示开始处理 1表示跨链成功 2表示跨链失败
int32 status = 1;
}
......@@ -345,7 +345,7 @@ type UpdateIndex struct {
SrcServiceID string `protobuf:"bytes,3,opt,name=srcServiceID,proto3" json:"srcServiceID,omitempty"`
//请求类型 0表示信息流入 1表示信息流出 2表示回滚
ReqType uint64 `protobuf:"varint,4,opt,name=reqType,proto3" json:"reqType,omitempty"`
//响应信息
//跨入交易执行结果
Response *Response `protobuf:"bytes,5,opt,name=response,proto3" json:"response,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
......@@ -1009,12 +1009,8 @@ func (m *Meta) GetMeta() map[string]uint64 {
}
type Response struct {
// A status code that should follow the HTTP status codes.
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
// A message associated with the response code.
Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
// A payload that can be used to include metadata with this response.
Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"`
//状态 0表示开始处理 1表示跨链成功 2表示跨链失败
Status int32 `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -1052,20 +1048,6 @@ func (m *Response) GetStatus() int32 {
return 0
}
func (m *Response) GetMessage() string {
if m != nil {
return m.Message
}
return ""
}
func (m *Response) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
func init() {
proto.RegisterType((*BrokerAction)(nil), "types.BrokerAction")
proto.RegisterType((*Init)(nil), "types.Init")
......@@ -1093,53 +1075,51 @@ func init() {
}
var fileDescriptor_f209535e190f2bed = []byte{
// 724 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x5f, 0x4f, 0xdb, 0x48,
0x10, 0x8f, 0x1d, 0x3b, 0x24, 0x93, 0x40, 0xb8, 0x85, 0x43, 0xd6, 0x3d, 0xdc, 0x71, 0x16, 0x0f,
0xdc, 0x9d, 0xc4, 0x49, 0x20, 0xb5, 0x55, 0xd5, 0x97, 0x84, 0x22, 0x25, 0x15, 0x50, 0xba, 0xfd,
0xa3, 0xf6, 0x71, 0xe3, 0x0c, 0x61, 0x4b, 0x62, 0x9b, 0xf5, 0x1a, 0xe1, 0x8f, 0xd2, 0x6f, 0xd2,
0xa7, 0x7e, 0x91, 0x7e, 0x99, 0x6a, 0xff, 0x24, 0x71, 0x02, 0x55, 0x55, 0x84, 0xfa, 0x02, 0x3b,
0xbf, 0x99, 0xdd, 0x99, 0xfc, 0x66, 0x7e, 0x63, 0x68, 0x0d, 0x44, 0x72, 0x89, 0x62, 0x2f, 0x15,
0x89, 0x4c, 0x88, 0x2f, 0x8b, 0x14, 0xb3, 0xf0, 0xb3, 0x0b, 0xad, 0xae, 0xc6, 0x3b, 0x91, 0xe4,
0x49, 0x4c, 0xfe, 0x06, 0x8f, 0xc7, 0x5c, 0x06, 0xce, 0xb6, 0xb3, 0xdb, 0xdc, 0x6f, 0xee, 0xe9,
0xb0, 0xbd, 0x7e, 0xcc, 0x65, 0xaf, 0x42, 0xb5, 0x8b, 0x74, 0xa1, 0x2d, 0x70, 0xc4, 0x33, 0x89,
0xe2, 0xe8, 0x06, 0x23, 0x99, 0x88, 0xc0, 0xd5, 0xd1, 0x5b, 0x36, 0x9a, 0x2e, 0x7a, 0x7b, 0x15,
0xba, 0x7c, 0x81, 0xec, 0x80, 0xcf, 0xf2, 0x21, 0x97, 0x41, 0x55, 0xdf, 0x6c, 0xd9, 0x9b, 0x1d,
0x85, 0xf5, 0x2a, 0xd4, 0x38, 0xc9, 0x0b, 0xd8, 0xc0, 0x09, 0x97, 0xfd, 0x58, 0xa2, 0x88, 0x2e,
0x18, 0x8f, 0x8f, 0xae, 0x31, 0x96, 0x81, 0xb7, 0x90, 0x6d, 0xc9, 0xdb, 0xab, 0xd0, 0xbb, 0x2e,
0x91, 0x47, 0xd0, 0xcc, 0xd3, 0x21, 0x93, 0xd8, 0x8f, 0x87, 0x78, 0x13, 0xf8, 0xfa, 0x0d, 0x62,
0xdf, 0x78, 0x3b, 0xf7, 0xf4, 0x2a, 0xb4, 0x1c, 0x48, 0xd6, 0xc0, 0x95, 0x45, 0x50, 0xdb, 0x76,
0x76, 0x7d, 0xea, 0xca, 0xa2, 0xbb, 0x02, 0xfe, 0x35, 0x1b, 0xe7, 0x18, 0x3e, 0x03, 0x4f, 0xd1,
0x42, 0x36, 0xc1, 0x1f, 0xdc, 0x5c, 0xf4, 0x87, 0x9a, 0xb2, 0x06, 0x35, 0x06, 0xf9, 0x13, 0x80,
0xa5, 0xe9, 0xa1, 0xca, 0xdf, 0x1f, 0x6a, 0x7e, 0x1a, 0xb4, 0x84, 0x84, 0x07, 0xd0, 0x5e, 0xa2,
0x89, 0x6c, 0x43, 0x13, 0xcd, 0xf1, 0x94, 0x4d, 0xd0, 0x3e, 0x57, 0x86, 0xc2, 0x0e, 0xf8, 0x9a,
0xa1, 0x1f, 0x87, 0x92, 0x2d, 0xa8, 0x65, 0x92, 0xc9, 0x3c, 0xb3, 0xb9, 0xad, 0x15, 0xfe, 0x0f,
0xad, 0xb3, 0x64, 0x3c, 0xe6, 0xf1, 0xc8, 0xd0, 0xf2, 0x17, 0x78, 0x13, 0x94, 0x6c, 0xa9, 0xdf,
0x27, 0x28, 0x19, 0xd5, 0x8e, 0xf0, 0x8b, 0x03, 0xcd, 0x12, 0x3d, 0x2a, 0x75, 0x86, 0x57, 0x39,
0xc6, 0x11, 0x9e, 0xe6, 0x13, 0x7d, 0xcf, 0xa3, 0x65, 0x88, 0x84, 0xd0, 0x1a, 0x66, 0xf2, 0x35,
0x8a, 0x6b, 0x1e, 0x61, 0xff, 0xb9, 0x2d, 0x60, 0x01, 0x53, 0x31, 0x99, 0x88, 0xe6, 0x31, 0x55,
0x13, 0x53, 0xc6, 0x48, 0x00, 0x2b, 0x02, 0xaf, 0xde, 0x14, 0x29, 0xea, 0x8e, 0x7b, 0x74, 0x6a,
0x92, 0xff, 0xa0, 0x2e, 0x30, 0x4b, 0x93, 0x38, 0x43, 0xdb, 0xc8, 0xf6, 0x6c, 0xf4, 0x0c, 0x4c,
0x67, 0x01, 0xe1, 0x57, 0x07, 0xda, 0xcb, 0xc3, 0xb0, 0x09, 0x3e, 0xd7, 0x63, 0x60, 0xca, 0x37,
0xc6, 0x83, 0x15, 0x4e, 0xc0, 0x93, 0xf3, 0xaa, 0xf5, 0x59, 0x61, 0xe7, 0x79, 0x1c, 0xe9, 0x72,
0x1b, 0x54, 0x9f, 0x15, 0xc6, 0xc4, 0x28, 0xd3, 0xc3, 0xd5, 0xa0, 0xfa, 0xac, 0xfa, 0xa6, 0xfe,
0x47, 0x83, 0x60, 0xc5, 0xf4, 0xcd, 0x58, 0x53, 0x5c, 0x0c, 0x82, 0xfa, 0x1c, 0x17, 0x83, 0xf0,
0x93, 0x0b, 0xeb, 0x14, 0x23, 0xe4, 0xa9, 0x34, 0x3a, 0x3e, 0x4e, 0x46, 0x77, 0x29, 0xd4, 0xb9,
0xb7, 0x42, 0xdd, 0x7b, 0x28, 0xb4, 0xfa, 0x00, 0x0a, 0xf5, 0x7e, 0x4e, 0xa1, 0xfe, 0x6d, 0x85,
0x4a, 0xd8, 0x7c, 0x95, 0xa3, 0x28, 0x7e, 0x69, 0xf7, 0xc3, 0x0e, 0x6c, 0xe8, 0x84, 0x87, 0xb3,
0x84, 0xc7, 0x3c, 0x93, 0xe4, 0x5f, 0xf0, 0xc6, 0x3c, 0x53, 0x8b, 0xb5, 0xfa, 0x7d, 0x6a, 0xa8,
0x8e, 0x09, 0xdb, 0xb0, 0xaa, 0x0b, 0x3f, 0xe5, 0xe3, 0x33, 0x26, 0xd8, 0x24, 0xfc, 0x0d, 0xda,
0x1a, 0x78, 0x99, 0x4b, 0x89, 0x42, 0xa9, 0x33, 0x5c, 0x87, 0x35, 0xfb, 0xe3, 0x62, 0x8b, 0xbc,
0x9f, 0x21, 0x27, 0x98, 0x65, 0x6c, 0x84, 0x64, 0x07, 0x56, 0x79, 0x6c, 0x2b, 0x3b, 0x63, 0x5c,
0xd8, 0x45, 0xb1, 0x08, 0x2e, 0x2b, 0xda, 0xbd, 0xa5, 0xe8, 0xf0, 0xc3, 0x3c, 0xfd, 0x43, 0x3f,
0xdd, 0x05, 0x30, 0x73, 0xdb, 0x8f, 0xcf, 0x93, 0x7b, 0xee, 0xd2, 0x8f, 0xe0, 0x29, 0x02, 0xc8,
0x3f, 0xb3, 0x5d, 0xa6, 0x28, 0xfe, 0xbd, 0xb4, 0xcb, 0xf4, 0x9f, 0xa3, 0x58, 0x8a, 0xc2, 0x6c,
0xb5, 0x3f, 0x1e, 0x43, 0x63, 0x06, 0x91, 0x75, 0xa8, 0x5e, 0x62, 0x61, 0x73, 0xaa, 0xa3, 0xaa,
0x43, 0x8f, 0x90, 0xad, 0xd8, 0x18, 0x4f, 0xdd, 0x27, 0x4e, 0xf8, 0x0e, 0xea, 0xd3, 0x1d, 0x53,
0xda, 0xb1, 0x8e, 0x1e, 0x3e, 0x6b, 0xa9, 0xc5, 0x35, 0x31, 0x34, 0xd9, 0x62, 0xa7, 0xa6, 0xf2,
0xa4, 0xac, 0x18, 0x27, 0x6c, 0xa8, 0x47, 0xa7, 0x45, 0xa7, 0xe6, 0x7e, 0x1d, 0x6a, 0xe6, 0xfb,
0x3c, 0xa8, 0xe9, 0x0f, 0xf4, 0xc1, 0xb7, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x11, 0xe4, 0xb4,
0xb0, 0x07, 0x00, 0x00,
// 702 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xcd, 0x4e, 0x1b, 0x49,
0x10, 0xf6, 0x8c, 0x67, 0x8c, 0x5d, 0x36, 0x98, 0x6d, 0x58, 0x34, 0xda, 0xc3, 0x2e, 0xdb, 0xe2,
0xc0, 0xee, 0x4a, 0xac, 0x04, 0xd2, 0x6e, 0x14, 0xe5, 0x62, 0x13, 0x24, 0x3b, 0x02, 0x42, 0x3a,
0x89, 0x94, 0x1c, 0xc7, 0xe3, 0xc2, 0x74, 0xb0, 0x7b, 0x86, 0x9e, 0x1e, 0x84, 0x1f, 0x25, 0x6f,
0x92, 0x53, 0x5e, 0x24, 0x2f, 0x13, 0xf5, 0x0f, 0xf6, 0xd8, 0x10, 0x45, 0x41, 0x28, 0x17, 0xe8,
0xfa, 0xaa, 0xba, 0xab, 0xfc, 0x55, 0x7d, 0x35, 0xd0, 0x1a, 0xc8, 0xf4, 0x12, 0xe5, 0x5e, 0x26,
0x53, 0x95, 0x92, 0x50, 0x4d, 0x33, 0xcc, 0xe9, 0x27, 0x1f, 0x5a, 0x5d, 0x83, 0x77, 0x12, 0xc5,
0x53, 0x41, 0xfe, 0x84, 0x80, 0x0b, 0xae, 0x22, 0x6f, 0xdb, 0xdb, 0x6d, 0xee, 0x37, 0xf7, 0x4c,
0xd8, 0x5e, 0x5f, 0x70, 0xd5, 0xab, 0x30, 0xe3, 0x22, 0x5d, 0x68, 0x4b, 0x1c, 0xf1, 0x5c, 0xa1,
0x3c, 0xba, 0xc1, 0x44, 0xa5, 0x32, 0xf2, 0x4d, 0xf4, 0x96, 0x8b, 0x66, 0x8b, 0xde, 0x5e, 0x85,
0x2d, 0x5f, 0x20, 0x3b, 0x10, 0xc6, 0xc5, 0x90, 0xab, 0xa8, 0x6a, 0x6e, 0xb6, 0xdc, 0xcd, 0x8e,
0xc6, 0x7a, 0x15, 0x66, 0x9d, 0xe4, 0x05, 0x6c, 0xe0, 0x84, 0xab, 0xbe, 0x50, 0x28, 0x93, 0x8b,
0x98, 0x8b, 0xa3, 0x6b, 0x14, 0x2a, 0x0a, 0x16, 0xb2, 0x2d, 0x79, 0x7b, 0x15, 0x76, 0xdf, 0x25,
0xf2, 0x1f, 0x34, 0x8b, 0x6c, 0x18, 0x2b, 0xec, 0x8b, 0x21, 0xde, 0x44, 0xa1, 0x79, 0x83, 0xb8,
0x37, 0xde, 0xce, 0x3d, 0xbd, 0x0a, 0x2b, 0x07, 0x92, 0x35, 0xf0, 0xd5, 0x34, 0xaa, 0x6d, 0x7b,
0xbb, 0x21, 0xf3, 0xd5, 0xb4, 0xbb, 0x02, 0xe1, 0x75, 0x3c, 0x2e, 0x90, 0x3e, 0x83, 0x40, 0xd3,
0x42, 0x36, 0x21, 0x1c, 0xdc, 0x5c, 0xf4, 0x87, 0x86, 0xb2, 0x06, 0xb3, 0x06, 0xf9, 0x1d, 0x20,
0xce, 0xb2, 0x43, 0x9d, 0xbf, 0x3f, 0x34, 0xfc, 0x34, 0x58, 0x09, 0xa1, 0x07, 0xd0, 0x5e, 0xa2,
0x89, 0x6c, 0x43, 0x13, 0xed, 0xf1, 0x34, 0x9e, 0xa0, 0x7b, 0xae, 0x0c, 0xd1, 0x0e, 0x84, 0x86,
0xa1, 0xef, 0x87, 0x92, 0x2d, 0xa8, 0xe5, 0x2a, 0x56, 0x45, 0xee, 0x72, 0x3b, 0x8b, 0xfe, 0x0b,
0xad, 0xb3, 0x74, 0x3c, 0xe6, 0x62, 0x64, 0x69, 0xf9, 0x03, 0x82, 0x09, 0xaa, 0x78, 0xa9, 0xdf,
0x27, 0xa8, 0x62, 0x66, 0x1c, 0xf4, 0xb3, 0x07, 0xcd, 0x12, 0x3d, 0x3a, 0x75, 0x8e, 0x57, 0x05,
0x8a, 0x04, 0x4f, 0x8b, 0x89, 0xb9, 0x17, 0xb0, 0x32, 0x44, 0x28, 0xb4, 0x86, 0xb9, 0x7a, 0x8d,
0xf2, 0x9a, 0x27, 0xd8, 0x7f, 0xee, 0x0a, 0x58, 0xc0, 0x74, 0x4c, 0x2e, 0x93, 0x79, 0x4c, 0xd5,
0xc6, 0x94, 0x31, 0x12, 0xc1, 0x8a, 0xc4, 0xab, 0x37, 0xd3, 0x0c, 0x4d, 0xc7, 0x03, 0x76, 0x6b,
0x92, 0x7f, 0xa0, 0x2e, 0x31, 0xcf, 0x52, 0x91, 0xa3, 0x6b, 0x64, 0x7b, 0x36, 0x7a, 0x16, 0x66,
0xb3, 0x00, 0xfa, 0xc5, 0x83, 0xf6, 0xf2, 0x30, 0x6c, 0x42, 0xc8, 0xcd, 0x18, 0xd8, 0xf2, 0xad,
0xf1, 0x68, 0x85, 0x13, 0x08, 0xd4, 0xbc, 0x6a, 0x73, 0xd6, 0xd8, 0x79, 0x21, 0x12, 0x53, 0x6e,
0x83, 0x99, 0xb3, 0xc6, 0x62, 0x39, 0xca, 0xcd, 0x70, 0x35, 0x98, 0x39, 0xeb, 0xbe, 0xe9, 0xff,
0xc9, 0x20, 0x5a, 0xb1, 0x7d, 0xb3, 0xd6, 0x2d, 0x2e, 0x07, 0x51, 0x7d, 0x8e, 0xcb, 0x01, 0xfd,
0xe8, 0xc3, 0x3a, 0xc3, 0x04, 0x79, 0xa6, 0xac, 0x8e, 0x8f, 0xd3, 0xd1, 0x7d, 0x0a, 0xf5, 0x1e,
0xac, 0x50, 0xff, 0x01, 0x0a, 0xad, 0x3e, 0x82, 0x42, 0x83, 0x1f, 0x53, 0x68, 0x78, 0x57, 0xa1,
0x0a, 0x36, 0x5f, 0x15, 0x28, 0xa7, 0x3f, 0xb5, 0xfb, 0xb4, 0x03, 0x1b, 0x26, 0xe1, 0xe1, 0x2c,
0xe1, 0x31, 0xcf, 0x15, 0xf9, 0x1b, 0x82, 0x31, 0xcf, 0xf5, 0x62, 0xad, 0x7e, 0x9b, 0x1a, 0x66,
0x62, 0x68, 0x1b, 0x56, 0x4d, 0xe1, 0xa7, 0x7c, 0x7c, 0x16, 0xcb, 0x78, 0x42, 0x7f, 0x81, 0xb6,
0x01, 0x5e, 0x16, 0x4a, 0xa1, 0xd4, 0xea, 0xa4, 0xeb, 0xb0, 0xe6, 0x7e, 0x9c, 0x70, 0xc8, 0xbb,
0x19, 0x72, 0x82, 0x79, 0x1e, 0x8f, 0x90, 0xec, 0xc0, 0x2a, 0x17, 0xae, 0xb2, 0xb3, 0x98, 0x4b,
0xb7, 0x28, 0x16, 0xc1, 0x65, 0x45, 0xfb, 0x77, 0x14, 0x4d, 0xdf, 0xcf, 0xd3, 0x3f, 0xf6, 0xd3,
0x5d, 0x00, 0x3b, 0xb7, 0x7d, 0x71, 0x9e, 0x3e, 0x70, 0x97, 0x7e, 0x80, 0x40, 0x13, 0x40, 0xfe,
0x9a, 0xed, 0x32, 0x4d, 0xf1, 0xaf, 0xa5, 0x5d, 0x66, 0xfe, 0x1c, 0x09, 0x25, 0xa7, 0x76, 0xab,
0xfd, 0xf6, 0x3f, 0x34, 0x66, 0x10, 0x59, 0x87, 0xea, 0x25, 0x4e, 0x5d, 0x4e, 0x7d, 0xd4, 0x75,
0x98, 0x11, 0x72, 0x15, 0x5b, 0xe3, 0xa9, 0xff, 0xc4, 0xa3, 0x14, 0xea, 0xb7, 0x3b, 0xa6, 0xb4,
0x63, 0x3d, 0x33, 0x7c, 0xce, 0xda, 0xaf, 0x43, 0xcd, 0x7e, 0x6b, 0x07, 0x35, 0xf3, 0xb1, 0x3d,
0xf8, 0x1a, 0x00, 0x00, 0xff, 0xff, 0xa5, 0xc4, 0x8c, 0xba, 0x7c, 0x07, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
......
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