diff --git a/gossip/gossip/channel/channel.go b/gossip/gossip/channel/channel.go index 94d6061c75f..ea9c0c6a8d3 100644 --- a/gossip/gossip/channel/channel.go +++ b/gossip/gossip/channel/channel.go @@ -76,6 +76,9 @@ type GossipChannel interface { // that are eligible to be in the channel ConfigureChannel(joinMsg api.JoinChannelMessage) + // LeaveChannel makes the peer leave the channel + LeaveChannel() + // Stop stops the channel's activity Stop() } @@ -134,6 +137,7 @@ type gossipChannel struct { stateInfoRequestScheduler *time.Ticker memFilter *membershipFilter ledgerHeight uint64 + leftChannel int32 } type membershipFilter struct { @@ -143,6 +147,9 @@ type membershipFilter struct { // GetMembership returns the known alive peers and their information func (mf *membershipFilter) GetMembership() []discovery.NetworkMember { + if mf.hasLeftChannel() { + return nil + } var members []discovery.NetworkMember for _, mem := range mf.adapter.GetMembership() { if mf.eligibleForChannelAndSameOrg(mem) { @@ -269,9 +276,21 @@ func (gc *gossipChannel) periodicalInvocation(fn func(), c <-chan time.Time) { } } +// LeaveChannel makes the peer leave the channel +func (gc *gossipChannel) LeaveChannel() { + atomic.StoreInt32(&gc.leftChannel, 1) +} + +func (gc *gossipChannel) hasLeftChannel() bool { + return atomic.LoadInt32(&gc.leftChannel) == 1 +} + // GetPeers returns a list of peers with metadata as published by them func (gc *gossipChannel) GetPeers() []discovery.NetworkMember { members := []discovery.NetworkMember{} + if gc.hasLeftChannel() { + return members + } for _, member := range gc.GetMembership() { if !gc.EligibleForChannel(member) { @@ -281,6 +300,10 @@ func (gc *gossipChannel) GetPeers() []discovery.NetworkMember { if stateInf == nil { continue } + props := stateInf.GetStateInfo().Properties + if props != nil && props.LeftChannel { + continue + } member.Metadata = stateInf.GetStateInfo().Metadata member.Properties = stateInf.GetStateInfo().Properties members = append(members, member) @@ -530,6 +553,10 @@ func (gc *gossipChannel) HandleMessage(msg proto.ReceivedMessage) { } if m.IsPullMsg() && m.GetPullMsgType() == proto.PullMsgType_BLOCK_MSG { + if gc.hasLeftChannel() { + gc.logger.Info("Received Pull message from", msg.GetConnectionInfo().Endpoint, "but left the channel", string(gc.chainID)) + return + } // If we don't have a StateInfo message from the peer, // no way of validating its eligibility in the channel. if gc.stateInfoMsgStore.MsgByID(msg.GetConnectionInfo().ID) == nil { diff --git a/gossip/gossip/channel/channel_test.go b/gossip/gossip/channel/channel_test.go index 8a47cea78e9..42128aa4a94 100644 --- a/gossip/gossip/channel/channel_test.go +++ b/gossip/gossip/channel/channel_test.go @@ -374,6 +374,81 @@ func TestMsgStoreNotExpire(t *testing.T) { assert.Len(t, c, 2) } +func TestLeaveChannel(t *testing.T) { + // Scenario: Have our peer receive a stateInfo message + // from a peer that has left the channel, and ensure that it skips it + // when returning membership. + // Next, have our own peer leave the channel and ensure: + // 1) It doesn't return any members of the channel when queried + // 2) It doesn't send anymore pull for blocks + // 3) When asked for pull for blocks, it ignores the request + t.Parallel() + + jcm := &joinChanMsg{ + members2AnchorPeers: map[string][]api.AnchorPeer{ + "ORG1": {}, + "ORG2": {}, + }, + } + + cs := &cryptoService{} + cs.On("VerifyBlock", mock.Anything).Return(nil) + adapter := new(gossipAdapterMock) + adapter.On("Gossip", mock.Anything) + adapter.On("DeMultiplex", mock.Anything) + members := []discovery.NetworkMember{ + {PKIid: pkiIDInOrg1}, + {PKIid: pkiIDinOrg2}, + } + var helloPullWG sync.WaitGroup + helloPullWG.Add(1) + configureAdapter(adapter, members...) + gc := NewGossipChannel(common.PKIidType("p0"), orgInChannelA, cs, channelA, adapter, jcm) + adapter.On("Send", mock.Anything, mock.Anything).Run(func(arguments mock.Arguments) { + msg := arguments.Get(0).(*proto.SignedGossipMessage) + if msg.IsPullMsg() { + helloPullWG.Done() + assert.False(t, gc.(*gossipChannel).hasLeftChannel()) + } + }) + gc.HandleMessage(&receivedMsg{PKIID: pkiIDInOrg1, msg: createStateInfoMsg(1, pkiIDInOrg1, channelA)}) + gc.HandleMessage(&receivedMsg{PKIID: pkiIDinOrg2, msg: createStateInfoMsg(1, pkiIDinOrg2, channelA)}) + // Have some peer send a block to us, so we can send some peer a digest when hello is sent to us + gc.HandleMessage(&receivedMsg{msg: createDataMsg(2, channelA), PKIID: pkiIDInOrg1}) + assert.Len(t, gc.GetPeers(), 2) + // Now, have peer in org2 "leave the channel" by publishing is an update + stateInfoMsg := &receivedMsg{PKIID: pkiIDinOrg2, msg: createStateInfoMsg(0, pkiIDinOrg2, channelA)} + stateInfoMsg.GetGossipMessage().GetStateInfo().Properties.LeftChannel = true + gc.HandleMessage(stateInfoMsg) + assert.Len(t, gc.GetPeers(), 1) + // Ensure peer in org1 remained and peer in org2 is skipped + assert.Equal(t, pkiIDInOrg1, gc.GetPeers()[0].PKIid) + var digestSendTime int32 + var DigestSentWg sync.WaitGroup + DigestSentWg.Add(1) + hello := createHelloMsg(pkiIDInOrg1) + hello.On("Respond", mock.Anything).Run(func(arguments mock.Arguments) { + atomic.AddInt32(&digestSendTime, 1) + // Ensure we only respond with digest before we leave the channel + assert.Equal(t, int32(1), atomic.LoadInt32(&digestSendTime)) + DigestSentWg.Done() + }) + // Wait until we send a hello pull message + helloPullWG.Wait() + go gc.HandleMessage(hello) + DigestSentWg.Wait() + // Make the peer leave the channel + gc.LeaveChannel() + // Send another hello. Shouldn't respond + go gc.HandleMessage(hello) + // Ensure it doesn't know now any other peer + assert.Len(t, gc.GetPeers(), 0) + // Sleep 3 times the pull interval. + // we're not supposed to send a pull during this time. + time.Sleep(conf.PullInterval * 3) + +} + func TestChannelPeriodicalPublishStateInfo(t *testing.T) { t.Parallel() ledgerHeight := 5 diff --git a/gossip/gossip/gossip.go b/gossip/gossip/gossip.go index e4c717c5e97..f63aff4a786 100644 --- a/gossip/gossip/gossip.go +++ b/gossip/gossip/gossip.go @@ -58,6 +58,12 @@ type Gossip interface { // JoinChan makes the Gossip instance join a channel JoinChan(joinMsg api.JoinChannelMessage, chainID common.ChainID) + // LeaveChan makes the Gossip instance leave a channel. + // It still disseminates stateInfo message, but doesn't participate + // in block pulling anymore, and can't return anymore a list of peers + // in the channel. + LeaveChan(chainID common.ChainID) + // SuspectPeers makes the gossip instance validate identities of suspected peers, and close // any connections to peers with identities that are found invalid SuspectPeers(s api.PeerSuspector) diff --git a/gossip/gossip/gossip_impl.go b/gossip/gossip/gossip_impl.go index d6648e1793e..aa21d2cd6dc 100644 --- a/gossip/gossip/gossip_impl.go +++ b/gossip/gossip/gossip_impl.go @@ -188,6 +188,22 @@ func (g *gossipServiceImpl) JoinChan(joinMsg api.JoinChannelMessage, chainID com } } +func (g *gossipServiceImpl) LeaveChan(chainID common.ChainID) { + gc := g.chanState.getGossipChannelByChainID(chainID) + if gc == nil { + g.logger.Debug("No such channel", chainID) + return + } + b, _ := (&common.NodeMetastate{}).Bytes() + stateInfMsg, err := g.createStateInfoMsg(b, chainID, true) + if err != nil { + g.logger.Errorf("Failed creating StateInfo message: %+v", errors.WithStack(err)) + return + } + gc.UpdateStateInfo(stateInfMsg) + gc.LeaveChannel() +} + // SuspectPeers makes the gossip instance validate identities of suspected peers, and close // any connections to peers with identities that are found invalid func (g *gossipServiceImpl) SuspectPeers(isSuspected api.PeerSuspector) { @@ -733,7 +749,7 @@ func (g *gossipServiceImpl) UpdateChannelMetadata(md []byte, chainID common.Chai g.logger.Debug("No such channel", chainID) return } - stateInfMsg, err := g.createStateInfoMsg(md, chainID) + stateInfMsg, err := g.createStateInfoMsg(md, chainID, false) if err != nil { g.logger.Errorf("Failed creating StateInfo message: %+v", errors.WithStack(err)) return @@ -1088,7 +1104,7 @@ func (g *gossipServiceImpl) connect2BootstrapPeers() { } -func (g *gossipServiceImpl) createStateInfoMsg(metadata []byte, chainID common.ChainID) (*proto.SignedGossipMessage, error) { +func (g *gossipServiceImpl) createStateInfoMsg(metadata []byte, chainID common.ChainID, leftChannel bool) (*proto.SignedGossipMessage, error) { metaState, err := common.FromBytes(metadata) if err != nil { return nil, err @@ -1106,6 +1122,9 @@ func (g *gossipServiceImpl) createStateInfoMsg(metadata []byte, chainID common.C LedgerHeight: metaState.LedgerHeight, }, } + if leftChannel { + stateInfMsg.Properties.LeftChannel = true + } m := &proto.GossipMessage{ Nonce: 0, Tag: proto.GossipMessage_CHAN_OR_ORG, diff --git a/gossip/gossip/gossip_test.go b/gossip/gossip/gossip_test.go index 1a18137d131..7a5ec0119e3 100644 --- a/gossip/gossip/gossip_test.go +++ b/gossip/gossip/gossip_test.go @@ -42,6 +42,7 @@ var tests = []func(t *testing.T){ TestMembershipConvergence, TestMembershipRequestSpoofing, TestDataLeakage, + TestLeaveChannel, //TestDisseminateAll2All: {}, TestIdentityExpiration, TestSendByCriteria, @@ -272,6 +273,50 @@ func newGossipInstanceWithOnlyPull(portPrefix int, id int, maxMsgCount int, boot return g } +func TestLeaveChannel(t *testing.T) { + t.Parallel() + defer testWG.Done() + portPrefix := 4500 + // Scenario: Have 3 peers in a channel and make one of them leave it. + // Ensure the peers don't recognize the other peer when it left the channel + + p0 := newGossipInstance(portPrefix, 0, 100, 2) + p0.JoinChan(&joinChanMsg{}, common.ChainID("A")) + p0.UpdateChannelMetadata(createMetadata(1), common.ChainID("A")) + defer p0.Stop() + + p1 := newGossipInstance(portPrefix, 1, 100, 0) + p1.JoinChan(&joinChanMsg{}, common.ChainID("A")) + p1.UpdateChannelMetadata(createMetadata(1), common.ChainID("A")) + defer p1.Stop() + + p2 := newGossipInstance(portPrefix, 2, 100, 1) + p2.JoinChan(&joinChanMsg{}, common.ChainID("A")) + p2.UpdateChannelMetadata(createMetadata(1), common.ChainID("A")) + defer p2.Stop() + + countMembership := func(g Gossip, expected int) func() bool { + return func() bool { + peers := g.PeersOfChannel(common.ChainID("A")) + return len(peers) == expected + } + } + + // Wait until everyone sees each other in the channel + waitUntilOrFail(t, countMembership(p0, 2)) + waitUntilOrFail(t, countMembership(p1, 2)) + waitUntilOrFail(t, countMembership(p2, 2)) + + // Now p2 leaves the channel + p2.LeaveChan(common.ChainID("A")) + + // Ensure channel membership is adjusted accordingly + waitUntilOrFail(t, countMembership(p0, 1)) + waitUntilOrFail(t, countMembership(p1, 1)) + waitUntilOrFail(t, countMembership(p2, 0)) + +} + func TestPull(t *testing.T) { t.Parallel() defer testWG.Done() diff --git a/gossip/service/join_test.go b/gossip/service/join_test.go index 1bb37bab4b3..f2d7589dfb1 100644 --- a/gossip/service/join_test.go +++ b/gossip/service/join_test.go @@ -80,6 +80,10 @@ func (g *gossipMock) JoinChan(joinMsg api.JoinChannelMessage, chainID common.Cha g.Called(joinMsg, chainID) } +func (g *gossipMock) LeaveChan(chainID common.ChainID) { + panic("implement me") +} + func (*gossipMock) Stop() { panic("implement me") } diff --git a/gossip/state/mocks/gossip.go b/gossip/state/mocks/gossip.go index c5214cae72c..95b47e748ca 100644 --- a/gossip/state/mocks/gossip.go +++ b/gossip/state/mocks/gossip.go @@ -30,6 +30,10 @@ func (g *GossipMock) SuspectPeers(s api.PeerSuspector) { } +func (g *GossipMock) LeaveChan(_ common.ChainID) { + panic("implement me") +} + func (g *GossipMock) Send(msg *proto.GossipMessage, peers ...*comm.RemotePeer) { g.Called(msg, peers) } diff --git a/protos/gossip/message.pb.go b/protos/gossip/message.pb.go index e23d3e9ea93..c360327bd21 100644 --- a/protos/gossip/message.pb.go +++ b/protos/gossip/message.pb.go @@ -1040,6 +1040,7 @@ func (m *StateInfo) GetProperties() *Properties { type Properties struct { LedgerHeight uint64 `protobuf:"varint,1,opt,name=ledger_height,json=ledgerHeight" json:"ledger_height,omitempty"` + LeftChannel bool `protobuf:"varint,2,opt,name=left_channel,json=leftChannel" json:"left_channel,omitempty"` } func (m *Properties) Reset() { *m = Properties{} } @@ -1054,6 +1055,13 @@ func (m *Properties) GetLedgerHeight() uint64 { return 0 } +func (m *Properties) GetLeftChannel() bool { + if m != nil { + return m.LeftChannel + } + return false +} + // StateInfoSnapshot is an aggregation of StateInfo messages type StateInfoSnapshot struct { Elements []*Envelope `protobuf:"bytes,1,rep,name=elements" json:"elements,omitempty"` @@ -1942,112 +1950,113 @@ var _Gossip_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("gossip/message.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1710 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0x7b, 0x6f, 0xe4, 0x48, - 0x11, 0x1f, 0x27, 0xf3, 0x72, 0xcd, 0x23, 0x93, 0x4e, 0x76, 0xd7, 0xe4, 0x8e, 0x23, 0x18, 0xf6, - 0x6e, 0x21, 0x77, 0xc9, 0x91, 0x03, 0x71, 0xd2, 0x01, 0xa7, 0x24, 0x33, 0x64, 0x46, 0xb7, 0x93, - 0x0d, 0x4e, 0x56, 0x10, 0x84, 0x64, 0x75, 0xec, 0x8e, 0xc7, 0xc4, 0x6e, 0x3b, 0xee, 0xce, 0x92, - 0xfc, 0x89, 0xf8, 0x8f, 0x6f, 0xc1, 0x67, 0x41, 0xe2, 0x73, 0xa1, 0xee, 0xf6, 0x33, 0x9e, 0x39, - 0x69, 0x57, 0xba, 0xff, 0xa6, 0x1e, 0xbf, 0xaa, 0xae, 0xea, 0xaa, 0xea, 0xf2, 0xc0, 0xb6, 0x17, - 0x31, 0xe6, 0xc7, 0x07, 0x21, 0x61, 0x0c, 0x7b, 0x64, 0x3f, 0x4e, 0x22, 0x1e, 0xa1, 0xb6, 0xe2, - 0x9a, 0xff, 0xd2, 0xa0, 0x3b, 0xa1, 0xef, 0x48, 0x10, 0xc5, 0x04, 0x19, 0xd0, 0x89, 0xf1, 0x63, - 0x10, 0x61, 0xd7, 0xd0, 0x76, 0xb5, 0x57, 0x7d, 0x2b, 0x23, 0xd1, 0xc7, 0xa0, 0x33, 0xdf, 0xa3, - 0x98, 0xdf, 0x27, 0xc4, 0x58, 0x93, 0xb2, 0x82, 0x81, 0xbe, 0x85, 0x0d, 0x46, 0x9c, 0x84, 0x70, - 0x9b, 0xa4, 0xa6, 0x8c, 0xf5, 0x5d, 0xed, 0x55, 0xef, 0xf0, 0xf9, 0xbe, 0x72, 0xb3, 0x7f, 0x21, - 0xc5, 0x99, 0x23, 0x6b, 0xc8, 0x2a, 0xb4, 0x39, 0x85, 0x61, 0x55, 0xe3, 0x43, 0x8f, 0x62, 0x1e, - 0x41, 0x5b, 0x59, 0x42, 0x9f, 0xc3, 0xc8, 0xa7, 0x9c, 0x24, 0x14, 0x07, 0x13, 0xea, 0xc6, 0x91, - 0x4f, 0xb9, 0x34, 0xa5, 0x4f, 0x1b, 0x56, 0x4d, 0x72, 0xac, 0x43, 0xc7, 0x89, 0x28, 0x27, 0x94, - 0x9b, 0xff, 0x03, 0x18, 0x9c, 0xca, 0x63, 0xcf, 0x55, 0xca, 0xd0, 0x36, 0xb4, 0x68, 0x44, 0x1d, - 0x22, 0xf1, 0x4d, 0x4b, 0x11, 0xe2, 0x88, 0xce, 0x02, 0x53, 0x4a, 0x82, 0xf4, 0x18, 0x19, 0x89, - 0xf6, 0x60, 0x9d, 0x63, 0x4f, 0xe6, 0x60, 0x78, 0xf8, 0xa3, 0x2c, 0x07, 0x15, 0x9b, 0xfb, 0x97, - 0xd8, 0xb3, 0x84, 0x16, 0xfa, 0x0a, 0x74, 0x1c, 0xf8, 0xef, 0x88, 0x1d, 0x32, 0xcf, 0x68, 0xc9, - 0xb4, 0x6d, 0x67, 0x90, 0x23, 0x21, 0x48, 0x11, 0xd3, 0x86, 0xd5, 0x95, 0x8a, 0x73, 0xe6, 0xa1, - 0x5f, 0x43, 0x27, 0x24, 0xa1, 0x9d, 0x90, 0x3b, 0xa3, 0x2d, 0x21, 0xb9, 0x97, 0x39, 0x09, 0xaf, - 0x49, 0xc2, 0x16, 0x7e, 0x6c, 0x91, 0xbb, 0x7b, 0xc2, 0xf8, 0xb4, 0x61, 0xb5, 0x43, 0x12, 0x5a, - 0xe4, 0x0e, 0xfd, 0x26, 0x43, 0x31, 0xa3, 0x23, 0x51, 0x3b, 0xcb, 0x50, 0x2c, 0x8e, 0x28, 0x23, - 0x39, 0x8c, 0xa1, 0x2f, 0xa1, 0xeb, 0x62, 0x8e, 0xe5, 0x01, 0xbb, 0x12, 0xb7, 0x95, 0xe1, 0xc6, - 0x98, 0xe3, 0xe2, 0x7c, 0x1d, 0xa1, 0x26, 0x8e, 0xb7, 0x07, 0xad, 0x05, 0x09, 0x82, 0xc8, 0xd0, - 0xab, 0xea, 0x2a, 0x05, 0x53, 0x21, 0x9a, 0x36, 0x2c, 0xa5, 0x83, 0x0e, 0x52, 0xf3, 0xae, 0xef, - 0x19, 0x20, 0xf5, 0x51, 0xd9, 0xfc, 0xd8, 0xf7, 0x54, 0x14, 0xd2, 0xfa, 0xd8, 0xf7, 0xf2, 0xf3, - 0x88, 0xe8, 0x7b, 0xf5, 0xf3, 0x14, 0x71, 0x4b, 0x84, 0x0a, 0xbc, 0x27, 0x11, 0xf7, 0xb1, 0x8b, - 0x39, 0x31, 0xfa, 0x75, 0x2f, 0x6f, 0xa5, 0x64, 0xda, 0xb0, 0xc0, 0xcd, 0x29, 0xf4, 0x12, 0x5a, - 0x24, 0x8c, 0xf9, 0xa3, 0x31, 0x90, 0x80, 0x41, 0x06, 0x98, 0x08, 0xa6, 0x08, 0x40, 0x4a, 0xd1, - 0x1e, 0x34, 0x9d, 0x88, 0x52, 0x63, 0x28, 0xb5, 0x9e, 0x65, 0x5a, 0x27, 0x11, 0xa5, 0x13, 0xc6, - 0xf1, 0x75, 0xe0, 0xb3, 0xc5, 0xb4, 0x61, 0x49, 0x25, 0x74, 0x08, 0xc0, 0x38, 0xe6, 0xc4, 0xf6, - 0xe9, 0x4d, 0x64, 0x6c, 0x48, 0xc8, 0x66, 0xde, 0x26, 0x42, 0x32, 0xa3, 0x37, 0x22, 0x3b, 0x3a, - 0xcb, 0x08, 0x74, 0x0c, 0x43, 0x85, 0x61, 0x14, 0xc7, 0x6c, 0x11, 0x71, 0x63, 0x54, 0xbd, 0xf4, - 0x1c, 0x77, 0x91, 0x2a, 0x4c, 0x1b, 0xd6, 0x40, 0x42, 0x32, 0x06, 0x9a, 0xc3, 0x56, 0xe1, 0xd7, - 0x8e, 0xef, 0x83, 0x40, 0xe6, 0x6f, 0x53, 0x1a, 0xfa, 0xb8, 0x66, 0xe8, 0xfc, 0x3e, 0x08, 0x8a, - 0x44, 0x8e, 0xd8, 0x13, 0x3e, 0x3a, 0x02, 0x65, 0x5f, 0x18, 0x11, 0x4a, 0x06, 0xaa, 0x16, 0x94, - 0x45, 0xc2, 0x88, 0x13, 0x69, 0xae, 0x30, 0xd3, 0x67, 0x25, 0x1a, 0x8d, 0xb3, 0xa8, 0x92, 0xb4, - 0xe4, 0x8c, 0x2d, 0x69, 0xe3, 0xa3, 0xa5, 0x36, 0xf2, 0xaa, 0x1c, 0xb0, 0x32, 0x43, 0xe4, 0x26, - 0x20, 0xd8, 0x55, 0xc5, 0x2b, 0x4b, 0x74, 0xbb, 0x9a, 0x9b, 0xd7, 0xb9, 0xb4, 0x28, 0xd4, 0x41, - 0x01, 0x11, 0xe5, 0xfa, 0x0d, 0x0c, 0x62, 0x42, 0x12, 0xdb, 0x77, 0x09, 0xe5, 0x3e, 0x7f, 0x34, - 0x9e, 0x55, 0xdb, 0xf0, 0x9c, 0x90, 0x64, 0x96, 0xca, 0x44, 0x18, 0x71, 0x89, 0x16, 0xcd, 0x8e, - 0x9d, 0x5b, 0xe3, 0xb9, 0x84, 0xbc, 0xc8, 0x3b, 0xd7, 0xb9, 0xa5, 0xd1, 0x3f, 0x02, 0xe2, 0x7a, - 0x24, 0x24, 0x54, 0x04, 0x2f, 0xb4, 0xd0, 0x1f, 0x00, 0xe2, 0xc4, 0x7f, 0xa7, 0xb2, 0x60, 0xbc, - 0xa8, 0x26, 0x5f, 0xc5, 0x7b, 0xfe, 0x8e, 0x57, 0xab, 0xb8, 0x84, 0x40, 0xdf, 0x96, 0xf0, 0xcc, - 0x30, 0x24, 0xfe, 0xc7, 0x2b, 0xf0, 0x79, 0xc6, 0x4a, 0x10, 0xd3, 0x86, 0xf5, 0x4b, 0xec, 0xa1, - 0x01, 0xe8, 0x6f, 0xcf, 0xc6, 0x93, 0x3f, 0xce, 0xce, 0x26, 0xe3, 0x51, 0x03, 0xe9, 0xd0, 0x9a, - 0xcc, 0xcf, 0x2f, 0xaf, 0x46, 0x1a, 0xea, 0x43, 0xf7, 0x8d, 0x75, 0x6a, 0xbf, 0x39, 0x7b, 0x7d, - 0x35, 0x5a, 0x13, 0x7a, 0x27, 0xd3, 0xa3, 0x33, 0x45, 0xae, 0xa3, 0x11, 0xf4, 0x25, 0x79, 0x74, - 0x36, 0xb6, 0xdf, 0x58, 0xa7, 0xa3, 0x26, 0xda, 0x80, 0x9e, 0x52, 0xb0, 0x24, 0xa3, 0x55, 0x1e, - 0xa4, 0xff, 0xd5, 0x40, 0xcf, 0x0b, 0x0a, 0xed, 0x40, 0x37, 0x24, 0x1c, 0x8b, 0xf6, 0x4a, 0x47, - 0x7a, 0x4e, 0xa3, 0x7d, 0xd0, 0xb9, 0x1f, 0x12, 0xc6, 0x71, 0x18, 0xcb, 0x61, 0xda, 0x3b, 0x1c, - 0x95, 0x93, 0x7f, 0xe9, 0x87, 0xc4, 0x2a, 0x54, 0xd0, 0x33, 0x68, 0xc7, 0xb7, 0xbe, 0xed, 0xbb, - 0x72, 0xc6, 0xf6, 0xad, 0x56, 0x7c, 0xeb, 0xcf, 0x5c, 0xf4, 0x13, 0xe8, 0xa5, 0x23, 0xd8, 0x9e, - 0x1f, 0x9d, 0x18, 0x4d, 0x29, 0x83, 0x94, 0x35, 0x3f, 0x3a, 0x11, 0xcd, 0x17, 0x27, 0x51, 0x4c, - 0x12, 0xee, 0x13, 0x96, 0x0e, 0xdb, 0x7c, 0x0c, 0x9c, 0xe7, 0x12, 0xab, 0xa4, 0x65, 0xfe, 0x0a, - 0xa0, 0x90, 0xa0, 0x9f, 0xc1, 0x40, 0x5e, 0x6a, 0x62, 0x2f, 0x88, 0xef, 0x2d, 0x78, 0xfa, 0x24, - 0xf4, 0x15, 0x73, 0x2a, 0x79, 0xe6, 0x11, 0x6c, 0xd6, 0x3a, 0x12, 0x7d, 0x0e, 0x5d, 0x12, 0xc8, - 0x62, 0x60, 0x86, 0xb6, 0xbb, 0x5e, 0x0e, 0x31, 0x7f, 0x17, 0x73, 0x0d, 0xf3, 0xb7, 0xb0, 0xbd, - 0xac, 0x17, 0x9f, 0x86, 0xa8, 0x3d, 0x0d, 0xd1, 0xbc, 0x81, 0x41, 0x65, 0xf0, 0x94, 0x72, 0xa5, - 0x95, 0x73, 0xb5, 0x03, 0xdd, 0xbc, 0xdc, 0xd5, 0xf3, 0x95, 0xd3, 0xc8, 0x84, 0x01, 0x0f, 0x98, - 0xed, 0x90, 0x84, 0xdb, 0x0b, 0xcc, 0x16, 0x69, 0x96, 0x7b, 0x3c, 0x60, 0x27, 0x24, 0xe1, 0x53, - 0xcc, 0x16, 0xe6, 0x5b, 0xe8, 0x97, 0xdb, 0x62, 0x95, 0x1b, 0x04, 0x4d, 0x61, 0x26, 0x75, 0x21, - 0x7f, 0x57, 0x2a, 0x61, 0xbd, 0x5a, 0x09, 0x66, 0x08, 0xbd, 0x52, 0xf5, 0xaf, 0x7e, 0x79, 0x5d, - 0xf9, 0x2a, 0x30, 0x63, 0x6d, 0x77, 0xfd, 0x95, 0x6e, 0x65, 0x24, 0xda, 0x87, 0x6e, 0xc8, 0x3c, - 0x9b, 0x3f, 0xa6, 0x2b, 0xc8, 0xb0, 0x78, 0x1a, 0x44, 0x16, 0xe7, 0xcc, 0xbb, 0x7c, 0x8c, 0x89, - 0xd5, 0x09, 0xd5, 0x0f, 0x33, 0x82, 0x5e, 0xe9, 0x4d, 0x5a, 0xe1, 0xae, 0x7c, 0xde, 0xb5, 0x5a, - 0xe5, 0xbe, 0x9f, 0xc3, 0x07, 0x80, 0xe2, 0xb9, 0x59, 0xe1, 0xef, 0xe7, 0xd0, 0x4c, 0x7d, 0x2d, - 0xaf, 0x92, 0xe6, 0x07, 0x79, 0x0e, 0x94, 0x67, 0xf5, 0x9c, 0xfe, 0xe0, 0x89, 0xfd, 0x5a, 0xdd, - 0x63, 0xb6, 0x41, 0xfd, 0xa2, 0xba, 0xce, 0xf5, 0x0e, 0x37, 0x72, 0xb4, 0x62, 0xe7, 0xfb, 0x9d, - 0x79, 0x05, 0x9d, 0x94, 0x87, 0x5e, 0x40, 0x87, 0x91, 0x3b, 0x9b, 0xde, 0x87, 0xe9, 0x31, 0xdb, - 0x8c, 0xdc, 0x9d, 0xdd, 0x87, 0xa2, 0xaa, 0x4a, 0xb7, 0xa1, 0xf2, 0xf1, 0x53, 0xe8, 0xa7, 0x73, - 0xce, 0x4e, 0x2b, 0x6b, 0x5d, 0xd4, 0x6c, 0xca, 0x13, 0x87, 0x31, 0xff, 0x06, 0xc3, 0x73, 0x45, - 0x66, 0x1e, 0x3e, 0x83, 0x0d, 0x27, 0x0a, 0x02, 0xe2, 0x70, 0x3f, 0xa2, 0x36, 0xc5, 0xa1, 0x4a, - 0x88, 0x6e, 0x0d, 0x0b, 0xf6, 0x19, 0x0e, 0x49, 0xcd, 0xfa, 0x5a, 0xdd, 0xfa, 0xbf, 0x35, 0xe8, - 0x97, 0x17, 0x36, 0xb4, 0x0f, 0x10, 0xe6, 0x7b, 0x55, 0x1a, 0xf7, 0xb0, 0xba, 0x71, 0x59, 0x25, - 0x8d, 0xf7, 0x9e, 0x82, 0xe5, 0x16, 0x6e, 0x56, 0x5b, 0xd8, 0xfc, 0xa7, 0x06, 0x9b, 0xb5, 0x97, - 0x6f, 0x55, 0x93, 0xbe, 0xaf, 0xe3, 0x97, 0x30, 0xf4, 0x99, 0xed, 0x12, 0x27, 0xc0, 0x09, 0x16, - 0x29, 0x92, 0x25, 0xd1, 0xb5, 0x06, 0x3e, 0x1b, 0x17, 0x4c, 0xf3, 0x77, 0xd0, 0xcd, 0xd0, 0xe2, - 0x2a, 0x7d, 0xea, 0x94, 0xaf, 0xd2, 0xa7, 0x8e, 0xb8, 0xca, 0xd2, 0x1d, 0xaf, 0x95, 0xef, 0xd8, - 0xbc, 0x81, 0xcd, 0xda, 0x2e, 0x8b, 0xbe, 0x81, 0x11, 0x23, 0xc1, 0x8d, 0x5c, 0x62, 0x92, 0x50, - 0xf9, 0xd6, 0xaa, 0x07, 0xce, 0xdb, 0x64, 0x43, 0x68, 0xce, 0x0a, 0x45, 0x51, 0xf3, 0xe2, 0x51, - 0xa6, 0xe9, 0xe5, 0x29, 0xc2, 0xbc, 0x06, 0x54, 0xdf, 0x7e, 0xd1, 0xa7, 0xd0, 0x92, 0xcb, 0xf6, - 0xca, 0x51, 0xad, 0xc4, 0xb2, 0x57, 0x09, 0x76, 0xbf, 0xa7, 0x57, 0x09, 0x76, 0xcd, 0x3f, 0x43, - 0x5b, 0xf9, 0x10, 0x77, 0x46, 0x2a, 0x5f, 0x23, 0x56, 0x4e, 0x7f, 0xef, 0x9c, 0x59, 0xfe, 0xe2, - 0x99, 0x1d, 0x68, 0xc9, 0x65, 0xd4, 0xfc, 0x0b, 0xa0, 0xfa, 0xca, 0x25, 0x06, 0x39, 0xe3, 0x38, - 0xe1, 0x76, 0xb5, 0x8d, 0x7a, 0x92, 0x79, 0xa1, 0x7a, 0xe9, 0x13, 0xe8, 0x11, 0xea, 0xda, 0xd5, - 0x4b, 0xd0, 0x09, 0x75, 0x95, 0xdc, 0x3c, 0x86, 0xad, 0x25, 0x8b, 0x18, 0xda, 0x83, 0x6e, 0xda, - 0xb1, 0xd9, 0x73, 0x56, 0x6b, 0xe9, 0x5c, 0xc1, 0x3c, 0x85, 0xed, 0x65, 0xcb, 0x0d, 0x3a, 0x28, - 0xe6, 0x8d, 0xb2, 0x91, 0x2f, 0xcf, 0xa9, 0xa2, 0x9a, 0x56, 0xf9, 0x18, 0x32, 0xff, 0xa3, 0xc1, - 0xa0, 0x22, 0x42, 0x5b, 0xd0, 0xe2, 0x0f, 0x59, 0x45, 0xeb, 0x56, 0x93, 0x3f, 0xcc, 0xe4, 0x37, - 0xa2, 0xe8, 0x65, 0x16, 0x63, 0x47, 0x7d, 0x23, 0xea, 0x56, 0xc1, 0x40, 0x9f, 0x00, 0x14, 0xdd, - 0x2d, 0xf3, 0xa9, 0x5b, 0x25, 0x0e, 0xfa, 0x08, 0xf4, 0xeb, 0x20, 0x72, 0x6e, 0x45, 0x4e, 0x64, - 0x63, 0x35, 0xad, 0xae, 0x64, 0x5c, 0x90, 0x3b, 0xb4, 0x0b, 0x7d, 0x91, 0x2a, 0x9f, 0xda, 0x92, - 0x25, 0x97, 0x88, 0xa6, 0x05, 0x8c, 0xdc, 0xcd, 0xe8, 0xb1, 0xe0, 0x98, 0xdf, 0xc1, 0xb3, 0xa5, - 0x9b, 0x18, 0x3a, 0xac, 0x6d, 0x00, 0xcf, 0x9f, 0x84, 0x3b, 0x51, 0xe2, 0xd2, 0x1e, 0x70, 0x05, - 0xc3, 0xaa, 0x0c, 0x7d, 0x01, 0x6d, 0x95, 0x8d, 0xb4, 0xf0, 0x57, 0xa4, 0x2c, 0x55, 0x2a, 0x7f, - 0x48, 0xab, 0xb2, 0xcf, 0x07, 0xed, 0x9f, 0x72, 0xd3, 0xd9, 0x34, 0x7c, 0x09, 0x1b, 0xfc, 0xc1, - 0xae, 0x84, 0x97, 0xae, 0x37, 0xfc, 0xe1, 0x22, 0x0f, 0xb0, 0x6a, 0xb2, 0xfc, 0x6d, 0x6e, 0x7e, - 0x06, 0x1b, 0x4f, 0x16, 0x5f, 0xd1, 0x74, 0x24, 0x49, 0xa2, 0x24, 0xbd, 0x1f, 0x45, 0xfc, 0xf2, - 0xf7, 0xd0, 0x2b, 0x3d, 0x1b, 0x4f, 0xd7, 0xd1, 0x01, 0xe8, 0xc7, 0xaf, 0xdf, 0x9c, 0x7c, 0x67, - 0xcf, 0x2f, 0x4e, 0x47, 0x9a, 0xd8, 0x3a, 0x67, 0xe3, 0xc9, 0xd9, 0xe5, 0xec, 0xf2, 0x4a, 0x72, - 0xd6, 0x0e, 0xff, 0x0e, 0x6d, 0xf5, 0x6c, 0xa3, 0xaf, 0xa1, 0xaf, 0x7e, 0x5d, 0xf0, 0x84, 0xe0, - 0x10, 0xd5, 0x3a, 0x70, 0xa7, 0xc6, 0x31, 0x1b, 0xaf, 0xb4, 0x2f, 0x35, 0xf4, 0x29, 0x34, 0xcf, - 0x7d, 0xea, 0xa1, 0xea, 0x57, 0xdd, 0x4e, 0x95, 0x34, 0x1b, 0xc7, 0x5f, 0xfc, 0x75, 0xcf, 0xf3, - 0xf9, 0xe2, 0xfe, 0x7a, 0xdf, 0x89, 0xc2, 0x83, 0xc5, 0x63, 0x4c, 0x12, 0xb5, 0xec, 0x1d, 0xdc, - 0xe0, 0xeb, 0xc4, 0x77, 0x0e, 0xe4, 0x1f, 0x2a, 0xec, 0x40, 0xc1, 0xae, 0xdb, 0x92, 0xfc, 0xea, - 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x17, 0xa4, 0x06, 0xf1, 0x77, 0x11, 0x00, 0x00, + // 1722 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x58, 0x6d, 0x4f, 0xe4, 0xc6, + 0x1d, 0xdf, 0x85, 0x7d, 0xf2, 0x7f, 0x1f, 0x58, 0x06, 0xee, 0xce, 0x25, 0x69, 0x4a, 0xdc, 0x5e, + 0x72, 0x2d, 0x09, 0x44, 0xa4, 0x55, 0x23, 0xa5, 0x6d, 0x04, 0xec, 0x96, 0x5d, 0xe5, 0x96, 0xa3, + 0x03, 0xa7, 0x96, 0xaa, 0x92, 0x35, 0xd8, 0x83, 0xd7, 0xc5, 0x1e, 0x1b, 0xcf, 0x70, 0x85, 0x97, + 0x55, 0xdf, 0xf5, 0x5b, 0xf4, 0xb3, 0x54, 0xea, 0xe7, 0xaa, 0x66, 0xc6, 0x8f, 0x18, 0x22, 0xdd, + 0x49, 0x79, 0xb7, 0xff, 0xe7, 0x99, 0xdf, 0xfc, 0x9f, 0xbc, 0xb0, 0xe9, 0x45, 0x9c, 0xfb, 0xf1, + 0x5e, 0x48, 0x39, 0x27, 0x1e, 0xdd, 0x8d, 0x93, 0x48, 0x44, 0xa8, 0xa3, 0xb9, 0xd6, 0xbf, 0x9a, + 0xd0, 0x9b, 0xb2, 0x77, 0x34, 0x88, 0x62, 0x8a, 0x4c, 0xe8, 0xc6, 0xe4, 0x3e, 0x88, 0x88, 0x6b, + 0x36, 0xb7, 0x9b, 0xaf, 0x06, 0x38, 0x23, 0xd1, 0xc7, 0x60, 0x70, 0xdf, 0x63, 0x44, 0xdc, 0x26, + 0xd4, 0x5c, 0x51, 0xb2, 0x82, 0x81, 0xbe, 0x83, 0x35, 0x4e, 0x9d, 0x84, 0x0a, 0x9b, 0xa6, 0xae, + 0xcc, 0xd5, 0xed, 0xe6, 0xab, 0xfe, 0xfe, 0xf3, 0x5d, 0x1d, 0x66, 0xf7, 0x4c, 0x89, 0xb3, 0x40, + 0x78, 0xc4, 0x2b, 0xb4, 0x35, 0x83, 0x51, 0x55, 0xe3, 0x43, 0x8f, 0x62, 0x1d, 0x40, 0x47, 0x7b, + 0x42, 0x5f, 0xc0, 0xd8, 0x67, 0x82, 0x26, 0x8c, 0x04, 0x53, 0xe6, 0xc6, 0x91, 0xcf, 0x84, 0x72, + 0x65, 0xcc, 0x1a, 0xb8, 0x26, 0x39, 0x34, 0xa0, 0xeb, 0x44, 0x4c, 0x50, 0x26, 0xac, 0xff, 0x01, + 0x0c, 0x8f, 0xd5, 0xb1, 0x17, 0x1a, 0x32, 0xb4, 0x09, 0x6d, 0x16, 0x31, 0x87, 0x2a, 0xfb, 0x16, + 0xd6, 0x84, 0x3c, 0xa2, 0xb3, 0x24, 0x8c, 0xd1, 0x20, 0x3d, 0x46, 0x46, 0xa2, 0x1d, 0x58, 0x15, + 0xc4, 0x53, 0x18, 0x8c, 0xf6, 0x7f, 0x92, 0x61, 0x50, 0xf1, 0xb9, 0x7b, 0x4e, 0x3c, 0x2c, 0xb5, + 0xd0, 0xd7, 0x60, 0x90, 0xc0, 0x7f, 0x47, 0xed, 0x90, 0x7b, 0x66, 0x5b, 0xc1, 0xb6, 0x99, 0x99, + 0x1c, 0x48, 0x41, 0x6a, 0x31, 0x6b, 0xe0, 0x9e, 0x52, 0x5c, 0x70, 0x0f, 0xfd, 0x1a, 0xba, 0x21, + 0x0d, 0xed, 0x84, 0xde, 0x98, 0x1d, 0x65, 0x92, 0x47, 0x59, 0xd0, 0xf0, 0x92, 0x26, 0x7c, 0xe9, + 0xc7, 0x98, 0xde, 0xdc, 0x52, 0x2e, 0x66, 0x0d, 0xdc, 0x09, 0x69, 0x88, 0xe9, 0x0d, 0xfa, 0x4d, + 0x66, 0xc5, 0xcd, 0xae, 0xb2, 0xda, 0x7a, 0xcc, 0x8a, 0xc7, 0x11, 0xe3, 0x34, 0x37, 0xe3, 0xe8, + 0x2b, 0xe8, 0xb9, 0x44, 0x10, 0x75, 0xc0, 0x9e, 0xb2, 0xdb, 0xc8, 0xec, 0x26, 0x44, 0x90, 0xe2, + 0x7c, 0x5d, 0xa9, 0x26, 0x8f, 0xb7, 0x03, 0xed, 0x25, 0x0d, 0x82, 0xc8, 0x34, 0xaa, 0xea, 0x1a, + 0x82, 0x99, 0x14, 0xcd, 0x1a, 0x58, 0xeb, 0xa0, 0xbd, 0xd4, 0xbd, 0xeb, 0x7b, 0x26, 0x28, 0x7d, + 0x54, 0x76, 0x3f, 0xf1, 0x3d, 0x7d, 0x0b, 0xe5, 0x7d, 0xe2, 0x7b, 0xf9, 0x79, 0xe4, 0xed, 0xfb, + 0xf5, 0xf3, 0x14, 0xf7, 0x56, 0x16, 0xfa, 0xe2, 0x7d, 0x65, 0x71, 0x1b, 0xbb, 0x44, 0x50, 0x73, + 0x50, 0x8f, 0xf2, 0x56, 0x49, 0x66, 0x0d, 0x0c, 0x6e, 0x4e, 0xa1, 0x97, 0xd0, 0xa6, 0x61, 0x2c, + 0xee, 0xcd, 0xa1, 0x32, 0x18, 0x66, 0x06, 0x53, 0xc9, 0x94, 0x17, 0x50, 0x52, 0xb4, 0x03, 0x2d, + 0x27, 0x62, 0xcc, 0x1c, 0x29, 0xad, 0x67, 0x99, 0xd6, 0x51, 0xc4, 0xd8, 0x94, 0x0b, 0x72, 0x19, + 0xf8, 0x7c, 0x39, 0x6b, 0x60, 0xa5, 0x84, 0xf6, 0x01, 0xb8, 0x20, 0x82, 0xda, 0x3e, 0xbb, 0x8a, + 0xcc, 0x35, 0x65, 0xb2, 0x9e, 0x97, 0x89, 0x94, 0xcc, 0xd9, 0x95, 0x44, 0xc7, 0xe0, 0x19, 0x81, + 0x0e, 0x61, 0xa4, 0x6d, 0x38, 0x23, 0x31, 0x5f, 0x46, 0xc2, 0x1c, 0x57, 0x1f, 0x3d, 0xb7, 0x3b, + 0x4b, 0x15, 0x66, 0x0d, 0x3c, 0x54, 0x26, 0x19, 0x03, 0x2d, 0x60, 0xa3, 0x88, 0x6b, 0xc7, 0xb7, + 0x41, 0xa0, 0xf0, 0x5b, 0x57, 0x8e, 0x3e, 0xae, 0x39, 0x3a, 0xbd, 0x0d, 0x82, 0x02, 0xc8, 0x31, + 0x7f, 0xc0, 0x47, 0x07, 0xa0, 0xfd, 0x4b, 0x27, 0x52, 0xc9, 0x44, 0xd5, 0x84, 0xc2, 0x34, 0x8c, + 0x04, 0x55, 0xee, 0x0a, 0x37, 0x03, 0x5e, 0xa2, 0xd1, 0x24, 0xbb, 0x55, 0x92, 0xa6, 0x9c, 0xb9, + 0xa1, 0x7c, 0x7c, 0xf4, 0xa8, 0x8f, 0x3c, 0x2b, 0x87, 0xbc, 0xcc, 0x90, 0xd8, 0x04, 0x94, 0xb8, + 0x3a, 0x79, 0x55, 0x8a, 0x6e, 0x56, 0xb1, 0x79, 0x9d, 0x4b, 0x8b, 0x44, 0x1d, 0x16, 0x26, 0x32, + 0x5d, 0xbf, 0x85, 0x61, 0x4c, 0x69, 0x62, 0xfb, 0x2e, 0x65, 0xc2, 0x17, 0xf7, 0xe6, 0xb3, 0x6a, + 0x19, 0x9e, 0x52, 0x9a, 0xcc, 0x53, 0x99, 0xbc, 0x46, 0x5c, 0xa2, 0x65, 0xb1, 0x13, 0xe7, 0xda, + 0x7c, 0xae, 0x4c, 0x5e, 0xe4, 0x95, 0xeb, 0x5c, 0xb3, 0xe8, 0x1f, 0x01, 0x75, 0x3d, 0x1a, 0x52, + 0x26, 0x2f, 0x2f, 0xb5, 0xd0, 0x1f, 0x00, 0xe2, 0xc4, 0x7f, 0xa7, 0x51, 0x30, 0x5f, 0x54, 0xc1, + 0xd7, 0xf7, 0x3d, 0x7d, 0x27, 0xaa, 0x59, 0x5c, 0xb2, 0x40, 0xdf, 0x95, 0xec, 0xb9, 0x69, 0x2a, + 0xfb, 0x9f, 0x3e, 0x61, 0x9f, 0x23, 0x56, 0x32, 0xb1, 0x6c, 0x58, 0x3d, 0x27, 0x1e, 0x1a, 0x82, + 0xf1, 0xf6, 0x64, 0x32, 0xfd, 0xe3, 0xfc, 0x64, 0x3a, 0x19, 0x37, 0x90, 0x01, 0xed, 0xe9, 0xe2, + 0xf4, 0xfc, 0x62, 0xdc, 0x44, 0x03, 0xe8, 0xbd, 0xc1, 0xc7, 0xf6, 0x9b, 0x93, 0xd7, 0x17, 0xe3, + 0x15, 0xa9, 0x77, 0x34, 0x3b, 0x38, 0xd1, 0xe4, 0x2a, 0x1a, 0xc3, 0x40, 0x91, 0x07, 0x27, 0x13, + 0xfb, 0x0d, 0x3e, 0x1e, 0xb7, 0xd0, 0x1a, 0xf4, 0xb5, 0x02, 0x56, 0x8c, 0x76, 0xb9, 0x91, 0xfe, + 0xb7, 0x09, 0x46, 0x9e, 0x50, 0x68, 0x0b, 0x7a, 0x21, 0x15, 0x44, 0x96, 0x57, 0xda, 0xd2, 0x73, + 0x1a, 0xed, 0x82, 0x21, 0xfc, 0x90, 0x72, 0x41, 0xc2, 0x58, 0x35, 0xd3, 0xfe, 0xfe, 0xb8, 0x0c, + 0xfe, 0xb9, 0x1f, 0x52, 0x5c, 0xa8, 0xa0, 0x67, 0xd0, 0x89, 0xaf, 0x7d, 0xdb, 0x77, 0x55, 0x8f, + 0x1d, 0xe0, 0x76, 0x7c, 0xed, 0xcf, 0x5d, 0xf4, 0x33, 0xe8, 0xa7, 0x2d, 0xd8, 0x5e, 0x1c, 0x1c, + 0x99, 0x2d, 0x25, 0x83, 0x94, 0xb5, 0x38, 0x38, 0x92, 0xc5, 0x17, 0x27, 0x51, 0x4c, 0x13, 0xe1, + 0x53, 0x9e, 0x36, 0xdb, 0xbc, 0x0d, 0x9c, 0xe6, 0x12, 0x5c, 0xd2, 0xb2, 0xce, 0x01, 0x0a, 0x09, + 0xfa, 0x39, 0x0c, 0xd5, 0xa3, 0x26, 0xf6, 0x92, 0xfa, 0xde, 0x52, 0xa4, 0x23, 0x61, 0xa0, 0x99, + 0x33, 0xc5, 0x43, 0x9f, 0xc2, 0x20, 0xa0, 0x57, 0xc2, 0x2e, 0x8f, 0x87, 0x1e, 0xee, 0x4b, 0xde, + 0x91, 0x66, 0x59, 0x07, 0xb0, 0x5e, 0x2b, 0x5a, 0xf4, 0x05, 0xf4, 0x68, 0xa0, 0xf2, 0x85, 0x9b, + 0xcd, 0xed, 0xd5, 0x32, 0x0a, 0xf9, 0xe8, 0xcc, 0x35, 0xac, 0xdf, 0xc2, 0xe6, 0x63, 0xe5, 0xfa, + 0x10, 0x85, 0xe6, 0x43, 0x14, 0xac, 0x2b, 0x18, 0x56, 0x7a, 0x53, 0x09, 0xce, 0x66, 0x19, 0xce, + 0x2d, 0xe8, 0xe5, 0x15, 0xa1, 0x27, 0x5c, 0x4e, 0x23, 0x0b, 0x86, 0x22, 0xe0, 0xb6, 0x43, 0x13, + 0x61, 0x2f, 0x09, 0x5f, 0xa6, 0x0f, 0xd1, 0x17, 0x01, 0x3f, 0xa2, 0x89, 0x98, 0x11, 0xbe, 0xb4, + 0xde, 0xc2, 0xa0, 0x5c, 0x39, 0x4f, 0x85, 0x41, 0xd0, 0x92, 0x6e, 0xd2, 0x10, 0xea, 0x77, 0x25, + 0x59, 0x56, 0xab, 0xc9, 0x62, 0x85, 0xd0, 0x2f, 0x15, 0xc8, 0xd3, 0xc3, 0xd9, 0x55, 0x83, 0x83, + 0x9b, 0x2b, 0xdb, 0xab, 0xaf, 0x0c, 0x9c, 0x91, 0x68, 0x17, 0x7a, 0x21, 0xf7, 0x6c, 0x71, 0x9f, + 0x6e, 0x29, 0xa3, 0x62, 0x7a, 0x48, 0x14, 0x17, 0xdc, 0x3b, 0xbf, 0x8f, 0x29, 0xee, 0x86, 0xfa, + 0x87, 0x15, 0x41, 0xbf, 0x34, 0xb6, 0x9e, 0x08, 0x57, 0x3e, 0xef, 0x4a, 0x2d, 0xb9, 0xdf, 0x2f, + 0xe0, 0x1d, 0x40, 0x31, 0x91, 0x9e, 0x88, 0xf7, 0x0b, 0x68, 0xa5, 0xb1, 0x1e, 0xcf, 0x92, 0xd6, + 0x07, 0x45, 0x0e, 0x74, 0x64, 0x3d, 0x71, 0x7f, 0x74, 0x60, 0xbf, 0xd1, 0xef, 0x98, 0x2d, 0x59, + 0xbf, 0xac, 0x6e, 0x7c, 0xfd, 0xfd, 0xb5, 0xdc, 0x5a, 0xb3, 0xf3, 0x15, 0xd0, 0xba, 0x80, 0x6e, + 0xca, 0x43, 0x2f, 0xa0, 0xcb, 0xe9, 0x8d, 0xcd, 0x6e, 0xc3, 0xf4, 0x98, 0x1d, 0x4e, 0x6f, 0x4e, + 0x6e, 0x43, 0x99, 0x55, 0xa5, 0xd7, 0xd0, 0x78, 0x7c, 0x0a, 0x83, 0xb4, 0x15, 0xda, 0x69, 0x66, + 0xad, 0xca, 0x9c, 0x4d, 0x79, 0xf2, 0x30, 0xd6, 0xdf, 0x60, 0x74, 0xaa, 0xc9, 0x2c, 0xc2, 0xe7, + 0xb0, 0xe6, 0x44, 0x41, 0x40, 0x1d, 0xe1, 0x47, 0xcc, 0x66, 0x24, 0xd4, 0x80, 0x18, 0x78, 0x54, + 0xb0, 0x4f, 0x48, 0x48, 0x6b, 0xde, 0x57, 0xea, 0xde, 0xff, 0xdd, 0x84, 0x41, 0x79, 0xa7, 0x43, + 0xbb, 0x00, 0x61, 0xbe, 0x7a, 0xa5, 0xf7, 0x1e, 0x55, 0x97, 0x32, 0x5c, 0xd2, 0x78, 0xef, 0x46, + 0x59, 0x2e, 0xe1, 0x56, 0xb5, 0x84, 0xad, 0x7f, 0x36, 0x61, 0xbd, 0x36, 0x1c, 0x9f, 0x2a, 0xd2, + 0xf7, 0x0d, 0xfc, 0x12, 0x46, 0x3e, 0xb7, 0x5d, 0xea, 0x04, 0x24, 0x21, 0x12, 0x22, 0x95, 0x12, + 0x3d, 0x3c, 0xf4, 0xf9, 0xa4, 0x60, 0x5a, 0xbf, 0x83, 0x5e, 0x66, 0x2d, 0x9f, 0xd2, 0x67, 0x4e, + 0xf9, 0x29, 0x7d, 0xe6, 0xc8, 0xa7, 0x2c, 0xbd, 0xf1, 0x4a, 0xf9, 0x8d, 0xad, 0x2b, 0x58, 0xaf, + 0xad, 0xbb, 0xe8, 0x5b, 0x18, 0x73, 0x1a, 0x5c, 0xa9, 0x3d, 0x27, 0x09, 0x75, 0xec, 0x66, 0xf5, + 0xc0, 0x79, 0x99, 0xac, 0x49, 0xcd, 0x79, 0xa1, 0x28, 0x73, 0x5e, 0xce, 0x6d, 0x96, 0x3e, 0x9e, + 0x26, 0xac, 0x4b, 0x40, 0xf5, 0x05, 0x19, 0x7d, 0x06, 0x6d, 0xb5, 0x8f, 0x3f, 0xd9, 0xaa, 0xb5, + 0x58, 0xd5, 0x2a, 0x25, 0xee, 0x0f, 0xd4, 0x2a, 0x25, 0xae, 0xf5, 0x67, 0xe8, 0xe8, 0x18, 0xf2, + 0xcd, 0x68, 0xe5, 0x83, 0x05, 0xe7, 0xf4, 0x0f, 0xf6, 0x99, 0xc7, 0x87, 0xa2, 0xd5, 0x85, 0xb6, + 0xda, 0x57, 0xad, 0xbf, 0x00, 0xaa, 0x6f, 0x65, 0xb2, 0x91, 0x73, 0x41, 0x12, 0x61, 0x57, 0xcb, + 0xa8, 0xaf, 0x98, 0x67, 0xba, 0x96, 0x3e, 0x81, 0x3e, 0x65, 0xae, 0x5d, 0x7d, 0x04, 0x83, 0x32, + 0x57, 0xcb, 0xad, 0x43, 0xd8, 0x78, 0x64, 0x57, 0x43, 0x3b, 0xd0, 0x4b, 0x2b, 0x36, 0x1b, 0x67, + 0xb5, 0x92, 0xce, 0x15, 0xac, 0x63, 0xd8, 0x7c, 0x6c, 0xff, 0x41, 0x7b, 0x45, 0xbf, 0xd1, 0x3e, + 0xf2, 0xfd, 0x3a, 0x55, 0xd4, 0xdd, 0x2a, 0x6f, 0x43, 0xd6, 0x7f, 0x9a, 0x30, 0xac, 0x88, 0xd0, + 0x06, 0xb4, 0xc5, 0x5d, 0x96, 0xd1, 0x06, 0x6e, 0x89, 0xbb, 0xb9, 0xfa, 0x8c, 0x94, 0xb5, 0xcc, + 0x63, 0xe2, 0xe8, 0xcf, 0x48, 0x03, 0x17, 0x0c, 0xf4, 0x09, 0x40, 0x51, 0xdd, 0x0a, 0x4f, 0x03, + 0x97, 0x38, 0xe8, 0x23, 0x30, 0x2e, 0x83, 0xc8, 0xb9, 0x96, 0x98, 0xa8, 0xc2, 0x6a, 0xe1, 0x9e, + 0x62, 0x9c, 0xd1, 0x1b, 0xb4, 0x0d, 0x03, 0x09, 0x95, 0xcf, 0x6c, 0xc5, 0x52, 0x7b, 0x46, 0x0b, + 0x03, 0xa7, 0x37, 0x73, 0x76, 0x28, 0x39, 0xd6, 0xf7, 0xf0, 0xec, 0xd1, 0x65, 0x0d, 0xed, 0xd7, + 0x36, 0x80, 0xe7, 0x0f, 0xae, 0x3b, 0xd5, 0xe2, 0xd2, 0x1e, 0x70, 0x01, 0xa3, 0xaa, 0x0c, 0x7d, + 0x09, 0x1d, 0x8d, 0x46, 0x9a, 0xf8, 0x4f, 0x40, 0x96, 0x2a, 0x95, 0xbf, 0xb5, 0x75, 0xda, 0xe7, + 0x8d, 0xf6, 0x4f, 0xb9, 0xeb, 0xac, 0x1b, 0xbe, 0x84, 0x35, 0x71, 0x67, 0x57, 0xae, 0x97, 0x6e, + 0x40, 0xe2, 0xee, 0x2c, 0xbf, 0x60, 0xd5, 0x65, 0xf9, 0xf3, 0xdd, 0xfa, 0x1c, 0xd6, 0x1e, 0xec, + 0xc6, 0xb2, 0xe8, 0x68, 0x92, 0x44, 0x49, 0xfa, 0x3e, 0x9a, 0xf8, 0xd5, 0xef, 0xa1, 0x5f, 0x1a, + 0x1b, 0x0f, 0x37, 0xd6, 0x21, 0x18, 0x87, 0xaf, 0xdf, 0x1c, 0x7d, 0x6f, 0x2f, 0xce, 0x8e, 0xc7, + 0x4d, 0xb9, 0x98, 0xce, 0x27, 0xd3, 0x93, 0xf3, 0xf9, 0xf9, 0x85, 0xe2, 0xac, 0xec, 0xff, 0x1d, + 0x3a, 0x7a, 0x6c, 0xa3, 0x6f, 0x60, 0xa0, 0x7f, 0x9d, 0x89, 0x84, 0x92, 0x10, 0xd5, 0x2a, 0x70, + 0xab, 0xc6, 0xb1, 0x1a, 0xaf, 0x9a, 0x5f, 0x35, 0xd1, 0x67, 0xd0, 0x3a, 0xf5, 0x99, 0x87, 0xaa, + 0x1f, 0x7e, 0x5b, 0x55, 0xd2, 0x6a, 0x1c, 0x7e, 0xf9, 0xd7, 0x1d, 0xcf, 0x17, 0xcb, 0xdb, 0xcb, + 0x5d, 0x27, 0x0a, 0xf7, 0x96, 0xf7, 0x31, 0x4d, 0xf4, 0x3e, 0xb8, 0x77, 0x45, 0x2e, 0x13, 0xdf, + 0xd9, 0x53, 0xff, 0xb9, 0xf0, 0x3d, 0x6d, 0x76, 0xd9, 0x51, 0xe4, 0xd7, 0xff, 0x0f, 0x00, 0x00, + 0xff, 0xff, 0x2b, 0x21, 0x65, 0x1c, 0x9a, 0x11, 0x00, 0x00, } diff --git a/protos/gossip/message.proto b/protos/gossip/message.proto index 1721566cfe2..74ded3f8324 100644 --- a/protos/gossip/message.proto +++ b/protos/gossip/message.proto @@ -145,6 +145,7 @@ message StateInfo { message Properties { uint64 ledger_height = 1; + bool left_channel = 2; } // StateInfoSnapshot is an aggregation of StateInfo messages