Commit f9d4465d authored by 任硕's avatar 任硕 Committed by linj

unfreeze exec

parent 9b25d121
......@@ -2,8 +2,9 @@ package executor
import (
"time"
"gitlab.33.cn/chain33/chain33/account"
"gitlab.33.cn/chain33/chain33/common"
dbm "gitlab.33.cn/chain33/chain33/common/db"
uf "gitlab.33.cn/chain33/chain33/plugin/dapp/unfreeze/types"
"gitlab.33.cn/chain33/chain33/system/dapp"
......@@ -30,21 +31,21 @@ func newAction(u *Unfreeze, tx *types.Transaction, index int32) *action {
//创建解冻交易
func (a *action) UnfreezeCreate(create *uf.UnfreezeCreate) (*types.Receipt, error) {
/*
*参数检测
*时间等
*/
if create.GetStartTime() <= time.Unix()
//构造ID - txHash
var unfreezeID string = a.txhash
receipt, err := a.coinsAccount.TransferToExec(a.fromaddr, a.execaddr, create.TotalCount)
var unfreezeID string = "unfreezeID_" + common.ToHex(a.txhash)
tokenAccDB, err := account.NewAccountDB("token", create.TokenName, a.db)
if err != nil {
return nil, err
}
receipt, err := tokenAccDB.ExecFrozen(a.fromaddr, a.execaddr, create.TotalCount)
if err != nil {
uflog.Error("unfreeze create ", "addr", a.fromaddr, "execaddr", a.execaddr, "ExecFrozen amount", create.TotalCount)
return nil, err
}
var logs []*types.ReceiptLog
var kv []*types.KeyValue
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
unfreeze := &uf.Unfreeze{
UnfreezeID: unfreezeID,
StartTime: create.StartTime,
......@@ -57,30 +58,17 @@ func (a *action) UnfreezeCreate(create *uf.UnfreezeCreate) (*types.Receipt, erro
Amount: create.Amount,
}
a.saveStateDB(unfreeze)
var logs []*types.ReceiptLog
var kv []*types.KeyValue
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
receiptLog := a.getReceiptLog(unfreeze) //TODO 修改receiptLog
k := []byte(unfreezeID)
v := types.Encode(unfreeze)
kv = append(kv, &types.KeyValue{k, v})
receiptLog := a.getCreateLog(unfreeze)
logs = append(logs, receiptLog)
return &types.Receipt{types.ExecOk, kv, logs}, nil
}
//提取解冻币
func (a *action) UnfreezeWithdraw(withdraw *uf.UnfreezeWithdraw) (*types.Receipt, error) {
//TODO pseudocode
/*
*参数检测
*检测该地址是否存在对应解冻交易ID
*/
/*
*从合约转币到该地址(收币地址)
*/
value, err := a.db.Get(key(withdraw.GetUnfreezeID()))
value, err := a.db.Get(key(withdraw.UnfreezeID))
if err != nil {
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", err)
return nil, err
......@@ -91,58 +79,109 @@ func (a *action) UnfreezeWithdraw(withdraw *uf.UnfreezeWithdraw) (*types.Receipt
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", err)
return nil, err
}
/*
*检测可取款状态(时间)
*计算可取款额
*计算取款次数增加量
*/
var amount int64
var withdrawTimes int32
var logs []*types.ReceiptLog
var kv []*types.KeyValue
currentTime := time.Now().Unix()
expectTimes := (currentTime + unfreeze.Period - unfreeze.StartTime) / unfreeze.Period
reaTimes := expectTimes - int64(unfreeze.WithdrawTimes)
if reaTimes <= 0 {
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", types.ErrUnfreezeBeforeDue)
return nil, types.ErrUnfreezeBeforeDue
}
if unfreeze.Remaining <= 0 {
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", types.ErrUnfreezeEmptied)
return nil, types.ErrUnfreezeEmptied
}
receipt, err := a.coinsAccount.ExecTransferFrozen(unfreeze.Initiator, unfreeze.Beneficiary, a.execaddr, amount)
var available int64
switch unfreeze.Means {
case 1: // 百分比
for i := int64(0); i < reaTimes; i++ {
if tmp := unfreeze.Remaining * unfreeze.Amount / 10000; tmp == 0 {
available = unfreeze.Remaining
break
} else {
available += tmp
}
}
case 2: // 固额
for i := int64(0); i < reaTimes; i++ {
if unfreeze.Remaining <= unfreeze.Amount {
available = unfreeze.Remaining
break
}
available += unfreeze.Amount
}
default:
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", types.ErrUnfreezeMeans)
return nil, types.ErrUnfreezeMeans
}
tokenAccDB, err := account.NewAccountDB("token", unfreeze.TokenName, a.db)
if err != nil {
return nil, err
}
receipt, err := tokenAccDB.ExecTransferFrozen(unfreeze.Initiator, a.fromaddr, a.execaddr, available)
if err != nil {
uflog.Error("unfreeze withdraw ", "execaddr", a.execaddr, "err", err)
return nil, err
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
unfreeze.WithdrawTimes += withdrawTimes
unfreeze.WithdrawTimes += int32(reaTimes)
unfreeze.Remaining -= available
a.saveStateDB(&unfreeze)
receiptLog := a.getWithdrawLog(&unfreeze)
logs = append(logs, receiptLog)
k := []byte(withdraw.UnfreezeID)
v := types.Encode(&unfreeze)
kv = append(kv, &types.KeyValue{k, v})
return &types.Receipt{types.ExecOk, kv, logs}, nil
}
//中止定期解冻
func (a *action) UnfreezeTerminate(terminate *uf.UnfreezeTerminate) (*types.Receipt, error) {
//TODO pseudocode
/*
*参数检测
*检测该地址是否存在对应解冻交易ID
*/
/*
*从合约转币到该地址(发币地址)
*/
//计算合约中剩余币数
var remain int64
//获取发币地址
var senderAddr string
receipt, err := a.coinsAccount.ExecActive(senderAddr, a.execaddr, remain)
value, err := a.db.Get(key(terminate.UnfreezeID))
if err != nil {
uflog.Error("unfreeze terminate ", "execaddr", a.execaddr, "err", err)
return nil, err
}
var unfreeze uf.Unfreeze
err = types.Decode(value, &unfreeze)
if err != nil {
uflog.Error("unfreeze terminate ", "execaddr", a.execaddr, "err", err)
return nil, err
}
if a.fromaddr != unfreeze.Initiator {
uflog.Error("unfreeze terminate ", "execaddr", a.execaddr, "err", types.ErrUnfreezeID)
return nil, types.ErrUnfreezeID
}
if unfreeze.Remaining <= 0 {
uflog.Error("unfreeze terminate ", "execaddr", a.execaddr, "err", types.ErrUnfreezeEmptied)
return nil, types.ErrUnfreezeEmptied
}
tokenAccDB, err := account.NewAccountDB("token", unfreeze.TokenName, a.db)
if err != nil {
return nil, err
}
receipt, err := tokenAccDB.ExecActive(unfreeze.Initiator, a.execaddr, unfreeze.Remaining)
if err != nil {
uflog.Error("unfreeze terminate ", "addr", senderAddr, "execaddr", a.execaddr, "err", err)
uflog.Error("unfreeze terminate ", "addr", unfreeze.Initiator, "execaddr", a.execaddr, "err", err)
return nil, err
}
var logs []*types.ReceiptLog
var kv []*types.KeyValue
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
/*修改receipt
*修改数据库中状态
*/
unfreeze.Remaining = 0
a.saveStateDB(&unfreeze)
receiptLog := a.getTerminateLog(&unfreeze)
logs = append(logs, receiptLog)
k := []byte(terminate.UnfreezeID)
v := types.Encode(&unfreeze)
kv = append(kv, &types.KeyValue{k, v})
return &types.Receipt{types.ExecOk, kv, logs}, nil
}
......@@ -156,19 +195,37 @@ func key(id string) (keys []byte) {
return keys
}
func (a *action) getReceiptLog(unfreeze *uf.Unfreeze) *types.ReceiptLog {
//TODO 判断不同类型receipt
func (a *action) getCreateLog(unfreeze *uf.Unfreeze) *types.ReceiptLog {
log := &types.ReceiptLog{}
log.Ty = uf.TyLogCreateUnfreeze
r := &uf.ReceiptCreate{}
r.UnfreezeID = unfreeze.UnfreezeID
r.Initiator = unfreeze.Initiator
log.Log = types.Encode(r)
return log
}
func (a *action) getWithdrawLog(unfreeze *uf.Unfreeze) *types.ReceiptLog {
log := &types.ReceiptLog{}
log.Ty = uf.TyLogCreateUnfreeze
r := &uf.ReceiptWithdraw{}
r.WithdrawTimes = unfreeze.WithdrawTimes
r.Beneficiary = unfreeze.Beneficiary
log.Log = types.Encode(r)
return log
}
func (a *action) getTerminateLog(unfreeze *uf.Unfreeze) *types.ReceiptLog {
log := &types.ReceiptLog{}
r := &uf.ReceiptUnfreeze{}
r.TokenName = unfreeze.TokenName
r.CreateAddr = unfreeze.Initiator
r.ReceiveAddr = unfreeze.Beneficiary
log.Ty = uf.TyLogCreateUnfreeze
r := &uf.ReceiptTerminate{}
r.UnfreezeID = unfreeze.UnfreezeID
log.Log = types.Encode(r)
return log
}
//查询可提币状态
func QueryWithdraw(stateDB dbm.KV, param *uf.QueryWithdraw) (types.Message, error) {
func QueryWithdraw(stateDB dbm.KV, param *uf.QueryWithdrawStatus) (types.Message, error) {
//查询提币次数
//计算当前可否提币
return &types.Reply{}, nil
......
......@@ -5,6 +5,6 @@ import (
"gitlab.33.cn/chain33/chain33/types"
)
func (u *Unfreeze) Query_QueryWithdraw(in *uf.QueryWithdraw) (types.Message, error) {
func (u *Unfreeze) Query_QueryWithdraw(in *uf.QueryWithdrawStatus) (types.Message, error) {
return QueryWithdraw(u.GetStateDB(), in)
}
......@@ -23,6 +23,8 @@ message Unfreeze {
int64 amount = 9;
//已解冻次数
int32 withdrawTimes = 10;
//解冻剩余币数
int64 remaining = 11;
}
// message for execs.unfreeze
......@@ -32,18 +34,18 @@ message UnfreezeAction {
UnfreezeWithdraw withdraw = 2;
UnfreezeTerminate terminate = 3;
}
int32 ty = 10;
int32 ty = 4;
}
// action
message UnfreezeCreate {
int64 startTime = 1;
string tokenName = 2;
int64 totalCount = 3;
string initiator = 4;
string beneficiary = 5;
int64 period = 6;
int32 means = 7;
int64 amount = 8;
string beneficiary = 4;
int64 period = 5;
int32 means = 6;
int64 amount = 7;
}
message UnfreezeWithdraw {
......@@ -54,13 +56,22 @@ message UnfreezeTerminate {
string unfreezeID = 1;
}
//TODO: 更多receipt类型
message ReceiptUnfreeze {
string tokenName = 1;
string createAddr = 2;
string receiveAddr = 3;
// receipt
message ReceiptCreate {
string unfreezeID = 1;
string initiator = 2;
}
message ReceiptWithdraw {
int32 withdrawTimes = 1;
string beneficiary = 3;
}
message ReceiptTerminate {
string unfreezeID = 1;
}
message QueryWithdraw {
// query
message QueryWithdrawStatus {
string unfreezeID = 1;
}
......@@ -35,9 +35,9 @@ type UnfreezeType struct {
func (u *UnfreezeType) GetLogMap() map[int64]*types.LogInfo {
return map[int64]*types.LogInfo{
TyLogCreateUnfreeze: {reflect.TypeOf(ReceiptUnfreeze{}), "LogCreateUnfreeze"},
TyLogWithdrawUnfreeze: {reflect.TypeOf(ReceiptUnfreeze{}), "LogWithdrawUnfreeze"},
TyLogTerminateUnfreeze: {reflect.TypeOf(ReceiptUnfreeze{}), "LogTerminateUnfreeze"},
TyLogCreateUnfreeze: {reflect.TypeOf(ReceiptCreate{}), "LogCreateUnfreeze"},
TyLogWithdrawUnfreeze: {reflect.TypeOf(ReceiptWithdraw{}), "LogWithdrawUnfreeze"},
TyLogTerminateUnfreeze: {reflect.TypeOf(ReceiptTerminate{}), "LogTerminateUnfreeze"},
}
}
......
......@@ -13,8 +13,10 @@ It has these top-level messages:
UnfreezeCreate
UnfreezeWithdraw
UnfreezeTerminate
ReceiptUnfreeze
QueryWithdraw
ReceiptCreate
ReceiptWithdraw
ReceiptTerminate
QueryWithdrawStatus
*/
package types
......@@ -54,6 +56,8 @@ type Unfreeze struct {
Amount int64 `protobuf:"varint,9,opt,name=amount" json:"amount,omitempty"`
// 已解冻次数
WithdrawTimes int32 `protobuf:"varint,10,opt,name=withdrawTimes" json:"withdrawTimes,omitempty"`
// 解冻剩余币数
Remaining int64 `protobuf:"varint,11,opt,name=remaining" json:"remaining,omitempty"`
}
func (m *Unfreeze) Reset() { *m = Unfreeze{} }
......@@ -131,6 +135,13 @@ func (m *Unfreeze) GetWithdrawTimes() int32 {
return 0
}
func (m *Unfreeze) GetRemaining() int64 {
if m != nil {
return m.Remaining
}
return 0
}
// message for execs.unfreeze
type UnfreezeAction struct {
// Types that are valid to be assigned to Value:
......@@ -138,7 +149,7 @@ type UnfreezeAction struct {
// *UnfreezeAction_Withdraw
// *UnfreezeAction_Terminate
Value isUnfreezeAction_Value `protobuf_oneof:"value"`
Ty int32 `protobuf:"varint,10,opt,name=ty" json:"ty,omitempty"`
Ty int32 `protobuf:"varint,4,opt,name=ty" json:"ty,omitempty"`
}
func (m *UnfreezeAction) Reset() { *m = UnfreezeAction{} }
......@@ -292,15 +303,15 @@ func _UnfreezeAction_OneofSizer(msg proto.Message) (n int) {
return n
}
// action
type UnfreezeCreate struct {
StartTime int64 `protobuf:"varint,1,opt,name=startTime" json:"startTime,omitempty"`
TokenName string `protobuf:"bytes,2,opt,name=tokenName" json:"tokenName,omitempty"`
TotalCount int64 `protobuf:"varint,3,opt,name=totalCount" json:"totalCount,omitempty"`
Initiator string `protobuf:"bytes,4,opt,name=initiator" json:"initiator,omitempty"`
Beneficiary string `protobuf:"bytes,5,opt,name=beneficiary" json:"beneficiary,omitempty"`
Period int64 `protobuf:"varint,6,opt,name=period" json:"period,omitempty"`
Means int32 `protobuf:"varint,7,opt,name=means" json:"means,omitempty"`
Amount int64 `protobuf:"varint,8,opt,name=amount" json:"amount,omitempty"`
Beneficiary string `protobuf:"bytes,4,opt,name=beneficiary" json:"beneficiary,omitempty"`
Period int64 `protobuf:"varint,5,opt,name=period" json:"period,omitempty"`
Means int32 `protobuf:"varint,6,opt,name=means" json:"means,omitempty"`
Amount int64 `protobuf:"varint,7,opt,name=amount" json:"amount,omitempty"`
}
func (m *UnfreezeCreate) Reset() { *m = UnfreezeCreate{} }
......@@ -329,13 +340,6 @@ func (m *UnfreezeCreate) GetTotalCount() int64 {
return 0
}
func (m *UnfreezeCreate) GetInitiator() string {
if m != nil {
return m.Initiator
}
return ""
}
func (m *UnfreezeCreate) GetBeneficiary() string {
if m != nil {
return m.Beneficiary
......@@ -396,49 +400,82 @@ func (m *UnfreezeTerminate) GetUnfreezeID() string {
return ""
}
// TODO: 更多receipt类型
type ReceiptUnfreeze struct {
TokenName string `protobuf:"bytes,1,opt,name=tokenName" json:"tokenName,omitempty"`
CreateAddr string `protobuf:"bytes,2,opt,name=createAddr" json:"createAddr,omitempty"`
ReceiveAddr string `protobuf:"bytes,3,opt,name=receiveAddr" json:"receiveAddr,omitempty"`
// receipt
type ReceiptCreate struct {
UnfreezeID string `protobuf:"bytes,1,opt,name=unfreezeID" json:"unfreezeID,omitempty"`
Initiator string `protobuf:"bytes,2,opt,name=initiator" json:"initiator,omitempty"`
}
func (m *ReceiptUnfreeze) Reset() { *m = ReceiptUnfreeze{} }
func (m *ReceiptUnfreeze) String() string { return proto.CompactTextString(m) }
func (*ReceiptUnfreeze) ProtoMessage() {}
func (*ReceiptUnfreeze) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *ReceiptCreate) Reset() { *m = ReceiptCreate{} }
func (m *ReceiptCreate) String() string { return proto.CompactTextString(m) }
func (*ReceiptCreate) ProtoMessage() {}
func (*ReceiptCreate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *ReceiptUnfreeze) GetTokenName() string {
func (m *ReceiptCreate) GetUnfreezeID() string {
if m != nil {
return m.TokenName
return m.UnfreezeID
}
return ""
}
func (m *ReceiptUnfreeze) GetCreateAddr() string {
func (m *ReceiptCreate) GetInitiator() string {
if m != nil {
return m.CreateAddr
return m.Initiator
}
return ""
}
func (m *ReceiptUnfreeze) GetReceiveAddr() string {
type ReceiptWithdraw struct {
WithdrawTimes int32 `protobuf:"varint,1,opt,name=withdrawTimes" json:"withdrawTimes,omitempty"`
Beneficiary string `protobuf:"bytes,3,opt,name=beneficiary" json:"beneficiary,omitempty"`
}
func (m *ReceiptWithdraw) Reset() { *m = ReceiptWithdraw{} }
func (m *ReceiptWithdraw) String() string { return proto.CompactTextString(m) }
func (*ReceiptWithdraw) ProtoMessage() {}
func (*ReceiptWithdraw) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *ReceiptWithdraw) GetWithdrawTimes() int32 {
if m != nil {
return m.ReceiveAddr
return m.WithdrawTimes
}
return 0
}
func (m *ReceiptWithdraw) GetBeneficiary() string {
if m != nil {
return m.Beneficiary
}
return ""
}
type ReceiptTerminate struct {
UnfreezeID string `protobuf:"bytes,1,opt,name=unfreezeID" json:"unfreezeID,omitempty"`
}
func (m *ReceiptTerminate) Reset() { *m = ReceiptTerminate{} }
func (m *ReceiptTerminate) String() string { return proto.CompactTextString(m) }
func (*ReceiptTerminate) ProtoMessage() {}
func (*ReceiptTerminate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *ReceiptTerminate) GetUnfreezeID() string {
if m != nil {
return m.UnfreezeID
}
return ""
}
type QueryWithdraw struct {
// query
type QueryWithdrawStatus struct {
UnfreezeID string `protobuf:"bytes,1,opt,name=unfreezeID" json:"unfreezeID,omitempty"`
}
func (m *QueryWithdraw) Reset() { *m = QueryWithdraw{} }
func (m *QueryWithdraw) String() string { return proto.CompactTextString(m) }
func (*QueryWithdraw) ProtoMessage() {}
func (*QueryWithdraw) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *QueryWithdrawStatus) Reset() { *m = QueryWithdrawStatus{} }
func (m *QueryWithdrawStatus) String() string { return proto.CompactTextString(m) }
func (*QueryWithdrawStatus) ProtoMessage() {}
func (*QueryWithdrawStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *QueryWithdraw) GetUnfreezeID() string {
func (m *QueryWithdrawStatus) GetUnfreezeID() string {
if m != nil {
return m.UnfreezeID
}
......@@ -451,39 +488,43 @@ func init() {
proto.RegisterType((*UnfreezeCreate)(nil), "types.UnfreezeCreate")
proto.RegisterType((*UnfreezeWithdraw)(nil), "types.UnfreezeWithdraw")
proto.RegisterType((*UnfreezeTerminate)(nil), "types.UnfreezeTerminate")
proto.RegisterType((*ReceiptUnfreeze)(nil), "types.ReceiptUnfreeze")
proto.RegisterType((*QueryWithdraw)(nil), "types.QueryWithdraw")
proto.RegisterType((*ReceiptCreate)(nil), "types.ReceiptCreate")
proto.RegisterType((*ReceiptWithdraw)(nil), "types.ReceiptWithdraw")
proto.RegisterType((*ReceiptTerminate)(nil), "types.ReceiptTerminate")
proto.RegisterType((*QueryWithdrawStatus)(nil), "types.QueryWithdrawStatus")
}
func init() { proto.RegisterFile("unfreeze.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 432 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4d, 0x8f, 0xd3, 0x30,
0x10, 0x6d, 0xd2, 0x4d, 0xda, 0x4e, 0xb5, 0x05, 0x2c, 0x3e, 0x7c, 0x40, 0xa8, 0x8a, 0x38, 0xf4,
0xd4, 0x95, 0xba, 0x42, 0xe2, 0xba, 0x2c, 0x87, 0x72, 0x41, 0x22, 0x5a, 0xc4, 0xd9, 0xdb, 0xce,
0x0a, 0x8b, 0x8d, 0x1d, 0x9c, 0xc9, 0x56, 0xe1, 0x67, 0xf1, 0x37, 0xf8, 0x37, 0xfc, 0x02, 0x64,
0x3b, 0x69, 0xd3, 0x52, 0xa5, 0x7b, 0x9c, 0x37, 0xef, 0x4d, 0x3c, 0xef, 0xd9, 0x81, 0x49, 0xa9,
0xee, 0x0c, 0xe2, 0x2f, 0x9c, 0xe7, 0x46, 0x93, 0x66, 0x11, 0x55, 0x39, 0x16, 0xc9, 0xef, 0x10,
0x86, 0x5f, 0xeb, 0x0e, 0x7b, 0x03, 0xd0, 0xb0, 0x3e, 0x7d, 0xe4, 0xc1, 0x34, 0x98, 0x8d, 0xd2,
0x16, 0xc2, 0x5e, 0xc3, 0xa8, 0x20, 0x61, 0xe8, 0x46, 0x66, 0xc8, 0xc3, 0x69, 0x30, 0xeb, 0xa7,
0x3b, 0xc0, 0x76, 0x49, 0xff, 0x40, 0xf5, 0x59, 0x64, 0xc8, 0xfb, 0x4e, 0xbc, 0x03, 0xec, 0x6c,
0xd2, 0x24, 0xee, 0xaf, 0x75, 0xa9, 0x88, 0x9f, 0x39, 0x71, 0x0b, 0xb1, 0x6a, 0xa9, 0x24, 0x49,
0x41, 0xda, 0xf0, 0xc8, 0xab, 0xb7, 0x00, 0x9b, 0xc2, 0xf8, 0x16, 0x15, 0xde, 0xc9, 0x95, 0x14,
0xa6, 0xe2, 0xb1, 0xeb, 0xb7, 0x21, 0xf6, 0x12, 0xe2, 0x1c, 0x8d, 0xd4, 0x6b, 0x3e, 0x70, 0xb3,
0xeb, 0x8a, 0x3d, 0x87, 0x28, 0x43, 0xa1, 0x0a, 0x3e, 0x9c, 0x06, 0xb3, 0x28, 0xf5, 0x85, 0x65,
0x8b, 0xcc, 0x9d, 0x64, 0xe4, 0xd9, 0xbe, 0x62, 0x6f, 0xe1, 0x7c, 0x23, 0xe9, 0xfb, 0xda, 0x88,
0x8d, 0xdd, 0xa9, 0xe0, 0xe0, 0x54, 0xfb, 0x60, 0xf2, 0x27, 0x80, 0x49, 0x63, 0xda, 0xd5, 0x8a,
0xa4, 0x56, 0xec, 0x02, 0xe2, 0x95, 0x41, 0x41, 0xe8, 0x6c, 0x1b, 0x2f, 0x5e, 0xcc, 0x9d, 0xbf,
0xf3, 0x86, 0x76, 0xed, 0x9a, 0xcb, 0x5e, 0x5a, 0xd3, 0xd8, 0x3b, 0x18, 0x36, 0x43, 0x9d, 0x95,
0xe3, 0xc5, 0xab, 0x03, 0xc9, 0xb7, 0xba, 0xbd, 0xec, 0xa5, 0x5b, 0x2a, 0x7b, 0x0f, 0x23, 0x42,
0x93, 0x49, 0x65, 0x3f, 0xd5, 0x77, 0x3a, 0x7e, 0xa0, 0xbb, 0x69, 0xfa, 0xcb, 0x5e, 0xba, 0x23,
0xb3, 0x09, 0x84, 0x54, 0xd5, 0xfb, 0x84, 0x54, 0x7d, 0x18, 0x40, 0xf4, 0x20, 0xee, 0x4b, 0x4c,
0xfe, 0xb6, 0xb6, 0xf1, 0xc7, 0xdc, 0x0f, 0x3a, 0xe8, 0x0c, 0x3a, 0xec, 0x0e, 0xba, 0xdf, 0x1d,
0xf4, 0xd9, 0x89, 0xa0, 0xa3, 0xae, 0xa0, 0xe3, 0xe3, 0x41, 0x0f, 0x8e, 0x07, 0x3d, 0x6c, 0x07,
0x9d, 0x2c, 0xe0, 0xe9, 0xa1, 0xcf, 0xa7, 0xae, 0x7f, 0x72, 0x09, 0xcf, 0xfe, 0xf3, 0xf8, 0xa4,
0xe8, 0x27, 0x3c, 0x49, 0x71, 0x85, 0x32, 0xa7, 0xed, 0x33, 0xdb, 0xf3, 0x2f, 0x38, 0xe2, 0x9f,
0xbf, 0x22, 0x57, 0xeb, 0xb5, 0xa9, 0xed, 0x6d, 0x21, 0xd6, 0x21, 0x63, 0x07, 0x3e, 0x78, 0x82,
0x7f, 0x68, 0x6d, 0x28, 0xb9, 0x80, 0xf3, 0x2f, 0x25, 0x9a, 0xea, 0xb1, 0x8b, 0xdd, 0xc6, 0xee,
0x97, 0x70, 0xf9, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x73, 0x88, 0x4e, 0x63, 0x24, 0x04, 0x00, 0x00,
// 459 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0x8d, 0xed, 0xda, 0x49, 0x26, 0x6a, 0x80, 0xe5, 0x6b, 0x0f, 0x08, 0x45, 0x16, 0x87, 0x9c,
0x82, 0x94, 0xaa, 0x12, 0x57, 0x28, 0x87, 0x70, 0x00, 0x89, 0xa5, 0x08, 0x71, 0xdc, 0xa6, 0x53,
0x58, 0x51, 0xef, 0x46, 0xeb, 0x31, 0x95, 0xf9, 0x8b, 0x5c, 0x38, 0xf0, 0x83, 0xaa, 0x5d, 0xdb,
0x89, 0xeb, 0x44, 0x49, 0x8f, 0xfb, 0xe6, 0xbd, 0xf1, 0xec, 0x9b, 0xb7, 0x86, 0x71, 0xa1, 0xaf,
0x2c, 0xe2, 0x1f, 0x9c, 0xad, 0xac, 0x21, 0xc3, 0x62, 0x2a, 0x57, 0x98, 0xa7, 0xff, 0x42, 0x18,
0x7c, 0xad, 0x2b, 0xec, 0x25, 0x40, 0xc3, 0xfa, 0xf0, 0x9e, 0x07, 0x93, 0x60, 0x3a, 0x14, 0x2d,
0x84, 0xbd, 0x80, 0x61, 0x4e, 0xd2, 0xd2, 0xb9, 0xca, 0x90, 0x87, 0x93, 0x60, 0x1a, 0x89, 0x0d,
0xe0, 0xaa, 0x64, 0x7e, 0xa1, 0xfe, 0x24, 0x33, 0xe4, 0x91, 0x17, 0x6f, 0x00, 0xd7, 0x9b, 0x0c,
0xc9, 0xeb, 0x33, 0x53, 0x68, 0xe2, 0x47, 0x5e, 0xdc, 0x42, 0x9c, 0x5a, 0x69, 0x45, 0x4a, 0x92,
0xb1, 0x3c, 0xae, 0xd4, 0x6b, 0x80, 0x4d, 0x60, 0x74, 0x81, 0x1a, 0xaf, 0xd4, 0x52, 0x49, 0x5b,
0xf2, 0xc4, 0xd7, 0xdb, 0x10, 0x7b, 0x06, 0xc9, 0x0a, 0xad, 0x32, 0x97, 0xbc, 0xef, 0x7b, 0xd7,
0x27, 0xf6, 0x04, 0xe2, 0x0c, 0xa5, 0xce, 0xf9, 0x60, 0x12, 0x4c, 0x63, 0x51, 0x1d, 0x1c, 0x5b,
0x66, 0x7e, 0x92, 0x61, 0xc5, 0xae, 0x4e, 0xec, 0x15, 0x1c, 0xdf, 0x28, 0xfa, 0x79, 0x69, 0xe5,
0x8d, 0xbb, 0x53, 0xce, 0xc1, 0xab, 0xee, 0x82, 0x6e, 0x56, 0x8b, 0x99, 0x54, 0x5a, 0xe9, 0x1f,
0x7c, 0x54, 0xf9, 0xb0, 0x06, 0xd2, 0xbf, 0x01, 0x8c, 0x1b, 0x4b, 0xdf, 0x2e, 0x49, 0x19, 0xcd,
0x5e, 0x43, 0xb2, 0xb4, 0x28, 0x09, 0xbd, 0xa9, 0xa3, 0xf9, 0xd3, 0x99, 0x77, 0x7f, 0xd6, 0xd0,
0xce, 0x7c, 0x71, 0xd1, 0x13, 0x35, 0x8d, 0x9d, 0xc2, 0xa0, 0xf9, 0xa4, 0x37, 0x7a, 0x34, 0x7f,
0xde, 0x91, 0x7c, 0xab, 0xcb, 0x8b, 0x9e, 0x58, 0x53, 0xd9, 0x1b, 0x18, 0x12, 0xda, 0x4c, 0x69,
0xf7, 0xa9, 0xc8, 0xeb, 0x78, 0x47, 0x77, 0xde, 0xd4, 0x17, 0x3d, 0xb1, 0x21, 0xb3, 0x31, 0x84,
0x54, 0xfa, 0xb5, 0xc4, 0x22, 0xa4, 0xf2, 0x5d, 0x1f, 0xe2, 0xdf, 0xf2, 0xba, 0xc0, 0xf4, 0x7f,
0xeb, 0x36, 0xd5, 0x98, 0x77, 0x63, 0x10, 0xec, 0x8d, 0x41, 0xb8, 0x3f, 0x06, 0xd1, 0x56, 0x0c,
0x3a, 0x8b, 0x3e, 0xda, 0xb7, 0xe8, 0x78, 0xf7, 0xa2, 0x93, 0xdd, 0x8b, 0xee, 0xb7, 0x17, 0x9d,
0xce, 0xe1, 0x61, 0xd7, 0xc9, 0x43, 0xf1, 0x4f, 0x4f, 0xe0, 0xd1, 0x96, 0x8b, 0x07, 0x45, 0x1f,
0xe1, 0x58, 0xe0, 0x12, 0xd5, 0x8a, 0x6a, 0xf7, 0xee, 0xf1, 0xc8, 0x36, 0x0f, 0x21, 0xec, 0x3c,
0x84, 0xf4, 0x3b, 0x3c, 0xa8, 0xdb, 0xad, 0xc7, 0xde, 0xca, 0x6c, 0xb0, 0x2b, 0xb3, 0x1d, 0x63,
0xa3, 0x2d, 0x63, 0x9d, 0x25, 0x75, 0xeb, 0xfb, 0xdf, 0xee, 0x14, 0x1e, 0x7f, 0x2e, 0xd0, 0x96,
0xcd, 0x30, 0x5f, 0x48, 0x52, 0x91, 0x1f, 0x92, 0x5d, 0x24, 0xfe, 0x1f, 0x74, 0x72, 0x1b, 0x00,
0x00, 0xff, 0xff, 0xb5, 0x01, 0xb3, 0xc9, 0x95, 0x04, 0x00, 0x00,
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment