diff --git a/chains/linearizable_vm.go b/chains/linearizable_vm.go index e7e99b77cb93..06e5115ac490 100644 --- a/chains/linearizable_vm.go +++ b/chains/linearizable_vm.go @@ -33,7 +33,6 @@ type initializeOnLinearizeVM struct { genesisBytes []byte upgradeBytes []byte configBytes []byte - toEngine chan<- common.Message fxs []*common.Fx appSender common.AppSender } @@ -47,7 +46,6 @@ func (vm *initializeOnLinearizeVM) Linearize(ctx context.Context, stopVertexID i vm.genesisBytes, vm.upgradeBytes, vm.configBytes, - vm.toEngine, vm.fxs, vm.appSender, ) @@ -74,9 +72,8 @@ func (vm *linearizeOnInitializeVM) Initialize( _ []byte, _ []byte, _ []byte, - toEngine chan<- common.Message, _ []*common.Fx, _ common.AppSender, ) error { - return vm.Linearize(ctx, vm.stopVertexID, toEngine) + return vm.Linearize(ctx, vm.stopVertexID) } diff --git a/chains/manager.go b/chains/manager.go index f772dfe73996..fe38875942f8 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -13,6 +13,8 @@ import ( "sync" "time" + "github.com/ava-labs/avalanchego/simplex" + "github.com/prometheus/client_golang/prometheus" "go.uber.org/zap" @@ -324,6 +326,9 @@ func New(config *ManagerConfig) (Manager, error) { return nil, err } + config.Log.Info("C-chain ID is:", zap.String("C-chain ID", config.CChainID.String())) + config.Log.Info("X-chain ID is:", zap.String("C-chain ID", config.XChainID.String())) + return &manager{ Aliaser: ids.NewAliaser(), ManagerConfig: *config, @@ -519,7 +524,6 @@ func (m *manager) buildChain(chainParams ChainParameters, sb subnets.Subnet) (*c TxAcceptor: m.TxAcceptorGroup, VertexAcceptor: m.VertexAcceptorGroup, } - // Get a factory for the vm we want to use on our chain vmFactory, err := m.VMManager.GetFactory(chainParams.VMID) if err != nil { @@ -566,15 +570,32 @@ func (m *manager) buildChain(chainParams ChainParameters, sb subnets.Subnet) (*c beacons = chainParams.CustomBeacons } - chain, err = m.createSnowmanChain( - ctx, - chainParams.GenesisData, - m.Validators, - beacons, - vm, - chainFxs, - sb, - ) + var err error + + isPrimaryNetwork := chainParams.SubnetID == constants.PrimaryNetworkID + isPlugin := chainParams.VMID == constants.SubnetEVMID || chainParams.VMID == constants.XSVMID + + if isPlugin && !isPrimaryNetwork { + chain, err = m.createSimplexChain( + ctx, + chainParams.GenesisData, + m.Validators, + beacons, + vm, + chainFxs, + sb) + } else { + chain, err = m.createSnowmanChain( + ctx, + chainParams.GenesisData, + m.Validators, + beacons, + vm, + chainFxs, + sb, + ) + } + if err != nil { return nil, fmt.Errorf("error while creating new snowman vm %w", err) } @@ -598,6 +619,22 @@ func (m *manager) buildChain(chainParams ChainParameters, sb subnets.Subnet) (*c ) } +func (m *manager) createSimplexEngine(ctx *snow.ConsensusContext, vm block.ChainVM, vdrs validators.Manager, getServer common.AllGetsServer, genesisData []byte) (*simplex.Engine, error) { + conf := &simplex.Config{ + GenesisData: genesisData, + GetServer: getServer, + SignBLS: m.ManagerConfig.StakingBLSKey.Sign, + Sender: m.Net, + OutboundMsgBuilder: m.MsgCreator, + DB: m.DB, + Ctx: ctx, + VM: vm, + Validators: vdrs, + } + + return simplex.CreateEngine(conf) +} + func (m *manager) AddRegistrant(r Registrant) { m.registrants = append(m.registrants, r) } @@ -727,10 +764,6 @@ func (m *manager) createAvalancheChain( }, ) - // The channel through which a VM may send messages to the consensus engine - // VM uses this channel to notify engine that a block is ready to be made - msgChan := make(chan common.Message, defaultChannelSize) - // The only difference between using avalancheMessageSender and // snowmanMessageSender here is where the metrics will be placed. Because we // end up using this sender after the linearization, we pass in @@ -742,7 +775,6 @@ func (m *manager) createAvalancheChain( genesisData, chainConfig.Upgrade, chainConfig.Config, - msgChan, fxs, snowmanMessageSender, ) @@ -823,7 +855,6 @@ func (m *manager) createAvalancheChain( genesisBytes: genesisData, upgradeBytes: chainConfig.Upgrade, configBytes: chainConfig.Config, - toEngine: msgChan, fxs: fxs, appSender: snowmanMessageSender, } @@ -886,7 +917,6 @@ func (m *manager) createAvalancheChain( h, err := handler.New( ctx, vdrs, - msgChan, m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, @@ -1202,10 +1232,6 @@ func (m *manager) createSnowmanChain( vm = tracedvm.NewBlockVM(vm, "proposervm", m.Tracer) } - // The channel through which a VM may send messages to the consensus engine - // VM uses this channel to notify engine that a block is ready to be made - msgChan := make(chan common.Message, defaultChannelSize) - if err := vm.Initialize( context.TODO(), ctx.Context, @@ -1213,7 +1239,6 @@ func (m *manager) createSnowmanChain( genesisData, chainConfig.Upgrade, chainConfig.Config, - msgChan, fxs, messageSender, ); err != nil { @@ -1278,7 +1303,6 @@ func (m *manager) createSnowmanChain( h, err := handler.New( ctx, vdrs, - msgChan, m.FrontierPollFrequency, m.ConsensusAppConcurrency, m.ResourceTracker, @@ -1412,6 +1436,213 @@ func (m *manager) createSnowmanChain( }, nil } +// Create a linear chain using the Snowman consensus engine +func (m *manager) createSimplexChain( + ctx *snow.ConsensusContext, + genesisData []byte, + vdrs validators.Manager, + beacons validators.Manager, + vm block.ChainVM, + fxs []*common.Fx, + sb subnets.Subnet, +) (*chain, error) { + ctx.Lock.Lock() + defer ctx.Lock.Unlock() + + ctx.State.Set(snow.EngineState{ + Type: p2ppb.EngineType_ENGINE_TYPE_SNOWMAN, + State: snow.NormalOp, + }) + + primaryAlias := m.PrimaryAliasOrDefault(ctx.ChainID) + meterDBReg, err := metrics.MakeAndRegister( + m.MeterDBMetrics, + primaryAlias, + ) + if err != nil { + return nil, err + } + + meterDB, err := meterdb.New(meterDBReg, m.DB) + if err != nil { + return nil, err + } + + prefixDB := prefixdb.New(ctx.ChainID[:], meterDB) + vmDB := prefixdb.New(VMDBPrefix, prefixDB) + + // Passes messages from the consensus engine to the network + messageSender, err := sender.New( + ctx, + m.MsgCreator, + m.Net, + m.ManagerConfig.Router, + m.TimeoutManager, + p2ppb.EngineType_ENGINE_TYPE_SNOWMAN, + sb, + ctx.Registerer, + ) + if err != nil { + return nil, fmt.Errorf("couldn't initialize sender: %w", err) + } + + if m.TracingEnabled { + messageSender = sender.Trace(messageSender, m.Tracer) + } + + chainConfig, err := m.getChainConfig(ctx.ChainID) + if err != nil { + return nil, fmt.Errorf("error while fetching chain config: %w", err) + } + + if m.TracingEnabled { + vm = tracedvm.NewBlockVM(vm, primaryAlias, m.Tracer) + } + + if m.MeterVMEnabled { + meterchainvmReg, err := metrics.MakeAndRegister( + m.meterChainVMGatherer, + primaryAlias, + ) + if err != nil { + return nil, err + } + + vm = metervm.NewBlockVM(vm, meterchainvmReg) + } + if m.TracingEnabled { + vm = tracedvm.NewBlockVM(vm, "proposervm", m.Tracer) + } + + if err := vm.Initialize( + context.TODO(), + ctx.Context, + vmDB, + genesisData, + chainConfig.Upgrade, + chainConfig.Config, + fxs, + messageSender, + ); err != nil { + return nil, err + } + + sb.Bootstrapped(ctx.ChainID) + + if err := vm.SetState(context.Background(), snow.NormalOp); err != nil { + return nil, fmt.Errorf("couldn't set chain's state to NormalOp: %w", err) + } + + bootstrapWeight, err := beacons.TotalWeight(ctx.SubnetID) + if err != nil { + return nil, fmt.Errorf("error while fetching weight for subnet %s: %w", ctx.SubnetID, err) + } + + stakeReg, err := metrics.MakeAndRegister( + m.stakeGatherer, + primaryAlias, + ) + if err != nil { + return nil, err + } + + connectedValidators, err := tracker.NewMeteredPeers(stakeReg) + if err != nil { + return nil, fmt.Errorf("error creating peer tracker: %w", err) + } + vdrs.RegisterSetCallbackListener(ctx.SubnetID, connectedValidators) + + p2pReg, err := metrics.MakeAndRegister( + m.p2pGatherer, + primaryAlias, + ) + if err != nil { + return nil, err + } + + peerTracker, err := p2p.NewPeerTracker( + ctx.Log, + "peer_tracker", + p2pReg, + set.Of(ctx.NodeID), + nil, + ) + if err != nil { + return nil, fmt.Errorf("error creating peer tracker: %w", err) + } + + handlerReg, err := metrics.MakeAndRegister( + m.handlerGatherer, + primaryAlias, + ) + if err != nil { + return nil, err + } + + var halter common.Halter + + // Asynchronously passes messages from the network to the consensus engine + h, err := handler.New( + ctx, + vdrs, + m.FrontierPollFrequency, + m.ConsensusAppConcurrency, + m.ResourceTracker, + sb, + connectedValidators, + peerTracker, + handlerReg, + halter.Halt, + ) + if err != nil { + return nil, fmt.Errorf("couldn't initialize message handler: %w", err) + } + + connectedBeacons := tracker.NewPeers() + startupTracker := tracker.NewStartup(connectedBeacons, (3*bootstrapWeight+3)/4) + beacons.RegisterSetCallbackListener(ctx.SubnetID, startupTracker) + + snowGetHandler, err := snowgetter.New( + vm, + messageSender, + ctx.Log, + m.BootstrapMaxTimeGetAncestors, + m.BootstrapAncestorsMaxContainersSent, + ctx.Registerer, + ) + if err != nil { + return nil, fmt.Errorf("couldn't initialize snow base message handler: %w", err) + } + + // Create engine, bootstrapper and state-syncer in this order, + // to make sure start callbacks are duly initialized + simplex, err := m.createSimplexEngine(ctx, vm, vdrs, snowGetHandler, genesisData) + if err != nil { + return nil, fmt.Errorf("couldn't create simplex instance: %w", err) + } + + var engine common.Engine + engine = simplex + + if m.TracingEnabled { + engine = common.TraceEngine(engine, m.Tracer) + } + + h.SetEngineManager(&handler.EngineManager{ + Avalanche: nil, + Snowman: &handler.Engine{ + Consensus: engine, + }, + }) + + return &chain{ + Name: primaryAlias, + Context: ctx, + VM: vm, + Handler: h, + }, nil +} + func (m *manager) IsBootstrapped(id ids.ID) bool { m.chainsLock.Lock() chain, exists := m.chains[id] @@ -1426,6 +1657,7 @@ func (m *manager) IsBootstrapped(id ids.ID) bool { func (m *manager) registerBootstrappedHealthChecks() error { bootstrappedCheck := health.CheckerFunc(func(context.Context) (interface{}, error) { if subnetIDs := m.Subnets.Bootstrapping(); len(subnetIDs) != 0 { + m.Log.Info("node is currently bootstrapping chains", zap.String("subnets", fmt.Sprintf("%v", subnetIDs))) return subnetIDs, errNotBootstrapped } return []ids.ID{}, nil diff --git a/chains/subnets.go b/chains/subnets.go index fda66a7eded2..f769fce34e7c 100644 --- a/chains/subnets.go +++ b/chains/subnets.go @@ -56,6 +56,7 @@ func (s *Subnets) Bootstrapping() []ids.ID { for subnetID, subnet := range s.subnets { if !subnet.IsBootstrapped() { subnetsBootstrapping = append(subnetsBootstrapping, subnetID) + subnet.IsBootstrapped() } } diff --git a/go.mod b/go.mod index ec917fd7f3ec..8c987aeaf6ee 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,16 @@ module github.com/ava-labs/avalanchego // - Consider updating the version of golangci-lint (in scripts/lint.sh). go 1.23.6 +replace simplex => ../Simplex + +replace github.com/ava-labs/coreth => ../coreth + require ( github.com/DataDog/zstd v1.5.2 github.com/NYTimes/gziphandler v1.1.1 github.com/StephenButtolph/canoto v0.15.0 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/coreth v0.15.1-rc.0 + github.com/ava-labs/coreth v0.15.1-rc.0.0.20250422161611-7cc3557e9955 github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 github.com/ava-labs/libevm v1.13.14-0.2.0.release github.com/btcsuite/btcd/btcutil v1.1.3 @@ -77,6 +81,7 @@ require ( k8s.io/apimachinery v0.29.0 k8s.io/client-go v0.29.0 k8s.io/utils v0.0.0-20230726121419-3b25d923346b + simplex v0.0.0-00010101000000-000000000000 ) require ( diff --git a/go.sum b/go.sum index d26e29b8ea10..94df9f566fa7 100644 --- a/go.sum +++ b/go.sum @@ -68,8 +68,6 @@ github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/ava-labs/coreth v0.15.1-rc.0 h1:ahuIyp1hb4xiZ3DTA9uKIpVBMpMyXO3VHvwcxQUboSo= -github.com/ava-labs/coreth v0.15.1-rc.0/go.mod h1:BDKMO8sL2wuvWbtMRzJAsJrleQULHA+CHRbkh5hRG5o= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60 h1:EL66gtXOAwR/4KYBjOV03LTWgkEXvLePribLlJNu4g0= github.com/ava-labs/ledger-avalanche/go v0.0.0-20241009183145-e6f90a8a1a60/go.mod h1:/7qKobTfbzBu7eSTVaXMTr56yTYk4j2Px6/8G+idxHo= github.com/ava-labs/libevm v1.13.14-0.2.0.release h1:uKGCc5/ceeBbfAPRVtBUxbQt50WzB2pEDb8Uy93ePgQ= diff --git a/message/fields.go b/message/fields.go index 962532d06a2f..cf2356220301 100644 --- a/message/fields.go +++ b/message/fields.go @@ -32,6 +32,7 @@ var ( _ chainIDGetter = (*p2p.AppRequest)(nil) _ chainIDGetter = (*p2p.AppResponse)(nil) _ chainIDGetter = (*p2p.AppGossip)(nil) + _ chainIDGetter = (*p2p.SimplexMessage)(nil) _ requestIDGetter = (*p2p.GetStateSummaryFrontier)(nil) _ requestIDGetter = (*p2p.StateSummaryFrontier)(nil) diff --git a/message/messagemock/outbound_message_builder.go b/message/messagemock/outbound_message_builder.go index 89794619de73..623d874c2604 100644 --- a/message/messagemock/outbound_message_builder.go +++ b/message/messagemock/outbound_message_builder.go @@ -12,6 +12,7 @@ package messagemock import ( netip "net/netip" reflect "reflect" + simplex "simplex" time "time" ids "github.com/ava-labs/avalanchego/ids" @@ -25,7 +26,6 @@ import ( type OutboundMsgBuilder struct { ctrl *gomock.Controller recorder *OutboundMsgBuilderMockRecorder - isgomock struct{} } // OutboundMsgBuilderMockRecorder is the mock recorder for OutboundMsgBuilder. @@ -46,288 +46,378 @@ func (m *OutboundMsgBuilder) EXPECT() *OutboundMsgBuilderMockRecorder { } // Accepted mocks base method. -func (m *OutboundMsgBuilder) Accepted(chainID ids.ID, requestID uint32, containerIDs []ids.ID) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Accepted(arg0 ids.ID, arg1 uint32, arg2 []ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Accepted", chainID, requestID, containerIDs) + ret := m.ctrl.Call(m, "Accepted", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Accepted indicates an expected call of Accepted. -func (mr *OutboundMsgBuilderMockRecorder) Accepted(chainID, requestID, containerIDs any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Accepted(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).Accepted), chainID, requestID, containerIDs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).Accepted), arg0, arg1, arg2) } // AcceptedFrontier mocks base method. -func (m *OutboundMsgBuilder) AcceptedFrontier(chainID ids.ID, requestID uint32, containerID ids.ID) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AcceptedFrontier(arg0 ids.ID, arg1 uint32, arg2 ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AcceptedFrontier", chainID, requestID, containerID) + ret := m.ctrl.Call(m, "AcceptedFrontier", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AcceptedFrontier indicates an expected call of AcceptedFrontier. -func (mr *OutboundMsgBuilderMockRecorder) AcceptedFrontier(chainID, requestID, containerID any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AcceptedFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedFrontier), chainID, requestID, containerID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedFrontier), arg0, arg1, arg2) } // AcceptedStateSummary mocks base method. -func (m *OutboundMsgBuilder) AcceptedStateSummary(chainID ids.ID, requestID uint32, summaryIDs []ids.ID) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AcceptedStateSummary(arg0 ids.ID, arg1 uint32, arg2 []ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AcceptedStateSummary", chainID, requestID, summaryIDs) + ret := m.ctrl.Call(m, "AcceptedStateSummary", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AcceptedStateSummary indicates an expected call of AcceptedStateSummary. -func (mr *OutboundMsgBuilderMockRecorder) AcceptedStateSummary(chainID, requestID, summaryIDs any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AcceptedStateSummary(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedStateSummary), chainID, requestID, summaryIDs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).AcceptedStateSummary), arg0, arg1, arg2) } // Ancestors mocks base method. -func (m *OutboundMsgBuilder) Ancestors(chainID ids.ID, requestID uint32, containers [][]byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Ancestors(arg0 ids.ID, arg1 uint32, arg2 [][]byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Ancestors", chainID, requestID, containers) + ret := m.ctrl.Call(m, "Ancestors", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Ancestors indicates an expected call of Ancestors. -func (mr *OutboundMsgBuilderMockRecorder) Ancestors(chainID, requestID, containers any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Ancestors(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ancestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ancestors), chainID, requestID, containers) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ancestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ancestors), arg0, arg1, arg2) } // AppError mocks base method. -func (m *OutboundMsgBuilder) AppError(chainID ids.ID, requestID uint32, errorCode int32, errorMessage string) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AppError(arg0 ids.ID, arg1 uint32, arg2 int32, arg3 string) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppError", chainID, requestID, errorCode, errorMessage) + ret := m.ctrl.Call(m, "AppError", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AppError indicates an expected call of AppError. -func (mr *OutboundMsgBuilderMockRecorder) AppError(chainID, requestID, errorCode, errorMessage any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AppError(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppError", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppError), chainID, requestID, errorCode, errorMessage) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppError", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppError), arg0, arg1, arg2, arg3) } // AppGossip mocks base method. -func (m *OutboundMsgBuilder) AppGossip(chainID ids.ID, msg []byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AppGossip(arg0 ids.ID, arg1 []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppGossip", chainID, msg) + ret := m.ctrl.Call(m, "AppGossip", arg0, arg1) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AppGossip indicates an expected call of AppGossip. -func (mr *OutboundMsgBuilderMockRecorder) AppGossip(chainID, msg any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AppGossip(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppGossip), chainID, msg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppGossip), arg0, arg1) } // AppRequest mocks base method. -func (m *OutboundMsgBuilder) AppRequest(chainID ids.ID, requestID uint32, deadline time.Duration, msg []byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AppRequest(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequest", chainID, requestID, deadline, msg) + ret := m.ctrl.Call(m, "AppRequest", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AppRequest indicates an expected call of AppRequest. -func (mr *OutboundMsgBuilderMockRecorder) AppRequest(chainID, requestID, deadline, msg any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AppRequest(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppRequest), chainID, requestID, deadline, msg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppRequest), arg0, arg1, arg2, arg3) } // AppResponse mocks base method. -func (m *OutboundMsgBuilder) AppResponse(chainID ids.ID, requestID uint32, msg []byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) AppResponse(arg0 ids.ID, arg1 uint32, arg2 []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppResponse", chainID, requestID, msg) + ret := m.ctrl.Call(m, "AppResponse", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // AppResponse indicates an expected call of AppResponse. -func (mr *OutboundMsgBuilderMockRecorder) AppResponse(chainID, requestID, msg any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) AppResponse(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppResponse), chainID, requestID, msg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*OutboundMsgBuilder)(nil).AppResponse), arg0, arg1, arg2) +} + +// Block mocks base method. +func (m *OutboundMsgBuilder) Block(arg0 ids.ID, arg1 []byte, arg2 simplex.BlockHeader, arg3 simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Block", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Block indicates an expected call of Block. +func (mr *OutboundMsgBuilderMockRecorder) Block(arg0, arg1, arg2, arg3 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*OutboundMsgBuilder)(nil).Block), arg0, arg1, arg2, arg3) } // Chits mocks base method. -func (m *OutboundMsgBuilder) Chits(chainID ids.ID, requestID uint32, preferredID, preferredIDAtHeight, acceptedID ids.ID, acceptedHeight uint64) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Chits(arg0 ids.ID, arg1 uint32, arg2, arg3, arg4 ids.ID, arg5 uint64) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Chits", chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight) + ret := m.ctrl.Call(m, "Chits", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Chits indicates an expected call of Chits. -func (mr *OutboundMsgBuilderMockRecorder) Chits(chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Chits(arg0, arg1, arg2, arg3, arg4, arg5 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*OutboundMsgBuilder)(nil).Chits), arg0, arg1, arg2, arg3, arg4, arg5) +} + +// EmptyNotarization mocks base method. +func (m *OutboundMsgBuilder) EmptyNotarization(arg0 ids.ID, arg1 simplex.ProtocolMetadata, arg2 []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EmptyNotarization", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EmptyNotarization indicates an expected call of EmptyNotarization. +func (mr *OutboundMsgBuilderMockRecorder) EmptyNotarization(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmptyNotarization", reflect.TypeOf((*OutboundMsgBuilder)(nil).EmptyNotarization), arg0, arg1, arg2) +} + +// EmptyVote mocks base method. +func (m *OutboundMsgBuilder) EmptyVote(arg0 ids.ID, arg1 simplex.ProtocolMetadata, arg2 simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "EmptyVote", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// EmptyVote indicates an expected call of EmptyVote. +func (mr *OutboundMsgBuilderMockRecorder) EmptyVote(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Chits", reflect.TypeOf((*OutboundMsgBuilder)(nil).Chits), chainID, requestID, preferredID, preferredIDAtHeight, acceptedID, acceptedHeight) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EmptyVote", reflect.TypeOf((*OutboundMsgBuilder)(nil).EmptyVote), arg0, arg1, arg2) +} + +// Finalization mocks base method. +func (m *OutboundMsgBuilder) Finalization(arg0 ids.ID, arg1 simplex.BlockHeader, arg2 simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Finalization", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Finalization indicates an expected call of Finalization. +func (mr *OutboundMsgBuilderMockRecorder) Finalization(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Finalization", reflect.TypeOf((*OutboundMsgBuilder)(nil).Finalization), arg0, arg1, arg2) +} + +// FinalizationCertificate mocks base method. +func (m *OutboundMsgBuilder) FinalizationCertificate(arg0 ids.ID, arg1 simplex.BlockHeader, arg2 []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FinalizationCertificate", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FinalizationCertificate indicates an expected call of FinalizationCertificate. +func (mr *OutboundMsgBuilderMockRecorder) FinalizationCertificate(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FinalizationCertificate", reflect.TypeOf((*OutboundMsgBuilder)(nil).FinalizationCertificate), arg0, arg1, arg2) } // Get mocks base method. -func (m *OutboundMsgBuilder) Get(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Get(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", chainID, requestID, deadline, containerID) + ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *OutboundMsgBuilderMockRecorder) Get(chainID, requestID, deadline, containerID any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Get(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*OutboundMsgBuilder)(nil).Get), chainID, requestID, deadline, containerID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*OutboundMsgBuilder)(nil).Get), arg0, arg1, arg2, arg3) } // GetAccepted mocks base method. -func (m *OutboundMsgBuilder) GetAccepted(chainID ids.ID, requestID uint32, deadline time.Duration, containerIDs []ids.ID) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetAccepted(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []ids.ID) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAccepted", chainID, requestID, deadline, containerIDs) + ret := m.ctrl.Call(m, "GetAccepted", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAccepted indicates an expected call of GetAccepted. -func (mr *OutboundMsgBuilderMockRecorder) GetAccepted(chainID, requestID, deadline, containerIDs any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetAccepted(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAccepted), chainID, requestID, deadline, containerIDs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccepted", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAccepted), arg0, arg1, arg2, arg3) } // GetAcceptedFrontier mocks base method. -func (m *OutboundMsgBuilder) GetAcceptedFrontier(chainID ids.ID, requestID uint32, deadline time.Duration) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetAcceptedFrontier(arg0 ids.ID, arg1 uint32, arg2 time.Duration) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAcceptedFrontier", chainID, requestID, deadline) + ret := m.ctrl.Call(m, "GetAcceptedFrontier", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAcceptedFrontier indicates an expected call of GetAcceptedFrontier. -func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedFrontier(chainID, requestID, deadline any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedFrontier), chainID, requestID, deadline) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedFrontier), arg0, arg1, arg2) } // GetAcceptedStateSummary mocks base method. -func (m *OutboundMsgBuilder) GetAcceptedStateSummary(chainID ids.ID, requestID uint32, deadline time.Duration, heights []uint64) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetAcceptedStateSummary(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []uint64) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAcceptedStateSummary", chainID, requestID, deadline, heights) + ret := m.ctrl.Call(m, "GetAcceptedStateSummary", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAcceptedStateSummary indicates an expected call of GetAcceptedStateSummary. -func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(chainID, requestID, deadline, heights any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetAcceptedStateSummary(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedStateSummary), chainID, requestID, deadline, heights) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAcceptedStateSummary", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAcceptedStateSummary), arg0, arg1, arg2, arg3) } // GetAncestors mocks base method. -func (m *OutboundMsgBuilder) GetAncestors(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID, engineType p2p.EngineType) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetAncestors(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID, arg4 p2p.EngineType) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAncestors", chainID, requestID, deadline, containerID, engineType) + ret := m.ctrl.Call(m, "GetAncestors", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetAncestors indicates an expected call of GetAncestors. -func (mr *OutboundMsgBuilderMockRecorder) GetAncestors(chainID, requestID, deadline, containerID, engineType any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetAncestors(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAncestors), chainID, requestID, deadline, containerID, engineType) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAncestors", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetAncestors), arg0, arg1, arg2, arg3, arg4) } // GetPeerList mocks base method. -func (m *OutboundMsgBuilder) GetPeerList(knownPeersFilter, knownPeersSalt []byte, requestAllSubnetIPs bool) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetPeerList(arg0, arg1 []byte, arg2 bool) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPeerList", knownPeersFilter, knownPeersSalt, requestAllSubnetIPs) + ret := m.ctrl.Call(m, "GetPeerList", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetPeerList indicates an expected call of GetPeerList. -func (mr *OutboundMsgBuilderMockRecorder) GetPeerList(knownPeersFilter, knownPeersSalt, requestAllSubnetIPs any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetPeerList(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetPeerList), knownPeersFilter, knownPeersSalt, requestAllSubnetIPs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetPeerList), arg0, arg1, arg2) } // GetStateSummaryFrontier mocks base method. -func (m *OutboundMsgBuilder) GetStateSummaryFrontier(chainID ids.ID, requestID uint32, deadline time.Duration) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) GetStateSummaryFrontier(arg0 ids.ID, arg1 uint32, arg2 time.Duration) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateSummaryFrontier", chainID, requestID, deadline) + ret := m.ctrl.Call(m, "GetStateSummaryFrontier", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStateSummaryFrontier indicates an expected call of GetStateSummaryFrontier. -func (mr *OutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(chainID, requestID, deadline any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) GetStateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetStateSummaryFrontier), chainID, requestID, deadline) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).GetStateSummaryFrontier), arg0, arg1, arg2) } // Handshake mocks base method. -func (m *OutboundMsgBuilder) Handshake(networkID uint32, myTime uint64, ip netip.AddrPort, client string, major, minor, patch uint32, ipSigningTime uint64, ipNodeIDSig, ipBLSSig []byte, trackedSubnets []ids.ID, supportedACPs, objectedACPs []uint32, knownPeersFilter, knownPeersSalt []byte, requestAllSubnetIPs bool) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Handshake(arg0 uint32, arg1 uint64, arg2 netip.AddrPort, arg3 string, arg4, arg5, arg6 uint32, arg7 uint64, arg8, arg9 []byte, arg10 []ids.ID, arg11, arg12 []uint32, arg13, arg14 []byte, arg15 bool) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Handshake", networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedSubnets, supportedACPs, objectedACPs, knownPeersFilter, knownPeersSalt, requestAllSubnetIPs) + ret := m.ctrl.Call(m, "Handshake", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Handshake indicates an expected call of Handshake. -func (mr *OutboundMsgBuilderMockRecorder) Handshake(networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedSubnets, supportedACPs, objectedACPs, knownPeersFilter, knownPeersSalt, requestAllSubnetIPs any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Handshake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*OutboundMsgBuilder)(nil).Handshake), networkID, myTime, ip, client, major, minor, patch, ipSigningTime, ipNodeIDSig, ipBLSSig, trackedSubnets, supportedACPs, objectedACPs, knownPeersFilter, knownPeersSalt, requestAllSubnetIPs) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*OutboundMsgBuilder)(nil).Handshake), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15) +} + +// Notarization mocks base method. +func (m *OutboundMsgBuilder) Notarization(arg0 ids.ID, arg1 simplex.BlockHeader, arg2 []byte) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Notarization", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Notarization indicates an expected call of Notarization. +func (mr *OutboundMsgBuilderMockRecorder) Notarization(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notarization", reflect.TypeOf((*OutboundMsgBuilder)(nil).Notarization), arg0, arg1, arg2) } // PeerList mocks base method. -func (m *OutboundMsgBuilder) PeerList(peers []*ips.ClaimedIPPort, bypassThrottling bool) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) PeerList(arg0 []*ips.ClaimedIPPort, arg1 bool) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeerList", peers, bypassThrottling) + ret := m.ctrl.Call(m, "PeerList", arg0, arg1) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // PeerList indicates an expected call of PeerList. -func (mr *OutboundMsgBuilderMockRecorder) PeerList(peers, bypassThrottling any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) PeerList(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).PeerList), peers, bypassThrottling) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerList", reflect.TypeOf((*OutboundMsgBuilder)(nil).PeerList), arg0, arg1) } // Ping mocks base method. -func (m *OutboundMsgBuilder) Ping(primaryUptime uint32) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Ping(arg0 uint32) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Ping", primaryUptime) + ret := m.ctrl.Call(m, "Ping", arg0) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Ping indicates an expected call of Ping. -func (mr *OutboundMsgBuilderMockRecorder) Ping(primaryUptime any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Ping(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ping), primaryUptime) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*OutboundMsgBuilder)(nil).Ping), arg0) } // Pong mocks base method. @@ -346,61 +436,76 @@ func (mr *OutboundMsgBuilderMockRecorder) Pong() *gomock.Call { } // PullQuery mocks base method. -func (m *OutboundMsgBuilder) PullQuery(chainID ids.ID, requestID uint32, deadline time.Duration, containerID ids.ID, requestedHeight uint64) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) PullQuery(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 ids.ID, arg4 uint64) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PullQuery", chainID, requestID, deadline, containerID, requestedHeight) + ret := m.ctrl.Call(m, "PullQuery", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // PullQuery indicates an expected call of PullQuery. -func (mr *OutboundMsgBuilderMockRecorder) PullQuery(chainID, requestID, deadline, containerID, requestedHeight any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) PullQuery(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PullQuery), chainID, requestID, deadline, containerID, requestedHeight) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PullQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PullQuery), arg0, arg1, arg2, arg3, arg4) } // PushQuery mocks base method. -func (m *OutboundMsgBuilder) PushQuery(chainID ids.ID, requestID uint32, deadline time.Duration, container []byte, requestedHeight uint64) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) PushQuery(arg0 ids.ID, arg1 uint32, arg2 time.Duration, arg3 []byte, arg4 uint64) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PushQuery", chainID, requestID, deadline, container, requestedHeight) + ret := m.ctrl.Call(m, "PushQuery", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // PushQuery indicates an expected call of PushQuery. -func (mr *OutboundMsgBuilderMockRecorder) PushQuery(chainID, requestID, deadline, container, requestedHeight any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) PushQuery(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PushQuery), chainID, requestID, deadline, container, requestedHeight) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushQuery", reflect.TypeOf((*OutboundMsgBuilder)(nil).PushQuery), arg0, arg1, arg2, arg3, arg4) } // Put mocks base method. -func (m *OutboundMsgBuilder) Put(chainID ids.ID, requestID uint32, container []byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) Put(arg0 ids.ID, arg1 uint32, arg2 []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Put", chainID, requestID, container) + ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // Put indicates an expected call of Put. -func (mr *OutboundMsgBuilderMockRecorder) Put(chainID, requestID, container any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) Put(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*OutboundMsgBuilder)(nil).Put), chainID, requestID, container) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*OutboundMsgBuilder)(nil).Put), arg0, arg1, arg2) } // StateSummaryFrontier mocks base method. -func (m *OutboundMsgBuilder) StateSummaryFrontier(chainID ids.ID, requestID uint32, summary []byte) (message.OutboundMessage, error) { +func (m *OutboundMsgBuilder) StateSummaryFrontier(arg0 ids.ID, arg1 uint32, arg2 []byte) (message.OutboundMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateSummaryFrontier", chainID, requestID, summary) + ret := m.ctrl.Call(m, "StateSummaryFrontier", arg0, arg1, arg2) ret0, _ := ret[0].(message.OutboundMessage) ret1, _ := ret[1].(error) return ret0, ret1 } // StateSummaryFrontier indicates an expected call of StateSummaryFrontier. -func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(chainID, requestID, summary any) *gomock.Call { +func (mr *OutboundMsgBuilderMockRecorder) StateSummaryFrontier(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), arg0, arg1, arg2) +} + +// Vote mocks base method. +func (m *OutboundMsgBuilder) Vote(arg0 ids.ID, arg1 simplex.BlockHeader, arg2 simplex.Signature) (message.OutboundMessage, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Vote", arg0, arg1, arg2) + ret0, _ := ret[0].(message.OutboundMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Vote indicates an expected call of Vote. +func (mr *OutboundMsgBuilderMockRecorder) Vote(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateSummaryFrontier", reflect.TypeOf((*OutboundMsgBuilder)(nil).StateSummaryFrontier), chainID, requestID, summary) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Vote", reflect.TypeOf((*OutboundMsgBuilder)(nil).Vote), arg0, arg1, arg2) } diff --git a/message/ops.go b/message/ops.go index 21728ddad053..dbac13c792a9 100644 --- a/message/ops.go +++ b/message/ops.go @@ -49,6 +49,7 @@ const ( PullQueryOp QueryFailedOp ChitsOp + Simplex // Application: AppRequestOp AppErrorOp @@ -244,6 +245,8 @@ func (op Op) String() string { return "query_failed" case ChitsOp: return "chits" + case Simplex: + return "simplex" // Application case AppRequestOp: return "app_request" @@ -313,6 +316,8 @@ func Unwrap(m *p2p.Message) (fmt.Stringer, error) { return msg.PullQuery, nil case *p2p.Message_Chits: return msg.Chits, nil + case *p2p.Message_Simplex: + return msg.Simplex, nil // Application: case *p2p.Message_AppRequest: return msg.AppRequest, nil @@ -377,6 +382,8 @@ func ToOp(m *p2p.Message) (Op, error) { return AppErrorOp, nil case *p2p.Message_AppGossip: return AppGossipOp, nil + case *p2p.Message_Simplex: + return Simplex, nil default: return 0, fmt.Errorf("%w: %T", errUnknownMessageType, msg) } diff --git a/message/outbound_msg_builder.go b/message/outbound_msg_builder.go index 042236c81482..4558db1bba57 100644 --- a/message/outbound_msg_builder.go +++ b/message/outbound_msg_builder.go @@ -5,6 +5,7 @@ package message import ( "net/netip" + "simplex" "time" "github.com/ava-labs/avalanchego/ids" @@ -181,6 +182,20 @@ type OutboundMsgBuilder interface { chainID ids.ID, msg []byte, ) (OutboundMessage, error) + + Block(chainID ids.ID, block []byte, vote simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) + + Vote(chainID ids.ID, header simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) + + EmptyVote(chainID ids.ID, header simplex.ProtocolMetadata, signature simplex.Signature) (OutboundMessage, error) + + Finalization(chainID ids.ID, header simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) + + FinalizationCertificate(chainID ids.ID, header simplex.BlockHeader, qc []byte) (OutboundMessage, error) + + Notarization(chainID ids.ID, header simplex.BlockHeader, qc []byte) (OutboundMessage, error) + + EmptyNotarization(chainID ids.ID, header simplex.ProtocolMetadata, qc []byte) (OutboundMessage, error) } type outMsgBuilder struct { @@ -725,3 +740,223 @@ func (b *outMsgBuilder) AppGossip(chainID ids.ID, msg []byte) (OutboundMessage, false, ) } + +func (b *outMsgBuilder) Block(chainID ids.ID, block []byte, vote simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) { + msg, err := b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_Block{ + Block: &p2p.Block{ + Vote: &p2p.Vote{ + Signature: &p2p.Signature{ + Signer: signature.Signer, + Value: signature.Value, + }, + Vote: &p2p.BlockHeader{ + Digest: vote.Digest[:], + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(vote.Version), + Epoch: vote.Epoch, + Round: vote.Round, + Seq: vote.Seq, + Prev: vote.Prev[:], + }, + }, + }, + Block: block, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) + + return msg, err + +} + +func (b *outMsgBuilder) Vote(chainID ids.ID, header simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_Vote{ + Vote: &p2p.Vote{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Digest: header.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer, + Value: signature.Value, + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) EmptyVote(chainID ids.ID, header simplex.ProtocolMetadata, signature simplex.Signature) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_EmptyVote{ + EmptyVote: &p2p.EmptyVote{ + Vote: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer, + Value: signature.Value, + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) Finalization(chainID ids.ID, header simplex.BlockHeader, signature simplex.Signature) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_Finalization{ + Finalization: &p2p.Finalization{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Digest: header.Digest[:], + }, + Signature: &p2p.Signature{ + Signer: signature.Signer, + Value: signature.Value, + }, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) FinalizationCertificate(chainID ids.ID, header simplex.BlockHeader, qc []byte) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_FinalizationCertificate{ + FinalizationCertificate: &p2p.FinalizationCertificate{ + Finalization: &p2p.Finalization{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Digest: header.Digest[:], + }, + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) Notarization(chainID ids.ID, header simplex.BlockHeader, qc []byte) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_Notarization{ + Notarization: &p2p.Notarization{ + Vote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Digest: header.Digest[:], + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} + +func (b *outMsgBuilder) EmptyNotarization(chainID ids.ID, header simplex.ProtocolMetadata, qc []byte) (OutboundMessage, error) { + return b.builder.createOutbound( + &p2p.Message{ + Message: &p2p.Message_Simplex{ + Simplex: &p2p.SimplexMessage{ + ChainId: chainID[:], + Message: &p2p.SimplexMessage_EmptyNotarization{ + EmptyNotarization: &p2p.EmptyNotarization{ + EmptyVote: &p2p.BlockHeader{ + Metadata: &p2p.ProtocolMetadata{ + Version: uint32(header.Version), + Epoch: header.Epoch, + Round: header.Round, + Seq: header.Seq, + Prev: header.Prev[:], + }, + Digest: nil, + }, + QuorumCertificate: qc, + }, + }, + }, + }, + }, + b.compressionType, + false, + ) +} diff --git a/network/peer/peer.go b/network/peer/peer.go index d65a85171f90..5f6296457f88 100644 --- a/network/peer/peer.go +++ b/network/peer/peer.go @@ -475,7 +475,7 @@ func (p *peer) readMessages() { // Parse the message msg, err := p.MessageCreator.Parse(msgBytes, p.id, onFinishedHandling) if err != nil { - p.Log.Verbo("failed to parse message", + p.Log.Warn("failed to parse message", zap.Stringer("nodeID", p.id), zap.Binary("messageBytes", msgBytes), zap.Error(err), @@ -489,6 +489,14 @@ func (p *peer) readMessages() { continue } + if msg.Op() == message.Simplex { + p.Log.Info("received simplex message", + zap.Stringer("op", msg.Op()), + zap.Stringer("nodeID", p.id), + zap.Binary("messageBytes", msgBytes), + ) + } + now := p.Clock.Time() p.storeLastReceived(now) p.Metrics.Received(msg, msgLen) @@ -587,6 +595,13 @@ func (p *peer) writeMessages() { func (p *peer) writeMessage(writer io.Writer, msg message.OutboundMessage) { msgBytes := msg.Bytes() + if msg.Op() == message.Simplex { + p.Log.Info("sending message", + zap.Stringer("op", msg.Op()), + zap.Stringer("nodeID", p.id), + zap.Binary("messageBytes", msgBytes), + ) + } p.Log.Verbo("sending message", zap.Stringer("op", msg.Op()), zap.Stringer("nodeID", p.id), @@ -594,7 +609,7 @@ func (p *peer) writeMessage(writer io.Writer, msg message.OutboundMessage) { ) if err := p.conn.SetWriteDeadline(p.nextTimeout()); err != nil { - p.Log.Verbo(failedToSetDeadlineLog, + p.Log.Warn(failedToSetDeadlineLog, zap.Stringer("nodeID", p.id), zap.String("direction", "write"), zap.Error(err), @@ -760,7 +775,7 @@ func (p *peer) handle(msg message.InboundMessage) { return } if !p.finishedHandshake.Get() { - p.Log.Debug("dropping message", + p.Log.Warn("dropping message", zap.Stringer("nodeID", p.id), zap.Stringer("messageOp", msg.Op()), zap.String("reason", "handshake isn't finished"), diff --git a/proto/messenger/messenger.proto b/proto/messenger/messenger.proto index 36c3f52202f0..f23a3f369ad0 100644 --- a/proto/messenger/messenger.proto +++ b/proto/messenger/messenger.proto @@ -5,7 +5,7 @@ package messenger; option go_package = "github.com/ava-labs/avalanchego/proto/pb/messenger"; service Messenger { - rpc Notify(NotifyRequest) returns (NotifyResponse); + rpc Notify(stream Event) returns (stream EventRequest); } enum Message { @@ -14,8 +14,13 @@ enum Message { MESSAGE_STATE_SYNC_FINISHED = 2; } -message NotifyRequest { - Message message = 1; +message EventRequest { + oneof event { + bool start = 1; + bool stop = 2; + } } -message NotifyResponse {} +message Event { + Message message = 1; +} diff --git a/proto/p2p/p2p.proto b/proto/p2p/p2p.proto index b93047e295ef..947e03b6ce2b 100644 --- a/proto/p2p/p2p.proto +++ b/proto/p2p/p2p.proto @@ -55,9 +55,87 @@ message Message { AppResponse app_response = 31; AppGossip app_gossip = 32; AppError app_error = 34; + + // Simplex messages + SimplexMessage simplex = 33; + } +} + +message SimplexMessage { + // Chain being responded from + bytes chain_id = 1; + + oneof message { + Block block = 2; + Vote vote = 3; + EmptyVote empty_vote = 4; + Finalization finalization = 5; + Notarization notarization = 6; + EmptyNotarization empty_notarization = 7; + FinalizationCertificate finalization_certificate = 8; } } +message Block { + bytes block = 1; + Vote vote = 2; +} + +message ProtocolMetadata { + // Version defines the version of the protocol this block was created with. + uint32 version = 1; + // Epoch returns the epoch in which the block was proposed + uint64 epoch = 2; + // Round returns the round number in which the block was proposed. + // Can also be an empty block. + uint64 round = 3; + // Seq is the order of the block among all blocks in the blockchain. + // Cannot correspond to an empty block. + uint64 seq = 4; + // Prev returns the digest of the previous data block + bytes prev = 5; +} + +message BlockHeader { + ProtocolMetadata metadata = 1; + bytes digest = 2; +} + +message Signature { + bytes signer = 1; + bytes value = 2; +} + +message Vote { + BlockHeader vote = 1; + Signature signature = 2; +} + +message EmptyVote { + ProtocolMetadata vote = 1; + Signature signature = 2; +} + +message Finalization { + BlockHeader vote = 1; + Signature signature = 2; +} + +message FinalizationCertificate { + Finalization finalization = 1; + bytes quorum_certificate = 2; +} + +message Notarization { + BlockHeader vote = 1; + bytes quorum_certificate = 2; +} + +message EmptyNotarization { + BlockHeader empty_vote = 1; + bytes quorum_certificate = 2; +} + // Ping reports a peer's perceived uptime percentage. // // Peers should respond to Ping with a Pong. diff --git a/proto/pb/messenger/messenger.pb.go b/proto/pb/messenger/messenger.pb.go index 5d89e6232680..febf480abe85 100644 --- a/proto/pb/messenger/messenger.pb.go +++ b/proto/pb/messenger/messenger.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: messenger/messenger.proto @@ -69,30 +69,36 @@ func (Message) EnumDescriptor() ([]byte, []int) { return file_messenger_messenger_proto_rawDescGZIP(), []int{0} } -type NotifyRequest struct { +type EventRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Message Message `protobuf:"varint,1,opt,name=message,proto3,enum=messenger.Message" json:"message,omitempty"` + // Types that are assignable to Event: + // + // *EventRequest_Start + // *EventRequest_Stop + Event isEventRequest_Event `protobuf_oneof:"event"` } -func (x *NotifyRequest) Reset() { - *x = NotifyRequest{} - mi := &file_messenger_messenger_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *EventRequest) Reset() { + *x = EventRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_messenger_messenger_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *NotifyRequest) String() string { +func (x *EventRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NotifyRequest) ProtoMessage() {} +func (*EventRequest) ProtoMessage() {} -func (x *NotifyRequest) ProtoReflect() protoreflect.Message { +func (x *EventRequest) ProtoReflect() protoreflect.Message { mi := &file_messenger_messenger_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -102,40 +108,74 @@ func (x *NotifyRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NotifyRequest.ProtoReflect.Descriptor instead. -func (*NotifyRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use EventRequest.ProtoReflect.Descriptor instead. +func (*EventRequest) Descriptor() ([]byte, []int) { return file_messenger_messenger_proto_rawDescGZIP(), []int{0} } -func (x *NotifyRequest) GetMessage() Message { - if x != nil { - return x.Message +func (m *EventRequest) GetEvent() isEventRequest_Event { + if m != nil { + return m.Event } - return Message_MESSAGE_UNSPECIFIED + return nil +} + +func (x *EventRequest) GetStart() bool { + if x, ok := x.GetEvent().(*EventRequest_Start); ok { + return x.Start + } + return false +} + +func (x *EventRequest) GetStop() bool { + if x, ok := x.GetEvent().(*EventRequest_Stop); ok { + return x.Stop + } + return false +} + +type isEventRequest_Event interface { + isEventRequest_Event() +} + +type EventRequest_Start struct { + Start bool `protobuf:"varint,1,opt,name=start,proto3,oneof"` +} + +type EventRequest_Stop struct { + Stop bool `protobuf:"varint,2,opt,name=stop,proto3,oneof"` } -type NotifyResponse struct { +func (*EventRequest_Start) isEventRequest_Event() {} + +func (*EventRequest_Stop) isEventRequest_Event() {} + +type Event struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Message Message `protobuf:"varint,1,opt,name=message,proto3,enum=messenger.Message" json:"message,omitempty"` } -func (x *NotifyResponse) Reset() { - *x = NotifyResponse{} - mi := &file_messenger_messenger_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_messenger_messenger_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *NotifyResponse) String() string { +func (x *Event) String() string { return protoimpl.X.MessageStringOf(x) } -func (*NotifyResponse) ProtoMessage() {} +func (*Event) ProtoMessage() {} -func (x *NotifyResponse) ProtoReflect() protoreflect.Message { +func (x *Event) ProtoReflect() protoreflect.Message { mi := &file_messenger_messenger_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -145,36 +185,46 @@ func (x *NotifyResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use NotifyResponse.ProtoReflect.Descriptor instead. -func (*NotifyResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { return file_messenger_messenger_proto_rawDescGZIP(), []int{1} } +func (x *Event) GetMessage() Message { + if x != nil { + return x.Message + } + return Message_MESSAGE_UNSPECIFIED +} + var File_messenger_messenger_proto protoreflect.FileDescriptor var file_messenger_messenger_proto_rawDesc = []byte{ 0x0a, 0x19, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x6d, 0x65, 0x73, - 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x22, 0x3d, 0x0a, 0x0d, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x65, - 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x5c, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4d, - 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x5f, 0x42, 0x4c, 0x4f, - 0x43, 0x4b, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x46, 0x49, 0x4e, 0x49, 0x53, - 0x48, 0x45, 0x44, 0x10, 0x02, 0x32, 0x4a, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, - 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x18, 0x2e, 0x6d, - 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, - 0x65, 0x72, 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x65, - 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x22, 0x45, 0x0a, 0x0c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, + 0x0a, 0x04, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x04, + 0x73, 0x74, 0x6f, 0x70, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x35, 0x0a, + 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, + 0x67, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2a, 0x5c, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x45, 0x53, 0x53, + 0x41, 0x47, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, + 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x46, 0x49, 0x4e, 0x49, 0x53, 0x48, 0x45, 0x44, + 0x10, 0x02, 0x32, 0x44, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x12, + 0x37, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x10, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x65, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x28, 0x01, 0x30, 0x01, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, + 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -191,15 +241,15 @@ func file_messenger_messenger_proto_rawDescGZIP() []byte { var file_messenger_messenger_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_messenger_messenger_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_messenger_messenger_proto_goTypes = []any{ - (Message)(0), // 0: messenger.Message - (*NotifyRequest)(nil), // 1: messenger.NotifyRequest - (*NotifyResponse)(nil), // 2: messenger.NotifyResponse +var file_messenger_messenger_proto_goTypes = []interface{}{ + (Message)(0), // 0: messenger.Message + (*EventRequest)(nil), // 1: messenger.EventRequest + (*Event)(nil), // 2: messenger.Event } var file_messenger_messenger_proto_depIdxs = []int32{ - 0, // 0: messenger.NotifyRequest.message:type_name -> messenger.Message - 1, // 1: messenger.Messenger.Notify:input_type -> messenger.NotifyRequest - 2, // 2: messenger.Messenger.Notify:output_type -> messenger.NotifyResponse + 0, // 0: messenger.Event.message:type_name -> messenger.Message + 2, // 1: messenger.Messenger.Notify:input_type -> messenger.Event + 1, // 2: messenger.Messenger.Notify:output_type -> messenger.EventRequest 2, // [2:3] is the sub-list for method output_type 1, // [1:2] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name @@ -212,6 +262,36 @@ func file_messenger_messenger_proto_init() { if File_messenger_messenger_proto != nil { return } + if !protoimpl.UnsafeEnabled { + file_messenger_messenger_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EventRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_messenger_messenger_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_messenger_messenger_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*EventRequest_Start)(nil), + (*EventRequest_Stop)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/proto/pb/messenger/messenger_grpc.pb.go b/proto/pb/messenger/messenger_grpc.pb.go index d03d1819e43f..e16badddc3f0 100644 --- a/proto/pb/messenger/messenger_grpc.pb.go +++ b/proto/pb/messenger/messenger_grpc.pb.go @@ -26,7 +26,7 @@ const ( // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type MessengerClient interface { - Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) + Notify(ctx context.Context, opts ...grpc.CallOption) (Messenger_NotifyClient, error) } type messengerClient struct { @@ -37,20 +37,42 @@ func NewMessengerClient(cc grpc.ClientConnInterface) MessengerClient { return &messengerClient{cc} } -func (c *messengerClient) Notify(ctx context.Context, in *NotifyRequest, opts ...grpc.CallOption) (*NotifyResponse, error) { - out := new(NotifyResponse) - err := c.cc.Invoke(ctx, Messenger_Notify_FullMethodName, in, out, opts...) +func (c *messengerClient) Notify(ctx context.Context, opts ...grpc.CallOption) (Messenger_NotifyClient, error) { + stream, err := c.cc.NewStream(ctx, &Messenger_ServiceDesc.Streams[0], Messenger_Notify_FullMethodName, opts...) if err != nil { return nil, err } - return out, nil + x := &messengerNotifyClient{stream} + return x, nil +} + +type Messenger_NotifyClient interface { + Send(*Event) error + Recv() (*EventRequest, error) + grpc.ClientStream +} + +type messengerNotifyClient struct { + grpc.ClientStream +} + +func (x *messengerNotifyClient) Send(m *Event) error { + return x.ClientStream.SendMsg(m) +} + +func (x *messengerNotifyClient) Recv() (*EventRequest, error) { + m := new(EventRequest) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil } // MessengerServer is the server API for Messenger service. // All implementations must embed UnimplementedMessengerServer // for forward compatibility type MessengerServer interface { - Notify(context.Context, *NotifyRequest) (*NotifyResponse, error) + Notify(Messenger_NotifyServer) error mustEmbedUnimplementedMessengerServer() } @@ -58,8 +80,8 @@ type MessengerServer interface { type UnimplementedMessengerServer struct { } -func (UnimplementedMessengerServer) Notify(context.Context, *NotifyRequest) (*NotifyResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Notify not implemented") +func (UnimplementedMessengerServer) Notify(Messenger_NotifyServer) error { + return status.Errorf(codes.Unimplemented, "method Notify not implemented") } func (UnimplementedMessengerServer) mustEmbedUnimplementedMessengerServer() {} @@ -74,22 +96,30 @@ func RegisterMessengerServer(s grpc.ServiceRegistrar, srv MessengerServer) { s.RegisterService(&Messenger_ServiceDesc, srv) } -func _Messenger_Notify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(NotifyRequest) - if err := dec(in); err != nil { +func _Messenger_Notify_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(MessengerServer).Notify(&messengerNotifyServer{stream}) +} + +type Messenger_NotifyServer interface { + Send(*EventRequest) error + Recv() (*Event, error) + grpc.ServerStream +} + +type messengerNotifyServer struct { + grpc.ServerStream +} + +func (x *messengerNotifyServer) Send(m *EventRequest) error { + return x.ServerStream.SendMsg(m) +} + +func (x *messengerNotifyServer) Recv() (*Event, error) { + m := new(Event) + if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err } - if interceptor == nil { - return srv.(MessengerServer).Notify(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Messenger_Notify_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MessengerServer).Notify(ctx, req.(*NotifyRequest)) - } - return interceptor(ctx, in, info, handler) + return m, nil } // Messenger_ServiceDesc is the grpc.ServiceDesc for Messenger service. @@ -98,12 +128,14 @@ func _Messenger_Notify_Handler(srv interface{}, ctx context.Context, dec func(in var Messenger_ServiceDesc = grpc.ServiceDesc{ ServiceName: "messenger.Messenger", HandlerType: (*MessengerServer)(nil), - Methods: []grpc.MethodDesc{ + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ { - MethodName: "Notify", - Handler: _Messenger_Notify_Handler, + StreamName: "Notify", + Handler: _Messenger_Notify_Handler, + ServerStreams: true, + ClientStreams: true, }, }, - Streams: []grpc.StreamDesc{}, Metadata: "messenger/messenger.proto", } diff --git a/proto/pb/p2p/p2p.pb.go b/proto/pb/p2p/p2p.pb.go index b6cbb66354d1..825da96d0064 100644 --- a/proto/pb/p2p/p2p.pb.go +++ b/proto/pb/p2p/p2p.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.35.1 +// protoc-gen-go v1.33.0 // protoc (unknown) // source: p2p/p2p.proto @@ -109,14 +109,17 @@ type Message struct { // *Message_AppResponse // *Message_AppGossip // *Message_AppError + // *Message_Simplex Message isMessage_Message `protobuf_oneof:"message"` } func (x *Message) Reset() { *x = Message{} - mi := &file_p2p_p2p_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Message) String() string { @@ -127,7 +130,7 @@ func (*Message) ProtoMessage() {} func (x *Message) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[0] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -324,6 +327,13 @@ func (x *Message) GetAppError() *AppError { return nil } +func (x *Message) GetSimplex() *SimplexMessage { + if x, ok := x.GetMessage().(*Message_Simplex); ok { + return x.Simplex + } + return nil +} + type isMessage_Message interface { isMessage_Message() } @@ -436,6 +446,11 @@ type Message_AppError struct { AppError *AppError `protobuf:"bytes,34,opt,name=app_error,json=appError,proto3,oneof"` } +type Message_Simplex struct { + // Simplex messages + Simplex *SimplexMessage `protobuf:"bytes,33,opt,name=simplex,proto3,oneof"` +} + func (*Message_CompressedZstd) isMessage_Message() {} func (*Message_Ping) isMessage_Message() {} @@ -486,34 +501,45 @@ func (*Message_AppGossip) isMessage_Message() {} func (*Message_AppError) isMessage_Message() {} -// Ping reports a peer's perceived uptime percentage. -// -// Peers should respond to Ping with a Pong. -type Ping struct { +func (*Message_Simplex) isMessage_Message() {} + +type SimplexMessage struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Uptime percentage on the primary network [0, 100] - Uptime uint32 `protobuf:"varint,1,opt,name=uptime,proto3" json:"uptime,omitempty"` -} - -func (x *Ping) Reset() { - *x = Ping{} - mi := &file_p2p_p2p_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + // Chain being responded from + ChainId []byte `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + // Types that are assignable to Message: + // + // *SimplexMessage_Block + // *SimplexMessage_Vote + // *SimplexMessage_EmptyVote + // *SimplexMessage_Finalization + // *SimplexMessage_Notarization + // *SimplexMessage_EmptyNotarization + // *SimplexMessage_FinalizationCertificate + Message isSimplexMessage_Message `protobuf_oneof:"message"` +} + +func (x *SimplexMessage) Reset() { + *x = SimplexMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *Ping) String() string { +func (x *SimplexMessage) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Ping) ProtoMessage() {} +func (*SimplexMessage) ProtoMessage() {} -func (x *Ping) ProtoReflect() protoreflect.Message { +func (x *SimplexMessage) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[1] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -523,41 +549,147 @@ func (x *Ping) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Ping.ProtoReflect.Descriptor instead. -func (*Ping) Descriptor() ([]byte, []int) { +// Deprecated: Use SimplexMessage.ProtoReflect.Descriptor instead. +func (*SimplexMessage) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{1} } -func (x *Ping) GetUptime() uint32 { +func (x *SimplexMessage) GetChainId() []byte { if x != nil { - return x.Uptime + return x.ChainId } - return 0 + return nil } -// Pong is sent in response to a Ping. -type Pong struct { +func (m *SimplexMessage) GetMessage() isSimplexMessage_Message { + if m != nil { + return m.Message + } + return nil +} + +func (x *SimplexMessage) GetBlock() *Block { + if x, ok := x.GetMessage().(*SimplexMessage_Block); ok { + return x.Block + } + return nil +} + +func (x *SimplexMessage) GetVote() *Vote { + if x, ok := x.GetMessage().(*SimplexMessage_Vote); ok { + return x.Vote + } + return nil +} + +func (x *SimplexMessage) GetEmptyVote() *EmptyVote { + if x, ok := x.GetMessage().(*SimplexMessage_EmptyVote); ok { + return x.EmptyVote + } + return nil +} + +func (x *SimplexMessage) GetFinalization() *Finalization { + if x, ok := x.GetMessage().(*SimplexMessage_Finalization); ok { + return x.Finalization + } + return nil +} + +func (x *SimplexMessage) GetNotarization() *Notarization { + if x, ok := x.GetMessage().(*SimplexMessage_Notarization); ok { + return x.Notarization + } + return nil +} + +func (x *SimplexMessage) GetEmptyNotarization() *EmptyNotarization { + if x, ok := x.GetMessage().(*SimplexMessage_EmptyNotarization); ok { + return x.EmptyNotarization + } + return nil +} + +func (x *SimplexMessage) GetFinalizationCertificate() *FinalizationCertificate { + if x, ok := x.GetMessage().(*SimplexMessage_FinalizationCertificate); ok { + return x.FinalizationCertificate + } + return nil +} + +type isSimplexMessage_Message interface { + isSimplexMessage_Message() +} + +type SimplexMessage_Block struct { + Block *Block `protobuf:"bytes,2,opt,name=block,proto3,oneof"` +} + +type SimplexMessage_Vote struct { + Vote *Vote `protobuf:"bytes,3,opt,name=vote,proto3,oneof"` +} + +type SimplexMessage_EmptyVote struct { + EmptyVote *EmptyVote `protobuf:"bytes,4,opt,name=empty_vote,json=emptyVote,proto3,oneof"` +} + +type SimplexMessage_Finalization struct { + Finalization *Finalization `protobuf:"bytes,5,opt,name=finalization,proto3,oneof"` +} + +type SimplexMessage_Notarization struct { + Notarization *Notarization `protobuf:"bytes,6,opt,name=notarization,proto3,oneof"` +} + +type SimplexMessage_EmptyNotarization struct { + EmptyNotarization *EmptyNotarization `protobuf:"bytes,7,opt,name=empty_notarization,json=emptyNotarization,proto3,oneof"` +} + +type SimplexMessage_FinalizationCertificate struct { + FinalizationCertificate *FinalizationCertificate `protobuf:"bytes,8,opt,name=finalization_certificate,json=finalizationCertificate,proto3,oneof"` +} + +func (*SimplexMessage_Block) isSimplexMessage_Message() {} + +func (*SimplexMessage_Vote) isSimplexMessage_Message() {} + +func (*SimplexMessage_EmptyVote) isSimplexMessage_Message() {} + +func (*SimplexMessage_Finalization) isSimplexMessage_Message() {} + +func (*SimplexMessage_Notarization) isSimplexMessage_Message() {} + +func (*SimplexMessage_EmptyNotarization) isSimplexMessage_Message() {} + +func (*SimplexMessage_FinalizationCertificate) isSimplexMessage_Message() {} + +type Block struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + Block []byte `protobuf:"bytes,1,opt,name=block,proto3" json:"block,omitempty"` + Vote *Vote `protobuf:"bytes,2,opt,name=vote,proto3" json:"vote,omitempty"` } -func (x *Pong) Reset() { - *x = Pong{} - mi := &file_p2p_p2p_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Block) Reset() { + *x = Block{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *Pong) String() string { +func (x *Block) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Pong) ProtoMessage() {} +func (*Block) ProtoMessage() {} -func (x *Pong) ProtoReflect() protoreflect.Message { +func (x *Block) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[2] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -567,66 +699,62 @@ func (x *Pong) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Pong.ProtoReflect.Descriptor instead. -func (*Pong) Descriptor() ([]byte, []int) { +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{2} } -// Handshake is the first outbound message sent to a peer when a connection is -// established to start the p2p handshake. -// -// Peers must respond to a Handshake message with a PeerList message to allow the -// peer to connect to other peers in the network. -// -// Peers should drop connections to peers with incompatible versions. -type Handshake struct { +func (x *Block) GetBlock() []byte { + if x != nil { + return x.Block + } + return nil +} + +func (x *Block) GetVote() *Vote { + if x != nil { + return x.Vote + } + return nil +} + +type ProtocolMetadata struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Network the peer is running on (e.g local, testnet, mainnet) - NetworkId uint32 `protobuf:"varint,1,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"` - // Unix timestamp when this Handshake message was created - MyTime uint64 `protobuf:"varint,2,opt,name=my_time,json=myTime,proto3" json:"my_time,omitempty"` - // IP address of the peer - IpAddr []byte `protobuf:"bytes,3,opt,name=ip_addr,json=ipAddr,proto3" json:"ip_addr,omitempty"` - // IP port of the peer - IpPort uint32 `protobuf:"varint,4,opt,name=ip_port,json=ipPort,proto3" json:"ip_port,omitempty"` - // Timestamp of the IP - IpSigningTime uint64 `protobuf:"varint,6,opt,name=ip_signing_time,json=ipSigningTime,proto3" json:"ip_signing_time,omitempty"` - // Signature of the peer IP port pair at a provided timestamp with the TLS - // key. - IpNodeIdSig []byte `protobuf:"bytes,7,opt,name=ip_node_id_sig,json=ipNodeIdSig,proto3" json:"ip_node_id_sig,omitempty"` - // Subnets the peer is tracking - TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` - Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` - SupportedAcps []uint32 `protobuf:"varint,10,rep,packed,name=supported_acps,json=supportedAcps,proto3" json:"supported_acps,omitempty"` - ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` - KnownPeers *BloomFilter `protobuf:"bytes,12,opt,name=known_peers,json=knownPeers,proto3" json:"known_peers,omitempty"` - // Signature of the peer IP port pair at a provided timestamp with the BLS - // key. - IpBlsSig []byte `protobuf:"bytes,13,opt,name=ip_bls_sig,json=ipBlsSig,proto3" json:"ip_bls_sig,omitempty"` - // To avoid sending IPs that the client isn't interested in tracking, the - // server expects the client to confirm that it is tracking all subnets. - AllSubnets bool `protobuf:"varint,14,opt,name=all_subnets,json=allSubnets,proto3" json:"all_subnets,omitempty"` -} - -func (x *Handshake) Reset() { - *x = Handshake{} - mi := &file_p2p_p2p_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + // Version defines the version of the protocol this block was created with. + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // Epoch returns the epoch in which the block was proposed + Epoch uint64 `protobuf:"varint,2,opt,name=epoch,proto3" json:"epoch,omitempty"` + // Round returns the round number in which the block was proposed. + // Can also be an empty block. + Round uint64 `protobuf:"varint,3,opt,name=round,proto3" json:"round,omitempty"` + // Seq is the order of the block among all blocks in the blockchain. + // Cannot correspond to an empty block. + Seq uint64 `protobuf:"varint,4,opt,name=seq,proto3" json:"seq,omitempty"` + // Prev returns the digest of the previous data block + Prev []byte `protobuf:"bytes,5,opt,name=prev,proto3" json:"prev,omitempty"` +} + +func (x *ProtocolMetadata) Reset() { + *x = ProtocolMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *Handshake) String() string { +func (x *ProtocolMetadata) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Handshake) ProtoMessage() {} +func (*ProtocolMetadata) ProtoMessage() {} -func (x *Handshake) ProtoReflect() protoreflect.Message { +func (x *ProtocolMetadata) ProtoReflect() protoreflect.Message { mi := &file_p2p_p2p_proto_msgTypes[3] - if x != nil { + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -636,132 +764,128 @@ func (x *Handshake) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. -func (*Handshake) Descriptor() ([]byte, []int) { +// Deprecated: Use ProtocolMetadata.ProtoReflect.Descriptor instead. +func (*ProtocolMetadata) Descriptor() ([]byte, []int) { return file_p2p_p2p_proto_rawDescGZIP(), []int{3} } -func (x *Handshake) GetNetworkId() uint32 { +func (x *ProtocolMetadata) GetVersion() uint32 { if x != nil { - return x.NetworkId + return x.Version } return 0 } -func (x *Handshake) GetMyTime() uint64 { +func (x *ProtocolMetadata) GetEpoch() uint64 { if x != nil { - return x.MyTime + return x.Epoch } return 0 } -func (x *Handshake) GetIpAddr() []byte { - if x != nil { - return x.IpAddr - } - return nil -} - -func (x *Handshake) GetIpPort() uint32 { +func (x *ProtocolMetadata) GetRound() uint64 { if x != nil { - return x.IpPort + return x.Round } return 0 } -func (x *Handshake) GetIpSigningTime() uint64 { +func (x *ProtocolMetadata) GetSeq() uint64 { if x != nil { - return x.IpSigningTime + return x.Seq } return 0 } -func (x *Handshake) GetIpNodeIdSig() []byte { +func (x *ProtocolMetadata) GetPrev() []byte { if x != nil { - return x.IpNodeIdSig + return x.Prev } return nil } -func (x *Handshake) GetTrackedSubnets() [][]byte { - if x != nil { - return x.TrackedSubnets - } - return nil +type BlockHeader struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Metadata *ProtocolMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + Digest []byte `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` } -func (x *Handshake) GetClient() *Client { - if x != nil { - return x.Client +func (x *BlockHeader) Reset() { + *x = BlockHeader{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } - return nil } -func (x *Handshake) GetSupportedAcps() []uint32 { - if x != nil { - return x.SupportedAcps - } - return nil +func (x *BlockHeader) String() string { + return protoimpl.X.MessageStringOf(x) } -func (x *Handshake) GetObjectedAcps() []uint32 { - if x != nil { - return x.ObjectedAcps +func (*BlockHeader) ProtoMessage() {} + +func (x *BlockHeader) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms } - return nil + return mi.MessageOf(x) } -func (x *Handshake) GetKnownPeers() *BloomFilter { - if x != nil { - return x.KnownPeers - } - return nil +// Deprecated: Use BlockHeader.ProtoReflect.Descriptor instead. +func (*BlockHeader) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{4} } -func (x *Handshake) GetIpBlsSig() []byte { +func (x *BlockHeader) GetMetadata() *ProtocolMetadata { if x != nil { - return x.IpBlsSig + return x.Metadata } return nil } -func (x *Handshake) GetAllSubnets() bool { +func (x *BlockHeader) GetDigest() []byte { if x != nil { - return x.AllSubnets + return x.Digest } - return false + return nil } -// Metadata about a peer's P2P client used to determine compatibility -type Client struct { +type Signature struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Client name (e.g avalanchego) - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Client semantic version - Major uint32 `protobuf:"varint,2,opt,name=major,proto3" json:"major,omitempty"` - Minor uint32 `protobuf:"varint,3,opt,name=minor,proto3" json:"minor,omitempty"` - Patch uint32 `protobuf:"varint,4,opt,name=patch,proto3" json:"patch,omitempty"` + Signer []byte `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } -func (x *Client) Reset() { - *x = Client{} - mi := &file_p2p_p2p_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) +func (x *Signature) Reset() { + *x = Signature{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } -func (x *Client) String() string { +func (x *Signature) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Client) ProtoMessage() {} +func (*Signature) ProtoMessage() {} -func (x *Client) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[4] - if x != nil { +func (x *Signature) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -771,21 +895,663 @@ func (x *Client) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Client.ProtoReflect.Descriptor instead. -func (*Client) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{4} +// Deprecated: Use Signature.ProtoReflect.Descriptor instead. +func (*Signature) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{5} } -func (x *Client) GetName() string { +func (x *Signature) GetSigner() []byte { if x != nil { - return x.Name + return x.Signer } - return "" + return nil } -func (x *Client) GetMajor() uint32 { +func (x *Signature) GetValue() []byte { if x != nil { - return x.Major + return x.Value + } + return nil +} + +type Vote struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vote *BlockHeader `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *Vote) Reset() { + *x = Vote{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Vote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Vote) ProtoMessage() {} + +func (x *Vote) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Vote.ProtoReflect.Descriptor instead. +func (*Vote) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{6} +} + +func (x *Vote) GetVote() *BlockHeader { + if x != nil { + return x.Vote + } + return nil +} + +func (x *Vote) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type EmptyVote struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vote *ProtocolMetadata `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *EmptyVote) Reset() { + *x = EmptyVote{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmptyVote) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyVote) ProtoMessage() {} + +func (x *EmptyVote) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptyVote.ProtoReflect.Descriptor instead. +func (*EmptyVote) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{7} +} + +func (x *EmptyVote) GetVote() *ProtocolMetadata { + if x != nil { + return x.Vote + } + return nil +} + +func (x *EmptyVote) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type Finalization struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vote *BlockHeader `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` + Signature *Signature `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *Finalization) Reset() { + *x = Finalization{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Finalization) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Finalization) ProtoMessage() {} + +func (x *Finalization) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Finalization.ProtoReflect.Descriptor instead. +func (*Finalization) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{8} +} + +func (x *Finalization) GetVote() *BlockHeader { + if x != nil { + return x.Vote + } + return nil +} + +func (x *Finalization) GetSignature() *Signature { + if x != nil { + return x.Signature + } + return nil +} + +type FinalizationCertificate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Finalization *Finalization `protobuf:"bytes,1,opt,name=finalization,proto3" json:"finalization,omitempty"` + QuorumCertificate []byte `protobuf:"bytes,2,opt,name=quorum_certificate,json=quorumCertificate,proto3" json:"quorum_certificate,omitempty"` +} + +func (x *FinalizationCertificate) Reset() { + *x = FinalizationCertificate{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FinalizationCertificate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FinalizationCertificate) ProtoMessage() {} + +func (x *FinalizationCertificate) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FinalizationCertificate.ProtoReflect.Descriptor instead. +func (*FinalizationCertificate) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{9} +} + +func (x *FinalizationCertificate) GetFinalization() *Finalization { + if x != nil { + return x.Finalization + } + return nil +} + +func (x *FinalizationCertificate) GetQuorumCertificate() []byte { + if x != nil { + return x.QuorumCertificate + } + return nil +} + +type Notarization struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Vote *BlockHeader `protobuf:"bytes,1,opt,name=vote,proto3" json:"vote,omitempty"` + QuorumCertificate []byte `protobuf:"bytes,2,opt,name=quorum_certificate,json=quorumCertificate,proto3" json:"quorum_certificate,omitempty"` +} + +func (x *Notarization) Reset() { + *x = Notarization{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Notarization) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Notarization) ProtoMessage() {} + +func (x *Notarization) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Notarization.ProtoReflect.Descriptor instead. +func (*Notarization) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{10} +} + +func (x *Notarization) GetVote() *BlockHeader { + if x != nil { + return x.Vote + } + return nil +} + +func (x *Notarization) GetQuorumCertificate() []byte { + if x != nil { + return x.QuorumCertificate + } + return nil +} + +type EmptyNotarization struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + EmptyVote *BlockHeader `protobuf:"bytes,1,opt,name=empty_vote,json=emptyVote,proto3" json:"empty_vote,omitempty"` + QuorumCertificate []byte `protobuf:"bytes,2,opt,name=quorum_certificate,json=quorumCertificate,proto3" json:"quorum_certificate,omitempty"` +} + +func (x *EmptyNotarization) Reset() { + *x = EmptyNotarization{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmptyNotarization) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmptyNotarization) ProtoMessage() {} + +func (x *EmptyNotarization) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmptyNotarization.ProtoReflect.Descriptor instead. +func (*EmptyNotarization) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{11} +} + +func (x *EmptyNotarization) GetEmptyVote() *BlockHeader { + if x != nil { + return x.EmptyVote + } + return nil +} + +func (x *EmptyNotarization) GetQuorumCertificate() []byte { + if x != nil { + return x.QuorumCertificate + } + return nil +} + +// Ping reports a peer's perceived uptime percentage. +// +// Peers should respond to Ping with a Pong. +type Ping struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Uptime percentage on the primary network [0, 100] + Uptime uint32 `protobuf:"varint,1,opt,name=uptime,proto3" json:"uptime,omitempty"` +} + +func (x *Ping) Reset() { + *x = Ping{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Ping) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Ping) ProtoMessage() {} + +func (x *Ping) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Ping.ProtoReflect.Descriptor instead. +func (*Ping) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{12} +} + +func (x *Ping) GetUptime() uint32 { + if x != nil { + return x.Uptime + } + return 0 +} + +// Pong is sent in response to a Ping. +type Pong struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Pong) Reset() { + *x = Pong{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Pong) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Pong) ProtoMessage() {} + +func (x *Pong) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Pong.ProtoReflect.Descriptor instead. +func (*Pong) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{13} +} + +// Handshake is the first outbound message sent to a peer when a connection is +// established to start the p2p handshake. +// +// Peers must respond to a Handshake message with a PeerList message to allow the +// peer to connect to other peers in the network. +// +// Peers should drop connections to peers with incompatible versions. +type Handshake struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Network the peer is running on (e.g local, testnet, mainnet) + NetworkId uint32 `protobuf:"varint,1,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"` + // Unix timestamp when this Handshake message was created + MyTime uint64 `protobuf:"varint,2,opt,name=my_time,json=myTime,proto3" json:"my_time,omitempty"` + // IP address of the peer + IpAddr []byte `protobuf:"bytes,3,opt,name=ip_addr,json=ipAddr,proto3" json:"ip_addr,omitempty"` + // IP port of the peer + IpPort uint32 `protobuf:"varint,4,opt,name=ip_port,json=ipPort,proto3" json:"ip_port,omitempty"` + // Timestamp of the IP + IpSigningTime uint64 `protobuf:"varint,6,opt,name=ip_signing_time,json=ipSigningTime,proto3" json:"ip_signing_time,omitempty"` + // Signature of the peer IP port pair at a provided timestamp with the TLS + // key. + IpNodeIdSig []byte `protobuf:"bytes,7,opt,name=ip_node_id_sig,json=ipNodeIdSig,proto3" json:"ip_node_id_sig,omitempty"` + // Subnets the peer is tracking + TrackedSubnets [][]byte `protobuf:"bytes,8,rep,name=tracked_subnets,json=trackedSubnets,proto3" json:"tracked_subnets,omitempty"` + Client *Client `protobuf:"bytes,9,opt,name=client,proto3" json:"client,omitempty"` + SupportedAcps []uint32 `protobuf:"varint,10,rep,packed,name=supported_acps,json=supportedAcps,proto3" json:"supported_acps,omitempty"` + ObjectedAcps []uint32 `protobuf:"varint,11,rep,packed,name=objected_acps,json=objectedAcps,proto3" json:"objected_acps,omitempty"` + KnownPeers *BloomFilter `protobuf:"bytes,12,opt,name=known_peers,json=knownPeers,proto3" json:"known_peers,omitempty"` + // Signature of the peer IP port pair at a provided timestamp with the BLS + // key. + IpBlsSig []byte `protobuf:"bytes,13,opt,name=ip_bls_sig,json=ipBlsSig,proto3" json:"ip_bls_sig,omitempty"` + // To avoid sending IPs that the client isn't interested in tracking, the + // server expects the client to confirm that it is tracking all subnets. + AllSubnets bool `protobuf:"varint,14,opt,name=all_subnets,json=allSubnets,proto3" json:"all_subnets,omitempty"` +} + +func (x *Handshake) Reset() { + *x = Handshake{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Handshake) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Handshake) ProtoMessage() {} + +func (x *Handshake) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Handshake.ProtoReflect.Descriptor instead. +func (*Handshake) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{14} +} + +func (x *Handshake) GetNetworkId() uint32 { + if x != nil { + return x.NetworkId + } + return 0 +} + +func (x *Handshake) GetMyTime() uint64 { + if x != nil { + return x.MyTime + } + return 0 +} + +func (x *Handshake) GetIpAddr() []byte { + if x != nil { + return x.IpAddr + } + return nil +} + +func (x *Handshake) GetIpPort() uint32 { + if x != nil { + return x.IpPort + } + return 0 +} + +func (x *Handshake) GetIpSigningTime() uint64 { + if x != nil { + return x.IpSigningTime + } + return 0 +} + +func (x *Handshake) GetIpNodeIdSig() []byte { + if x != nil { + return x.IpNodeIdSig + } + return nil +} + +func (x *Handshake) GetTrackedSubnets() [][]byte { + if x != nil { + return x.TrackedSubnets + } + return nil +} + +func (x *Handshake) GetClient() *Client { + if x != nil { + return x.Client + } + return nil +} + +func (x *Handshake) GetSupportedAcps() []uint32 { + if x != nil { + return x.SupportedAcps + } + return nil +} + +func (x *Handshake) GetObjectedAcps() []uint32 { + if x != nil { + return x.ObjectedAcps + } + return nil +} + +func (x *Handshake) GetKnownPeers() *BloomFilter { + if x != nil { + return x.KnownPeers + } + return nil +} + +func (x *Handshake) GetIpBlsSig() []byte { + if x != nil { + return x.IpBlsSig + } + return nil +} + +func (x *Handshake) GetAllSubnets() bool { + if x != nil { + return x.AllSubnets + } + return false +} + +// Metadata about a peer's P2P client used to determine compatibility +type Client struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Client name (e.g avalanchego) + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Client semantic version + Major uint32 `protobuf:"varint,2,opt,name=major,proto3" json:"major,omitempty"` + Minor uint32 `protobuf:"varint,3,opt,name=minor,proto3" json:"minor,omitempty"` + Patch uint32 `protobuf:"varint,4,opt,name=patch,proto3" json:"patch,omitempty"` +} + +func (x *Client) Reset() { + *x = Client{} + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Client) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Client) ProtoMessage() {} + +func (x *Client) ProtoReflect() protoreflect.Message { + mi := &file_p2p_p2p_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Client.ProtoReflect.Descriptor instead. +func (*Client) Descriptor() ([]byte, []int) { + return file_p2p_p2p_proto_rawDescGZIP(), []int{15} +} + +func (x *Client) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Client) GetMajor() uint32 { + if x != nil { + return x.Major } return 0 } @@ -816,9 +1582,11 @@ type BloomFilter struct { func (x *BloomFilter) Reset() { *x = BloomFilter{} - mi := &file_p2p_p2p_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *BloomFilter) String() string { @@ -828,8 +1596,8 @@ func (x *BloomFilter) String() string { func (*BloomFilter) ProtoMessage() {} func (x *BloomFilter) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[5] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -841,7 +1609,7 @@ func (x *BloomFilter) ProtoReflect() protoreflect.Message { // Deprecated: Use BloomFilter.ProtoReflect.Descriptor instead. func (*BloomFilter) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{5} + return file_p2p_p2p_proto_rawDescGZIP(), []int{16} } func (x *BloomFilter) GetFilter() []byte { @@ -880,9 +1648,11 @@ type ClaimedIpPort struct { func (x *ClaimedIpPort) Reset() { *x = ClaimedIpPort{} - mi := &file_p2p_p2p_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *ClaimedIpPort) String() string { @@ -892,8 +1662,8 @@ func (x *ClaimedIpPort) String() string { func (*ClaimedIpPort) ProtoMessage() {} func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[6] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -905,7 +1675,7 @@ func (x *ClaimedIpPort) ProtoReflect() protoreflect.Message { // Deprecated: Use ClaimedIpPort.ProtoReflect.Descriptor instead. func (*ClaimedIpPort) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{6} + return file_p2p_p2p_proto_rawDescGZIP(), []int{17} } func (x *ClaimedIpPort) GetX509Certificate() []byte { @@ -967,9 +1737,11 @@ type GetPeerList struct { func (x *GetPeerList) Reset() { *x = GetPeerList{} - mi := &file_p2p_p2p_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetPeerList) String() string { @@ -979,8 +1751,8 @@ func (x *GetPeerList) String() string { func (*GetPeerList) ProtoMessage() {} func (x *GetPeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[7] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -992,7 +1764,7 @@ func (x *GetPeerList) ProtoReflect() protoreflect.Message { // Deprecated: Use GetPeerList.ProtoReflect.Descriptor instead. func (*GetPeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{7} + return file_p2p_p2p_proto_rawDescGZIP(), []int{18} } func (x *GetPeerList) GetKnownPeers() *BloomFilter { @@ -1028,9 +1800,11 @@ type PeerList struct { func (x *PeerList) Reset() { *x = PeerList{} - mi := &file_p2p_p2p_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PeerList) String() string { @@ -1040,8 +1814,8 @@ func (x *PeerList) String() string { func (*PeerList) ProtoMessage() {} func (x *PeerList) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[8] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1053,7 +1827,7 @@ func (x *PeerList) ProtoReflect() protoreflect.Message { // Deprecated: Use PeerList.ProtoReflect.Descriptor instead. func (*PeerList) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{8} + return file_p2p_p2p_proto_rawDescGZIP(), []int{19} } func (x *PeerList) GetClaimedIpPorts() []*ClaimedIpPort { @@ -1080,9 +1854,11 @@ type GetStateSummaryFrontier struct { func (x *GetStateSummaryFrontier) Reset() { *x = GetStateSummaryFrontier{} - mi := &file_p2p_p2p_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetStateSummaryFrontier) String() string { @@ -1092,8 +1868,8 @@ func (x *GetStateSummaryFrontier) String() string { func (*GetStateSummaryFrontier) ProtoMessage() {} func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[9] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1105,7 +1881,7 @@ func (x *GetStateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetStateSummaryFrontier.ProtoReflect.Descriptor instead. func (*GetStateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{9} + return file_p2p_p2p_proto_rawDescGZIP(), []int{20} } func (x *GetStateSummaryFrontier) GetChainId() []byte { @@ -1145,9 +1921,11 @@ type StateSummaryFrontier struct { func (x *StateSummaryFrontier) Reset() { *x = StateSummaryFrontier{} - mi := &file_p2p_p2p_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *StateSummaryFrontier) String() string { @@ -1157,8 +1935,8 @@ func (x *StateSummaryFrontier) String() string { func (*StateSummaryFrontier) ProtoMessage() {} func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[10] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1170,7 +1948,7 @@ func (x *StateSummaryFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use StateSummaryFrontier.ProtoReflect.Descriptor instead. func (*StateSummaryFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{10} + return file_p2p_p2p_proto_rawDescGZIP(), []int{21} } func (x *StateSummaryFrontier) GetChainId() []byte { @@ -1213,9 +1991,11 @@ type GetAcceptedStateSummary struct { func (x *GetAcceptedStateSummary) Reset() { *x = GetAcceptedStateSummary{} - mi := &file_p2p_p2p_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAcceptedStateSummary) String() string { @@ -1225,8 +2005,8 @@ func (x *GetAcceptedStateSummary) String() string { func (*GetAcceptedStateSummary) ProtoMessage() {} func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[11] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1238,7 +2018,7 @@ func (x *GetAcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedStateSummary.ProtoReflect.Descriptor instead. func (*GetAcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{11} + return file_p2p_p2p_proto_rawDescGZIP(), []int{22} } func (x *GetAcceptedStateSummary) GetChainId() []byte { @@ -1285,9 +2065,11 @@ type AcceptedStateSummary struct { func (x *AcceptedStateSummary) Reset() { *x = AcceptedStateSummary{} - mi := &file_p2p_p2p_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AcceptedStateSummary) String() string { @@ -1297,8 +2079,8 @@ func (x *AcceptedStateSummary) String() string { func (*AcceptedStateSummary) ProtoMessage() {} func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[12] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1310,7 +2092,7 @@ func (x *AcceptedStateSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedStateSummary.ProtoReflect.Descriptor instead. func (*AcceptedStateSummary) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{12} + return file_p2p_p2p_proto_rawDescGZIP(), []int{23} } func (x *AcceptedStateSummary) GetChainId() []byte { @@ -1352,9 +2134,11 @@ type GetAcceptedFrontier struct { func (x *GetAcceptedFrontier) Reset() { *x = GetAcceptedFrontier{} - mi := &file_p2p_p2p_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAcceptedFrontier) String() string { @@ -1364,8 +2148,8 @@ func (x *GetAcceptedFrontier) String() string { func (*GetAcceptedFrontier) ProtoMessage() {} func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[13] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1377,7 +2161,7 @@ func (x *GetAcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAcceptedFrontier.ProtoReflect.Descriptor instead. func (*GetAcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{13} + return file_p2p_p2p_proto_rawDescGZIP(), []int{24} } func (x *GetAcceptedFrontier) GetChainId() []byte { @@ -1419,9 +2203,11 @@ type AcceptedFrontier struct { func (x *AcceptedFrontier) Reset() { *x = AcceptedFrontier{} - mi := &file_p2p_p2p_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AcceptedFrontier) String() string { @@ -1431,8 +2217,8 @@ func (x *AcceptedFrontier) String() string { func (*AcceptedFrontier) ProtoMessage() {} func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[14] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1444,7 +2230,7 @@ func (x *AcceptedFrontier) ProtoReflect() protoreflect.Message { // Deprecated: Use AcceptedFrontier.ProtoReflect.Descriptor instead. func (*AcceptedFrontier) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{14} + return file_p2p_p2p_proto_rawDescGZIP(), []int{25} } func (x *AcceptedFrontier) GetChainId() []byte { @@ -1489,9 +2275,11 @@ type GetAccepted struct { func (x *GetAccepted) Reset() { *x = GetAccepted{} - mi := &file_p2p_p2p_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAccepted) String() string { @@ -1501,8 +2289,8 @@ func (x *GetAccepted) String() string { func (*GetAccepted) ProtoMessage() {} func (x *GetAccepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[15] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1514,7 +2302,7 @@ func (x *GetAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAccepted.ProtoReflect.Descriptor instead. func (*GetAccepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{15} + return file_p2p_p2p_proto_rawDescGZIP(), []int{26} } func (x *GetAccepted) GetChainId() []byte { @@ -1564,9 +2352,11 @@ type Accepted struct { func (x *Accepted) Reset() { *x = Accepted{} - mi := &file_p2p_p2p_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Accepted) String() string { @@ -1576,8 +2366,8 @@ func (x *Accepted) String() string { func (*Accepted) ProtoMessage() {} func (x *Accepted) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[16] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1589,7 +2379,7 @@ func (x *Accepted) ProtoReflect() protoreflect.Message { // Deprecated: Use Accepted.ProtoReflect.Descriptor instead. func (*Accepted) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{16} + return file_p2p_p2p_proto_rawDescGZIP(), []int{27} } func (x *Accepted) GetChainId() []byte { @@ -1635,9 +2425,11 @@ type GetAncestors struct { func (x *GetAncestors) Reset() { *x = GetAncestors{} - mi := &file_p2p_p2p_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *GetAncestors) String() string { @@ -1647,8 +2439,8 @@ func (x *GetAncestors) String() string { func (*GetAncestors) ProtoMessage() {} func (x *GetAncestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[17] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1660,7 +2452,7 @@ func (x *GetAncestors) ProtoReflect() protoreflect.Message { // Deprecated: Use GetAncestors.ProtoReflect.Descriptor instead. func (*GetAncestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{17} + return file_p2p_p2p_proto_rawDescGZIP(), []int{28} } func (x *GetAncestors) GetChainId() []byte { @@ -1717,9 +2509,11 @@ type Ancestors struct { func (x *Ancestors) Reset() { *x = Ancestors{} - mi := &file_p2p_p2p_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Ancestors) String() string { @@ -1729,8 +2523,8 @@ func (x *Ancestors) String() string { func (*Ancestors) ProtoMessage() {} func (x *Ancestors) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[18] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1742,7 +2536,7 @@ func (x *Ancestors) ProtoReflect() protoreflect.Message { // Deprecated: Use Ancestors.ProtoReflect.Descriptor instead. func (*Ancestors) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{18} + return file_p2p_p2p_proto_rawDescGZIP(), []int{29} } func (x *Ancestors) GetChainId() []byte { @@ -1786,9 +2580,11 @@ type Get struct { func (x *Get) Reset() { *x = Get{} - mi := &file_p2p_p2p_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Get) String() string { @@ -1798,8 +2594,8 @@ func (x *Get) String() string { func (*Get) ProtoMessage() {} func (x *Get) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[19] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1811,7 +2607,7 @@ func (x *Get) ProtoReflect() protoreflect.Message { // Deprecated: Use Get.ProtoReflect.Descriptor instead. func (*Get) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{19} + return file_p2p_p2p_proto_rawDescGZIP(), []int{30} } func (x *Get) GetChainId() []byte { @@ -1858,9 +2654,11 @@ type Put struct { func (x *Put) Reset() { *x = Put{} - mi := &file_p2p_p2p_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Put) String() string { @@ -1870,8 +2668,8 @@ func (x *Put) String() string { func (*Put) ProtoMessage() {} func (x *Put) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[20] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1883,7 +2681,7 @@ func (x *Put) ProtoReflect() protoreflect.Message { // Deprecated: Use Put.ProtoReflect.Descriptor instead. func (*Put) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{20} + return file_p2p_p2p_proto_rawDescGZIP(), []int{31} } func (x *Put) GetChainId() []byte { @@ -1929,9 +2727,11 @@ type PushQuery struct { func (x *PushQuery) Reset() { *x = PushQuery{} - mi := &file_p2p_p2p_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PushQuery) String() string { @@ -1941,8 +2741,8 @@ func (x *PushQuery) String() string { func (*PushQuery) ProtoMessage() {} func (x *PushQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[21] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1954,7 +2754,7 @@ func (x *PushQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PushQuery.ProtoReflect.Descriptor instead. func (*PushQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{21} + return file_p2p_p2p_proto_rawDescGZIP(), []int{32} } func (x *PushQuery) GetChainId() []byte { @@ -2014,9 +2814,11 @@ type PullQuery struct { func (x *PullQuery) Reset() { *x = PullQuery{} - mi := &file_p2p_p2p_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *PullQuery) String() string { @@ -2026,8 +2828,8 @@ func (x *PullQuery) String() string { func (*PullQuery) ProtoMessage() {} func (x *PullQuery) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[22] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2039,7 +2841,7 @@ func (x *PullQuery) ProtoReflect() protoreflect.Message { // Deprecated: Use PullQuery.ProtoReflect.Descriptor instead. func (*PullQuery) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{22} + return file_p2p_p2p_proto_rawDescGZIP(), []int{33} } func (x *PullQuery) GetChainId() []byte { @@ -2100,9 +2902,11 @@ type Chits struct { func (x *Chits) Reset() { *x = Chits{} - mi := &file_p2p_p2p_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *Chits) String() string { @@ -2112,8 +2916,8 @@ func (x *Chits) String() string { func (*Chits) ProtoMessage() {} func (x *Chits) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[23] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2125,7 +2929,7 @@ func (x *Chits) ProtoReflect() protoreflect.Message { // Deprecated: Use Chits.ProtoReflect.Descriptor instead. func (*Chits) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{23} + return file_p2p_p2p_proto_rawDescGZIP(), []int{34} } func (x *Chits) GetChainId() []byte { @@ -2191,9 +2995,11 @@ type AppRequest struct { func (x *AppRequest) Reset() { *x = AppRequest{} - mi := &file_p2p_p2p_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AppRequest) String() string { @@ -2203,8 +3009,8 @@ func (x *AppRequest) String() string { func (*AppRequest) ProtoMessage() {} func (x *AppRequest) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[24] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2216,7 +3022,7 @@ func (x *AppRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AppRequest.ProtoReflect.Descriptor instead. func (*AppRequest) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{24} + return file_p2p_p2p_proto_rawDescGZIP(), []int{35} } func (x *AppRequest) GetChainId() []byte { @@ -2263,9 +3069,11 @@ type AppResponse struct { func (x *AppResponse) Reset() { *x = AppResponse{} - mi := &file_p2p_p2p_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AppResponse) String() string { @@ -2275,8 +3083,8 @@ func (x *AppResponse) String() string { func (*AppResponse) ProtoMessage() {} func (x *AppResponse) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[25] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2288,7 +3096,7 @@ func (x *AppResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AppResponse.ProtoReflect.Descriptor instead. func (*AppResponse) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{25} + return file_p2p_p2p_proto_rawDescGZIP(), []int{36} } func (x *AppResponse) GetChainId() []byte { @@ -2330,9 +3138,11 @@ type AppError struct { func (x *AppError) Reset() { *x = AppError{} - mi := &file_p2p_p2p_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AppError) String() string { @@ -2342,8 +3152,8 @@ func (x *AppError) String() string { func (*AppError) ProtoMessage() {} func (x *AppError) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[26] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2355,7 +3165,7 @@ func (x *AppError) ProtoReflect() protoreflect.Message { // Deprecated: Use AppError.ProtoReflect.Descriptor instead. func (*AppError) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{26} + return file_p2p_p2p_proto_rawDescGZIP(), []int{37} } func (x *AppError) GetChainId() []byte { @@ -2400,9 +3210,11 @@ type AppGossip struct { func (x *AppGossip) Reset() { *x = AppGossip{} - mi := &file_p2p_p2p_proto_msgTypes[27] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if protoimpl.UnsafeEnabled { + mi := &file_p2p_p2p_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } } func (x *AppGossip) String() string { @@ -2412,8 +3224,8 @@ func (x *AppGossip) String() string { func (*AppGossip) ProtoMessage() {} func (x *AppGossip) ProtoReflect() protoreflect.Message { - mi := &file_p2p_p2p_proto_msgTypes[27] - if x != nil { + mi := &file_p2p_p2p_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2425,7 +3237,7 @@ func (x *AppGossip) ProtoReflect() protoreflect.Message { // Deprecated: Use AppGossip.ProtoReflect.Descriptor instead. func (*AppGossip) Descriptor() ([]byte, []int) { - return file_p2p_p2p_proto_rawDescGZIP(), []int{27} + return file_p2p_p2p_proto_rawDescGZIP(), []int{38} } func (x *AppGossip) GetChainId() []byte { @@ -2446,7 +3258,7 @@ var File_p2p_p2p_proto protoreflect.FileDescriptor var file_p2p_p2p_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x70, 0x32, 0x70, 0x2f, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x03, 0x70, 0x32, 0x70, 0x22, 0xf3, 0x0a, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x03, 0x70, 0x32, 0x70, 0x22, 0xa4, 0x0b, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x7a, 0x73, 0x74, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5a, 0x73, 0x74, 0x64, 0x12, 0x1f, 0x0a, 0x04, 0x70, @@ -2532,152 +3344,227 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x2c, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x22, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x48, 0x00, 0x52, 0x08, 0x61, 0x70, 0x70, 0x45, 0x72, - 0x72, 0x6f, 0x72, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4a, 0x04, - 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x22, 0x24, 0x0a, 0x04, 0x50, 0x69, - 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, - 0x22, 0x12, 0x0a, 0x04, 0x50, 0x6f, 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, - 0x08, 0x02, 0x10, 0x03, 0x22, 0xd4, 0x03, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, - 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, - 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, - 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, - 0x69, 0x70, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0e, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, - 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x70, - 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x53, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, - 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, - 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, - 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, - 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, - 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, - 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, - 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, - 0x63, 0x70, 0x73, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, - 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, - 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x62, 0x6c, 0x73, - 0x5f, 0x73, 0x69, 0x67, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x69, 0x70, 0x42, 0x6c, - 0x73, 0x53, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x6e, - 0x65, 0x74, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x53, 0x75, - 0x62, 0x6e, 0x65, 0x74, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x5e, 0x0a, 0x06, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, - 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, - 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x0b, 0x42, - 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, - 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, - 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, - 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, - 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, - 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, 0x22, 0x61, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, - 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, - 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, - 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, - 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, - 0x6c, 0x6c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, - 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, - 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, - 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, - 0x72, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, - 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, + 0x72, 0x6f, 0x72, 0x12, 0x2f, 0x0a, 0x07, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x18, 0x21, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x07, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x78, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4a, + 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x24, 0x10, 0x25, 0x22, 0xc2, 0x03, 0x0a, 0x0e, + 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x78, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, - 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, - 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, - 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, - 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, - 0x71, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x05, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1f, 0x0a, + 0x04, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x32, + 0x70, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x48, 0x00, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x2f, + 0x0a, 0x0a, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, + 0x74, 0x65, 0x48, 0x00, 0x52, 0x09, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, 0x74, 0x65, 0x12, + 0x37, 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x46, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x6e, 0x6f, 0x74, 0x61, + 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x0c, 0x6e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x47, 0x0a, 0x12, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x6e, 0x6f, 0x74, 0x61, 0x72, + 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x11, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, + 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x59, 0x0a, 0x18, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x3c, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x12, + 0x1d, 0x0a, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, + 0x70, 0x32, 0x70, 0x2e, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x22, 0x7e, + 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x65, 0x71, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x73, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x72, + 0x65, 0x76, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x70, 0x72, 0x65, 0x76, 0x22, 0x58, + 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x31, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x09, 0x53, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x5a, 0x0a, 0x04, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x76, + 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x04, 0x76, 0x6f, 0x74, + 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, + 0x64, 0x0a, 0x09, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x29, 0x0a, 0x04, + 0x76, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x62, 0x0a, 0x0c, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, 0x12, 0x2c, 0x0a, 0x09, 0x73, + 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x7f, 0x0a, 0x17, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x32, 0x70, + 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12, 0x71, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x63, 0x0a, 0x0c, 0x4e, 0x6f, + 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x04, 0x76, 0x6f, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x04, 0x76, 0x6f, 0x74, 0x65, + 0x12, 0x2d, 0x0a, 0x12, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x71, 0x75, + 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, + 0x73, 0x0a, 0x11, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x61, 0x72, 0x69, 0x7a, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2f, 0x0a, 0x0a, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x6f, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x09, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x2d, 0x0a, 0x12, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x5f, + 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x22, 0x24, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x06, + 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x75, 0x70, + 0x74, 0x69, 0x6d, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0x12, 0x0a, 0x04, 0x50, 0x6f, + 0x6e, 0x67, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, 0xd4, + 0x03, 0x0a, 0x09, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x1d, 0x0a, 0x0a, + 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x6d, + 0x79, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, + 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, + 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x70, 0x5f, 0x73, 0x69, 0x67, + 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0d, 0x69, 0x70, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x23, + 0x0a, 0x0e, 0x69, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x5f, 0x73, 0x69, 0x67, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x69, 0x70, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x53, 0x69, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x5f, 0x73, + 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0e, 0x74, 0x72, + 0x61, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x12, 0x23, 0x0a, 0x06, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, + 0x32, 0x70, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x63, 0x70, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0d, 0x73, 0x75, 0x70, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, + 0x0c, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x41, 0x63, 0x70, 0x73, 0x12, 0x31, 0x0a, + 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, 0x72, 0x73, + 0x12, 0x1c, 0x0a, 0x0a, 0x69, 0x70, 0x5f, 0x62, 0x6c, 0x73, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x69, 0x70, 0x42, 0x6c, 0x73, 0x53, 0x69, 0x67, 0x12, 0x1f, + 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x53, 0x75, 0x62, 0x6e, 0x65, 0x74, 0x73, 0x4a, + 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x5e, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, + 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0x39, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, + 0x73, 0x61, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x73, 0x61, 0x6c, 0x74, + 0x22, 0xbd, 0x01, 0x0a, 0x0d, 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, + 0x72, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x78, 0x35, 0x30, 0x39, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x78, 0x35, + 0x30, 0x39, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x74, + 0x78, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x74, 0x78, 0x49, 0x64, + 0x22, 0x61, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x31, 0x0a, 0x0b, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x5f, 0x70, 0x65, 0x65, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, + 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x65, 0x65, + 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x75, 0x62, 0x6e, 0x65, 0x74, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x53, 0x75, 0x62, 0x6e, + 0x65, 0x74, 0x73, 0x22, 0x48, 0x0a, 0x08, 0x50, 0x65, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, + 0x3c, 0x0a, 0x10, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x69, 0x70, 0x5f, 0x70, 0x6f, + 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x32, 0x70, 0x2e, + 0x43, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x0e, 0x63, + 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x49, 0x70, 0x50, 0x6f, 0x72, 0x74, 0x73, 0x22, 0x6f, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, + 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, + 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x6a, + 0x0a, 0x14, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x04, 0x08, 0x04, - 0x10, 0x05, 0x22, 0x6f, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, - 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, + 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x89, 0x01, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x49, 0x64, 0x22, 0x8e, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, - 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, - 0x08, 0x05, 0x10, 0x06, 0x22, 0x69, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x04, 0x52, 0x07, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, + 0x65, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x6d, 0x6d, + 0x61, 0x72, 0x79, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x49, 0x64, 0x73, 0x22, 0x71, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, - 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x22, 0x6f, 0x0a, 0x10, + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x69, 0x65, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, - 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, - 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, - 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x65, 0x0a, 0x09, 0x41, - 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x8e, 0x01, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, + 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, + 0x69, 0x6e, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x69, + 0x0a, 0x08, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x0c, 0x47, 0x65, + 0x74, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, @@ -2685,87 +3572,105 @@ var file_p2p_p2p_proto_rawDesc = []byte{ 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x5d, 0x0a, 0x03, 0x50, 0x75, 0x74, + 0x72, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0b, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x70, 0x32, 0x70, 0x2e, 0x45, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x65, 0x6e, 0x67, 0x69, 0x6e, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x22, 0x65, 0x0a, 0x09, 0x41, 0x6e, 0x63, 0x65, 0x73, 0x74, 0x6f, + 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x84, 0x01, 0x0a, + 0x03, 0x47, 0x65, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, + 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x4a, 0x04, 0x08, + 0x05, 0x10, 0x06, 0x22, 0x5d, 0x0a, 0x03, 0x50, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x22, 0xb0, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0xb0, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x73, - 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, - 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xb5, 0x01, 0x0a, 0x09, - 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, - 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, - 0x05, 0x10, 0x06, 0x22, 0xe3, 0x01, 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, - 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, - 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, + 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, + 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xb5, 0x01, 0x0a, 0x09, 0x50, 0x75, 0x6c, 0x6c, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x65, + 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xe3, 0x01, + 0x0a, 0x05, 0x43, 0x68, 0x69, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, - 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, - 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, - 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, - 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, - 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, - 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, - 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, - 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, - 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, - 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, - 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x70, + 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, + 0x65, 0x64, 0x5f, 0x69, 0x64, 0x5f, 0x61, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, + 0x49, 0x64, 0x41, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x63, + 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x48, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x22, 0x7f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, + 0x65, 0x61, 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x0b, 0x41, 0x70, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x41, + 0x70, 0x70, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, + 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x43, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x47, 0x6f, 0x73, 0x73, + 0x69, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, + 0x09, 0x61, 0x70, 0x70, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x08, 0x61, 0x70, 0x70, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x5d, 0x0a, 0x0a, 0x45, 0x6e, + 0x67, 0x69, 0x6e, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x4e, 0x47, 0x49, + 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x56, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x48, 0x45, 0x10, 0x01, + 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4e, 0x47, 0x49, 0x4e, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, + 0x53, 0x4e, 0x4f, 0x57, 0x4d, 0x41, 0x4e, 0x10, 0x02, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, + 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x70, 0x32, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -2781,73 +3686,103 @@ func file_p2p_p2p_proto_rawDescGZIP() []byte { } var file_p2p_p2p_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 28) -var file_p2p_p2p_proto_goTypes = []any{ +var file_p2p_p2p_proto_msgTypes = make([]protoimpl.MessageInfo, 39) +var file_p2p_p2p_proto_goTypes = []interface{}{ (EngineType)(0), // 0: p2p.EngineType (*Message)(nil), // 1: p2p.Message - (*Ping)(nil), // 2: p2p.Ping - (*Pong)(nil), // 3: p2p.Pong - (*Handshake)(nil), // 4: p2p.Handshake - (*Client)(nil), // 5: p2p.Client - (*BloomFilter)(nil), // 6: p2p.BloomFilter - (*ClaimedIpPort)(nil), // 7: p2p.ClaimedIpPort - (*GetPeerList)(nil), // 8: p2p.GetPeerList - (*PeerList)(nil), // 9: p2p.PeerList - (*GetStateSummaryFrontier)(nil), // 10: p2p.GetStateSummaryFrontier - (*StateSummaryFrontier)(nil), // 11: p2p.StateSummaryFrontier - (*GetAcceptedStateSummary)(nil), // 12: p2p.GetAcceptedStateSummary - (*AcceptedStateSummary)(nil), // 13: p2p.AcceptedStateSummary - (*GetAcceptedFrontier)(nil), // 14: p2p.GetAcceptedFrontier - (*AcceptedFrontier)(nil), // 15: p2p.AcceptedFrontier - (*GetAccepted)(nil), // 16: p2p.GetAccepted - (*Accepted)(nil), // 17: p2p.Accepted - (*GetAncestors)(nil), // 18: p2p.GetAncestors - (*Ancestors)(nil), // 19: p2p.Ancestors - (*Get)(nil), // 20: p2p.Get - (*Put)(nil), // 21: p2p.Put - (*PushQuery)(nil), // 22: p2p.PushQuery - (*PullQuery)(nil), // 23: p2p.PullQuery - (*Chits)(nil), // 24: p2p.Chits - (*AppRequest)(nil), // 25: p2p.AppRequest - (*AppResponse)(nil), // 26: p2p.AppResponse - (*AppError)(nil), // 27: p2p.AppError - (*AppGossip)(nil), // 28: p2p.AppGossip + (*SimplexMessage)(nil), // 2: p2p.SimplexMessage + (*Block)(nil), // 3: p2p.Block + (*ProtocolMetadata)(nil), // 4: p2p.ProtocolMetadata + (*BlockHeader)(nil), // 5: p2p.BlockHeader + (*Signature)(nil), // 6: p2p.Signature + (*Vote)(nil), // 7: p2p.Vote + (*EmptyVote)(nil), // 8: p2p.EmptyVote + (*Finalization)(nil), // 9: p2p.Finalization + (*FinalizationCertificate)(nil), // 10: p2p.FinalizationCertificate + (*Notarization)(nil), // 11: p2p.Notarization + (*EmptyNotarization)(nil), // 12: p2p.EmptyNotarization + (*Ping)(nil), // 13: p2p.Ping + (*Pong)(nil), // 14: p2p.Pong + (*Handshake)(nil), // 15: p2p.Handshake + (*Client)(nil), // 16: p2p.Client + (*BloomFilter)(nil), // 17: p2p.BloomFilter + (*ClaimedIpPort)(nil), // 18: p2p.ClaimedIpPort + (*GetPeerList)(nil), // 19: p2p.GetPeerList + (*PeerList)(nil), // 20: p2p.PeerList + (*GetStateSummaryFrontier)(nil), // 21: p2p.GetStateSummaryFrontier + (*StateSummaryFrontier)(nil), // 22: p2p.StateSummaryFrontier + (*GetAcceptedStateSummary)(nil), // 23: p2p.GetAcceptedStateSummary + (*AcceptedStateSummary)(nil), // 24: p2p.AcceptedStateSummary + (*GetAcceptedFrontier)(nil), // 25: p2p.GetAcceptedFrontier + (*AcceptedFrontier)(nil), // 26: p2p.AcceptedFrontier + (*GetAccepted)(nil), // 27: p2p.GetAccepted + (*Accepted)(nil), // 28: p2p.Accepted + (*GetAncestors)(nil), // 29: p2p.GetAncestors + (*Ancestors)(nil), // 30: p2p.Ancestors + (*Get)(nil), // 31: p2p.Get + (*Put)(nil), // 32: p2p.Put + (*PushQuery)(nil), // 33: p2p.PushQuery + (*PullQuery)(nil), // 34: p2p.PullQuery + (*Chits)(nil), // 35: p2p.Chits + (*AppRequest)(nil), // 36: p2p.AppRequest + (*AppResponse)(nil), // 37: p2p.AppResponse + (*AppError)(nil), // 38: p2p.AppError + (*AppGossip)(nil), // 39: p2p.AppGossip } var file_p2p_p2p_proto_depIdxs = []int32{ - 2, // 0: p2p.Message.ping:type_name -> p2p.Ping - 3, // 1: p2p.Message.pong:type_name -> p2p.Pong - 4, // 2: p2p.Message.handshake:type_name -> p2p.Handshake - 8, // 3: p2p.Message.get_peer_list:type_name -> p2p.GetPeerList - 9, // 4: p2p.Message.peer_list:type_name -> p2p.PeerList - 10, // 5: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier - 11, // 6: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier - 12, // 7: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary - 13, // 8: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary - 14, // 9: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier - 15, // 10: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier - 16, // 11: p2p.Message.get_accepted:type_name -> p2p.GetAccepted - 17, // 12: p2p.Message.accepted:type_name -> p2p.Accepted - 18, // 13: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors - 19, // 14: p2p.Message.ancestors:type_name -> p2p.Ancestors - 20, // 15: p2p.Message.get:type_name -> p2p.Get - 21, // 16: p2p.Message.put:type_name -> p2p.Put - 22, // 17: p2p.Message.push_query:type_name -> p2p.PushQuery - 23, // 18: p2p.Message.pull_query:type_name -> p2p.PullQuery - 24, // 19: p2p.Message.chits:type_name -> p2p.Chits - 25, // 20: p2p.Message.app_request:type_name -> p2p.AppRequest - 26, // 21: p2p.Message.app_response:type_name -> p2p.AppResponse - 28, // 22: p2p.Message.app_gossip:type_name -> p2p.AppGossip - 27, // 23: p2p.Message.app_error:type_name -> p2p.AppError - 5, // 24: p2p.Handshake.client:type_name -> p2p.Client - 6, // 25: p2p.Handshake.known_peers:type_name -> p2p.BloomFilter - 6, // 26: p2p.GetPeerList.known_peers:type_name -> p2p.BloomFilter - 7, // 27: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort - 0, // 28: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType - 29, // [29:29] is the sub-list for method output_type - 29, // [29:29] is the sub-list for method input_type - 29, // [29:29] is the sub-list for extension type_name - 29, // [29:29] is the sub-list for extension extendee - 0, // [0:29] is the sub-list for field type_name + 13, // 0: p2p.Message.ping:type_name -> p2p.Ping + 14, // 1: p2p.Message.pong:type_name -> p2p.Pong + 15, // 2: p2p.Message.handshake:type_name -> p2p.Handshake + 19, // 3: p2p.Message.get_peer_list:type_name -> p2p.GetPeerList + 20, // 4: p2p.Message.peer_list:type_name -> p2p.PeerList + 21, // 5: p2p.Message.get_state_summary_frontier:type_name -> p2p.GetStateSummaryFrontier + 22, // 6: p2p.Message.state_summary_frontier:type_name -> p2p.StateSummaryFrontier + 23, // 7: p2p.Message.get_accepted_state_summary:type_name -> p2p.GetAcceptedStateSummary + 24, // 8: p2p.Message.accepted_state_summary:type_name -> p2p.AcceptedStateSummary + 25, // 9: p2p.Message.get_accepted_frontier:type_name -> p2p.GetAcceptedFrontier + 26, // 10: p2p.Message.accepted_frontier:type_name -> p2p.AcceptedFrontier + 27, // 11: p2p.Message.get_accepted:type_name -> p2p.GetAccepted + 28, // 12: p2p.Message.accepted:type_name -> p2p.Accepted + 29, // 13: p2p.Message.get_ancestors:type_name -> p2p.GetAncestors + 30, // 14: p2p.Message.ancestors:type_name -> p2p.Ancestors + 31, // 15: p2p.Message.get:type_name -> p2p.Get + 32, // 16: p2p.Message.put:type_name -> p2p.Put + 33, // 17: p2p.Message.push_query:type_name -> p2p.PushQuery + 34, // 18: p2p.Message.pull_query:type_name -> p2p.PullQuery + 35, // 19: p2p.Message.chits:type_name -> p2p.Chits + 36, // 20: p2p.Message.app_request:type_name -> p2p.AppRequest + 37, // 21: p2p.Message.app_response:type_name -> p2p.AppResponse + 39, // 22: p2p.Message.app_gossip:type_name -> p2p.AppGossip + 38, // 23: p2p.Message.app_error:type_name -> p2p.AppError + 2, // 24: p2p.Message.simplex:type_name -> p2p.SimplexMessage + 3, // 25: p2p.SimplexMessage.block:type_name -> p2p.Block + 7, // 26: p2p.SimplexMessage.vote:type_name -> p2p.Vote + 8, // 27: p2p.SimplexMessage.empty_vote:type_name -> p2p.EmptyVote + 9, // 28: p2p.SimplexMessage.finalization:type_name -> p2p.Finalization + 11, // 29: p2p.SimplexMessage.notarization:type_name -> p2p.Notarization + 12, // 30: p2p.SimplexMessage.empty_notarization:type_name -> p2p.EmptyNotarization + 10, // 31: p2p.SimplexMessage.finalization_certificate:type_name -> p2p.FinalizationCertificate + 7, // 32: p2p.Block.vote:type_name -> p2p.Vote + 4, // 33: p2p.BlockHeader.metadata:type_name -> p2p.ProtocolMetadata + 5, // 34: p2p.Vote.vote:type_name -> p2p.BlockHeader + 6, // 35: p2p.Vote.signature:type_name -> p2p.Signature + 4, // 36: p2p.EmptyVote.vote:type_name -> p2p.ProtocolMetadata + 6, // 37: p2p.EmptyVote.signature:type_name -> p2p.Signature + 5, // 38: p2p.Finalization.vote:type_name -> p2p.BlockHeader + 6, // 39: p2p.Finalization.signature:type_name -> p2p.Signature + 9, // 40: p2p.FinalizationCertificate.finalization:type_name -> p2p.Finalization + 5, // 41: p2p.Notarization.vote:type_name -> p2p.BlockHeader + 5, // 42: p2p.EmptyNotarization.empty_vote:type_name -> p2p.BlockHeader + 16, // 43: p2p.Handshake.client:type_name -> p2p.Client + 17, // 44: p2p.Handshake.known_peers:type_name -> p2p.BloomFilter + 17, // 45: p2p.GetPeerList.known_peers:type_name -> p2p.BloomFilter + 18, // 46: p2p.PeerList.claimed_ip_ports:type_name -> p2p.ClaimedIpPort + 0, // 47: p2p.GetAncestors.engine_type:type_name -> p2p.EngineType + 48, // [48:48] is the sub-list for method output_type + 48, // [48:48] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { file_p2p_p2p_proto_init() } @@ -2855,7 +3790,477 @@ func file_p2p_p2p_proto_init() { if File_p2p_p2p_proto != nil { return } - file_p2p_p2p_proto_msgTypes[0].OneofWrappers = []any{ + if !protoimpl.UnsafeEnabled { + file_p2p_p2p_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SimplexMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtocolMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlockHeader); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Signature); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Vote); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptyVote); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Finalization); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FinalizationCertificate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Notarization); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmptyNotarization); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Ping); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Pong); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Handshake); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Client); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BloomFilter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClaimedIpPort); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetPeerList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PeerList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetStateSummaryFrontier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StateSummaryFrontier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAcceptedStateSummary); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AcceptedStateSummary); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAcceptedFrontier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AcceptedFrontier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAccepted); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Accepted); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetAncestors); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Ancestors); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Get); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Put); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PushQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PullQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Chits); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppError); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_p2p_p2p_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppGossip); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_p2p_p2p_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Message_CompressedZstd)(nil), (*Message_Ping)(nil), (*Message_Pong)(nil), @@ -2881,6 +4286,16 @@ func file_p2p_p2p_proto_init() { (*Message_AppResponse)(nil), (*Message_AppGossip)(nil), (*Message_AppError)(nil), + (*Message_Simplex)(nil), + } + file_p2p_p2p_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*SimplexMessage_Block)(nil), + (*SimplexMessage_Vote)(nil), + (*SimplexMessage_EmptyVote)(nil), + (*SimplexMessage_Finalization)(nil), + (*SimplexMessage_Notarization)(nil), + (*SimplexMessage_EmptyNotarization)(nil), + (*SimplexMessage_FinalizationCertificate)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -2888,7 +4303,7 @@ func file_p2p_p2p_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_p2p_p2p_proto_rawDesc, NumEnums: 1, - NumMessages: 28, + NumMessages: 39, NumExtensions: 0, NumServices: 0, }, diff --git a/scripts/create-L1.sh b/scripts/create-L1.sh new file mode 100755 index 000000000000..6e3c0e7254f5 --- /dev/null +++ b/scripts/create-L1.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash + +set -euo pipefail + +addValidator1="0x00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f26fc08172000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc0d7da000000010000000000000000479f66c8be895830547e70b4b298cafd433dba6e00000000680be75f00000000681e5c5f000000000000c137176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d30000000a0000000100000000000000020000000900000001255a66ca51a499d95deb58a46fc927ce2f501df7efb05f1479b8762af8ad619d7f96efcbc4e23d182575e719622c71fde297e860d88443052205e6cb838c12d5000000000900000001255a66ca51a499d95deb58a46fc927ce2f501df7efb05f1479b8762af8ad619d7f96efcbc4e23d182575e719622c71fde297e860d88443052205e6cb838c12d5002d58bb23" +addValidator2="0x00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f26fc02b0a000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001d5e9ca417ce80de63cc07529d033783198f6fc20248e7bc5d1a780872d58bb2300000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc08172000000010000000000000000de31b4d8b22991d51aa6aa1fc733f23a851a8c9400000000680be75f00000000681e5c5f000000000000c137176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d30000000a0000000100000000000000020000000900000001d3f1bc1c7a8c72aa7f00fe43e9dd3d1d32e8560ac507d60bad1276edc572b00a57b5fca9ac76d8a8631cd018190a3c824e7fff7f76ba99e8ef70dd8d1bb476c3000000000900000001d3f1bc1c7a8c72aa7f00fe43e9dd3d1d32e8560ac507d60bad1276edc572b00a57b5fca9ac76d8a8631cd018190a3c824e7fff7f76ba99e8ef70dd8d1bb476c30026af7599" +addValidator3="0x00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f26fbfd4a2000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001cbcd1e65c18af863583f16f17fe7a2c6f78182f7fef227495bbb13bd26af759900000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc02b0a000000010000000000000000e9094f73698002fd52c90819b457b9fbc866ab8000000000680be75f00000000681e5c5f000000000000c137176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d30000000a000000010000000000000002000000090000000144399f600ca598c171e5e61850b84d0abee869d6cffaa1c448d34257c4f6fd41452112a75ffcbbad87b646aa78c989747356ee5c94ac578d56a4dbbf2f36ba3201000000090000000144399f600ca598c171e5e61850b84d0abee869d6cffaa1c448d34257c4f6fd41452112a75ffcbbad87b646aa78c989747356ee5c94ac578d56a4dbbf2f36ba320131fd5bcf" +addValidator4="0x00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470de4df81a998000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470de4df820000000000010000000000000000aa18d3991cf637aa6c162f5e95cf163f69cd829100000000680be75f00000000681e5c5f000000000000c137176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d30000000a000000010000000000000002000000090000000189f6ef5bba8726ed5c2050dd218f4184a2f250741b2829def3cd7b2db3410c1e223fdbe8ad51e78b75601e506877a2f8be593aa1f760f06ab99baa7018b4833d01000000090000000189f6ef5bba8726ed5c2050dd218f4184a2f250741b2829def3cd7b2db3410c1e223fdbe8ad51e78b75601e506877a2f8be593aa1f760f06ab99baa7018b4833d0111d5f544" +addValidator5="0x00000000000d00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470de4df815330000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000019933739f11b40aecaf496f862d0bec6860d7a6e3060c0e6a9f90d94711d5f54400000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470de4df81a998000000010000000000000000f29bce5f34a74301eb0de716d5194e4a4aea5d7a00000000680be75f00000000681e5c5f000000000000c137176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d30000000a000000010000000000000002000000090000000154be2e8d6b5d89403b015215fe5c61a42afa03d33d91cadfb7466c929681d5d5752c00aeb664f50afc529201aa3304e9ab7c6c77a83f79ca903ec101d1f1b03e01000000090000000154be2e8d6b5d89403b015215fe5c61a42afa03d33d91cadfb7466c929681d5d5752c00aeb664f50afc529201aa3304e9ab7c6c77a83f79ca903ec101d1f1b03e013d739cd2" + +createSubnet="0x00000000001000003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f26fc0d7da000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000001000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f26fc100000000000100000000000000000000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001c10487da88ee59569fefcb95b2c9ed8a66b033fad707a6619cb4ddad21ddeb7e018bf56e2b983a94ede093f22666493d256cd6f9a2aab7ff79233f492a54d86a00a5d9d7d3" + +createChain="0x00000000000f00003039000000000000000000000000000000000000000000000000000000000000000000000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000700470de4df80250c000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000011cdb4f55926af9a39bf7b459ea86208d0c9820adb63c7918cccde47e3d739cd200000000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500470de4df815330000000010000000000000000176b038753246d52ecadcc1f77a495e33dbbb8c7d9e1ce70c4285786a5d9d7d3000973696d706c6578766d7375626e657465766d000000000000000000000000000000000000000000000000000000000073a77b0a2020202022636f6e666967223a207b0a2020202020202020226265726c696e426c6f636b223a20302c0a20202020202020202262797a616e7469756d426c6f636b223a20302c0a202020202020202022636861696e4964223a20353631312c0a202020202020202022636f6e7374616e74696e6f706c65426c6f636b223a20302c0a202020202020202022636f6e74726163744e61746976654d696e746572436f6e666967223a207b0a20202020202020202020202022656e61626c6564416464726573736573223a205b0a2020202020202020202020202020202022307830666565646330646530303030303030303030303030303030303030303030303030303030303030220a2020202020202020202020205d2c0a20202020202020202020202022626c6f636b54696d657374616d70223a20313734353631343033370a20202020202020207d2c0a202020202020202022656970313530426c6f636b223a20302c0a202020202020202022656970313535426c6f636b223a20302c0a202020202020202022656970313538426c6f636b223a20302c0a202020202020202022666565436f6e666967223a207b0a202020202020202020202020226761734c696d6974223a2031323030303030302c0a20202020202020202020202022746172676574426c6f636b52617465223a20322c0a202020202020202020202020226d696e42617365466565223a2032353030303030303030302c0a20202020202020202020202022746172676574476173223a2036303030303030302c0a20202020202020202020202022626173654665654368616e676544656e6f6d696e61746f72223a2033362c0a202020202020202020202020226d696e426c6f636b476173436f7374223a20302c0a202020202020202020202020226d6178426c6f636b476173436f7374223a20313030303030302c0a20202020202020202020202022626c6f636b476173436f737453746570223a203230303030300a20202020202020207d2c0a202020202020202022686f6d657374656164426c6f636b223a20302c0a202020202020202022697374616e62756c426c6f636b223a20302c0a2020202020202020226c6f6e646f6e426c6f636b223a20302c0a2020202020202020226d756972476c6163696572426c6f636b223a20302c0a20202020202020202270657465727362757267426c6f636b223a20302c0a2020202020202020227265776172644d616e61676572436f6e666967223a207b0a20202020202020202020202022626c6f636b54696d657374616d70223a20313734353631343033370a20202020202020207d2c0a20202020202020202277617270436f6e666967223a207b0a20202020202020202020202022626c6f636b54696d657374616d70223a20313734353631343033372c0a2020202020202020202020202271756f72756d4e756d657261746f72223a2036372c0a20202020202020202020202022726571756972655072696d6172794e6574776f726b5369676e657273223a20747275650a20202020202020207d0a202020207d2c0a20202020226e6f6e6365223a2022307830222c0a202020202274696d657374616d70223a202230783638306266346435222c0a2020202022657874726144617461223a20223078222c0a20202020226761734c696d6974223a20223078623731623030222c0a2020202022646966666963756c7479223a2022307830222c0a20202020226d697848617368223a2022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202022636f696e62617365223a2022307830303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a2020202022616c6c6f63223a207b0a20202020202020202230646561646330646530303030303030303030303030303030303030303030303030303030303030223a207b0a20202020202020202020202022636f6465223a202230783630383036303430353233343830313536313030306635373566383066643562353036303034333631303631303035353537356633353630653031633830363334663232343239663134363130303539353738303633356463633933393131343631303037663537383036336139373738613761313436313030386135373830363361666261383738613134363130306136353738303633626236356232343231343631303063303537356235663830666435623631303036633631303036373336363030343631303164623536356236313031303035363562363034303531393038313532363032303031356236303430353138303931303339306633356236313030366336333031653133333830383135363562363130303933363132373130383135363562363034303531363166666666393039313136383135323630323030313631303037363536356236313030616536303530383135363562363034303531363066663930393131363831353236303230303136313030373635363562363130306537376630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030383135363562363034303531363766666666666666666666666666666666393039313136383135323630323030313631303037363536356235663630353036313031306438363835363130323439353635623631303131373931393036313032373135363562363766666666666666666666666666666666313636313031326338333630363436313032373135363562363766666666666666666666666666666666313631303135363130313433353735303566363130316236353635623631323731303633303165313333383036313031353538363836363130323439353635623637666666666666666666666666666666663136376630303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030363766666666666666666666666666666666313638393631303139353931393036313032396435363562363130313966393139303631303239643536356236313031613939313930363130326261353635623631303162333931393036313032626135363562393035303562393539343530353035303530353035363562383033353637666666666666666666666666666666663831313638313134363130316436353735663830666435623931393035303536356235663830356638303566363061303836383830333132313536313031656635373566383066643562383533353934353036313031666636303230383730313631303162663536356239333530363130323064363034303837303136313031626635363562393235303631303231623630363038373031363130316266353635623931353036313032323936303830383730313631303162663536356239303530393239353530393239353930393335303536356236333465343837623731363065303162356635323630313136303034353236303234356666643562363766666666666666666666666666666666383238313136383238323136303339303830383231313135363130323661353736313032366136313032333535363562353039323931353035303536356236376666666666666666666666666666666638313831313638333832313630323830383231363931393038323831313436313032393535373631303239353631303233353536356235303530393239313530353035363562383038323032383131353832383230343834313431373631303262343537363130326234363130323335353635623932393135303530353635623566383236313032643435373633346534383762373136306530316235663532363031323630303435323630323435666664356235303034393035366665613136343733366636633633343330303038313930303061222c0a2020202020202020202020202273746f72616765223a207b0a2020202020202020202020202020202022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030223a2022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303634220a2020202020202020202020207d2c0a2020202020202020202020202262616c616e6365223a2022307830222c0a202020202020202020202020226e6f6e6365223a2022307831220a20202020202020207d2c0a20202020202020202230666565646330646530303030303030303030303030303030303030303030303030303030303030223a207b0a20202020202020202020202022636f6465223a202230783630383036303430353233363631303031333537363130303131363130303137353635623030356236313030313135623631303031663631303136393536356236303031363030313630613031623033313633333033363130313566353736303630363030313630303136306530316230333139363030303335313636333634643331383064363065313162383130313631303035613537363130303533363130313963353635623931353036313031353735363562363335383730383662643630653131623630303136303031363065303162303331393832313630313631303037613537363130303533363130316633353635623633303730643763363936306534316236303031363030313630653031623033313938323136303136313030396135373631303035333631303233393536356236323165623936663630653631623630303136303031363065303162303331393832313630313631303062393537363130303533363130323661353635623633613339663235653536306530316236303031363030313630653031623033313938323136303136313030643935373631303035333631303261613536356236303430353136323436316263643630653531623831353236303230363030343832303135323630343236303234383230313532376635343732363136653733373036313732363536653734353537303637373236313634363536313632366336353530373236663738373933613230363136343664363034343832303135323766363936653230363336313665366536663734323036363631366336633632363136333662323037343666323037303732366637383739323037343631373236373630363438323031353236313139356436306632316236303834383230313532363061343031356236303430353138303931303339306664356238313531363032303833303166333562363130313637363130326265353635623536356236303030376662353331323736383461353638623331373361653133623966386136303136653234336536336236653865653131373864366137313738353062356436313033356235343630303136303031363061303162303331363931393035303536356236303630363130316136363130326365353635623630303036313031623533363630303438313834363130363833353635623831303139303631303163323931393036313036633935363562393035303631303164663831363034303531383036303230303136303430353238303630303038313532353036303030363130326439353635623530353036303430383035313630323038313031393039313532363030303831353239303536356236303630363030303830363130323035333636303034383138343631303638333536356238313031393036313032313239313930363130366661353635623931353039313530363130323232383238323630303136313032643935363562363034303531383036303230303136303430353238303630303038313532353039323530353035303930353635623630363036313032343336313032636535363562363030303631303235323336363030343831383436313036383335363562383130313930363130323566393139303631303663393536356239303530363130316466383136313033303535363562363036303631303237343631303263653536356236303030363130323765363130313639353635623630343038303531363030313630303136306130316230333833313636303230383230313532393139323530303136303430353136303230383138333033303338313532393036303430353239313530353039303536356236303630363130326234363130326365353635623630303036313032376536313033356335363562363130313637363130326339363130333563353635623631303336623536356233343135363130313637353736303030383066643562363130326532383336313033386635363562363030303832353131313830363130326566353735303830356231353631303330303537363130326665383338333631303363663536356235303562353035303530353635623766376536343464373934323266313763303165343839346235663466353838643333316562666132383635336434326165383332646335396533386339373938663631303332653631303136393536356236303430383035313630303136303031363061303162303339323833313638313532393138343136363032303833303135323031363034303531383039313033393061313631303335393831363130336662353635623530353635623630303036313033363636313034613435363562393035303930353635623336363030303830333736303030383033363630303038343561663433643630303038303365383038303135363130333861353733643630303066333562336436303030666435623631303339383831363130346363353635623630343035313630303136303031363061303162303338323136393037666263376364373561323065653237666439616465626162333230343166373535323134646263366266666139306363303232356233396461326535633264336239303630303039306132353035363562363036303631303366343833383336303430353138303630363030313630343035323830363032373831353236303230303136313038333036303237393133393631303536303536356239333932353035303530353635623630303136303031363061303162303338313136363130343630353736303430353136323436316263643630653531623831353236303230363030343832303135323630323636303234383230313532376634353532343333313339333633373361323036653635373732303631363436643639366532303639373332303734363836353230376136353732366632303631363034343832303135323635363436343732363537333733363064303162363036343832303135323630383430313631303134653536356238303766623533313237363834613536386233313733616531336239663861363031366532343365363362366538656531313738643661373137383530623564363130333562383035343630303136303031363061303162303331393136363030313630303136306130316230333932393039323136393139303931313739303535353035363562363030303766333630383934613133626131613332313036363763383238343932646239386463613365323037366363333733356139323061336361353035643338326262633631303138643536356236303031363030313630613031623033383131363362363130353339353736303430353136323436316263643630653531623831353236303230363030343832303135323630326436303234383230313532376634353532343333313339333633373361323036653635373732303639366437303663363536643635366537343631373436393666366532303639373332303665363034343832303135323663316264643038313834383138646264623964316339383538646436303961316236303634383230313532363038343031363130313465353635623830376633363038393461313362613161333231303636376338323834393264623938646361336532303736636333373335613932306133636135303564333832626263363130343833353635623630363036303030383038353630303136303031363061303162303331363835363034303531363130353764393139303631303765303536356236303030363034303531383038333033383138353561663439313530353033643830363030303831313436313035623835373630343035313931353036303166313936303366336430313136383230313630343035323364383235323364363030303630323038343031336536313035626435363562363036303931353035623530393135303931353036313035636538363833383338373631303564383536356239363935353035303530353035303530353635623630363038333135363130363437353738323531363030303033363130363430353736303031363030313630613031623033383531363362363130363430353736303430353136323436316263643630653531623831353236303230363030343832303135323630316436303234383230313532376634313634363437323635373337333361323036333631366336633230373436663230366536663665326436333666366537343732363136333734303030303030363034343832303135323630363430313631303134653536356235303831363130363531353635623631303635313833383336313036353935363562393439333530353035303530353635623831353131353631303636393537383135313830383336303230303166643562383036303430353136323436316263643630653531623831353236303034303136313031346539313930363130376663353635623630303038303835383531313135363130363933353736303030383066643562383338363131313536313036613035373630303038306664356235303530383230313933393139303932303339313530353635623830333536303031363030313630613031623033383131363831313436313036633435373630303038306664356239313930353035363562363030303630323038323834303331323135363130366462353736303030383066643562363130336634383236313036616435363562363334653438376237313630653031623630303035323630343136303034353236303234363030306664356236303030383036303430383338353033313231353631303730643537363030303830666435623631303731363833363130366164353635623931353036303230383330313335363766666666666666666666666666666666383038323131313536313037333335373630303038306664356238313835303139313530383536303166383330313132363130373437353736303030383066643562383133353831383131313135363130373539353736313037353936313036653435363562363034303531363031663832303136303166313939303831313636303366303131363831303139303833383231313831383331303137313536313037383135373631303738313631303665343536356238313630343035323832383135323838363032303834383730313031313131353631303739613537363030303830666435623832363032303836303136303230383330313337363030303630323038343833303130313532383039353530353035303530353035303932353039323930353035363562363030303562383338313130313536313037643735373831383130313531383338323031353236303230303136313037626635363562353035303630303039313031353235363562363030303832353136313037663238313834363032303837303136313037626335363562393139303931303139323931353035303536356236303230383135323630303038323531383036303230383430313532363130383162383136303430383530313630323038373031363130376263353635623630316630313630316631393136393139303931303136303430303139323931353035303536666534313634363437323635373337333361323036633666373732643663363537363635366332303634363536633635363736313734363532303633363136633663323036363631363936633635363461323634363937303636373335383232313232306232323938346562316633333438663562323134383836326236663830333932653439376533633635643064326366626235653533643733376535613663366136343733366636633633343330303038313930303333222c0a2020202020202020202020202273746f72616765223a207b0a2020202020202020202020202020202022307833363038393461313362613161333231303636376338323834393264623938646361336532303736636333373335613932306133636135303564333832626263223a2022307830303030303030303030303030303030303030303030303030633064656261356530303030303030303030303030303030303030303030303030303030303030222c0a2020202020202020202020202020202022307862353331323736383461353638623331373361653133623966386136303136653234336536336236653865653131373864366137313738353062356436313033223a2022307830303030303030303030303030303030303030303030303063306666656531323334353637383930616263646566313233343536373839306162636465663334220a2020202020202020202020207d2c0a2020202020202020202020202262616c616e6365223a2022307830222c0a202020202020202020202020226e6f6e6365223a2022307831220a20202020202020207d2c0a20202020202020202231333738663639343731646331336262363562396661323561393661396432366135333064326565223a207b0a2020202020202020202020202262616c616e6365223a20223078323038366163333531303532363030303030220a20202020202020207d2c0a20202020202020202238646239376337636563653234396332623938626463303232366363346332613537626635326663223a207b0a2020202020202020202020202262616c616e6365223a202230786433633231626365636365646131303030303030220a20202020202020207d2c0a20202020202020202239633030363239636537313262303235356231376134613635373137316163643135373230623863223a207b0a20202020202020202020202022636f6465223a202230783733303030303030303030303030303030303030303030303030303030303030303030303030303030303330313436303830363034303532363030343336313036313030623135373566333536306530316338303633383534613839336631313631303037393537383036333835346138393366313436313031623235373830363338373431386238653134363130323066353738303633396238333534363531343631303232323537383036336136393963313335313436313032343235373830363365316436386633303134363130323535353738303633656239376365353131343631303236383537356638306664356238303633303231646538386631343631303062353537383036333038386332343633313436313030653235373830363334643834373838343134363130313132353738303633353037383262306631343631303133333537383036333766376334323761313436313031366235373562356638306664356236313030633836313030633333363630303436313138613935363562363130323839353635623630343038303531393238333532393031353135363032303833303135323031356236303430353138303931303339306633356236313030663536313030663033363630303436313138613935363562363130343461353635623630343038303531393238333532363030313630303136303430316230333930393131363630323038333031353230313631303064393536356236313031323536313031323033363630303436313138613935363562363130363362353635623630343035313930383135323630323030313631303064393536356236313031343636313031343133363630303436313138613935363562363130376338353635623630343038303531393338343532363030313630303136303430316230333932383331363630323038353031353239313136393038323031353236303630303136313030643935363562363130316135363130313739333636303034363131386532353635623630343038303531356636303230383230313831393035323630323238323031353236303236383038323031393339303933353238313531383038323033393039333031383335323630343630313930353239303536356236303430353136313030643939313930363131393436353635623631303161353631303163303336363030343631313937613536356236303430383035313566363032303832303135323630303336306530316236303232383230313532363032363831303139343930393435323630303136303031363063303162303331393630633039333834316238313136363034363836303135323931393039323162313636303465383330313532383035313830383330333630333630313831353236303536393039323031393035323930353635623631303161353631303231643336363030343631313965623536356236313061316535363562363130323335363130323330333636303034363131386139353635623631306236303536356236303430353136313030643939313930363131626234353635623631303161353631303235303336363030343631316336623536356236313134616235363562363130316135363130323633333636303034363131633964353635623631313465663536356236313032376236313032373633363630303436313164383035363562363131353235353635623630343035313631303064393932393139303631316537633536356235663830383235313630323731343631303263343537383235313630343035313633636339326461613136306530316238313532363366666666666666663930393131363630303438323031353236303237363032343832303135323630343430313562363034303531383039313033393066643562356638303562363030323831313031353631303331333537363130326462383136303031363131656138353635623631303265363930363030383631316562623536356236316666666631363835383238313531383131303631303266633537363130326663363131656432353635623031363032303031353136306638316339303162393139303931313739303630303130313631303263373536356235303631666666663831313631353631303333643537363034303531363334303762353837333630653031623831353236316666666638323136363030343832303135323630323430313631303262623536356235663830356236303034383131303135363130333938353736313033353438313630303336313165613835363562363130333566393036303038363131656262353635623633666666666666666631363836363130333731383336303032363131656536353635623831353138313130363130333831353736313033383136313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130333430353635623530363366666666666666663831313636303032313436313033633035373630343035313633356236303839326636306530316238313532363030343031363034303531383039313033393066643562356638303562363032303831313031353631303431353537363130336437383136303166363131656138353635623631303365323930363030383631316562623536356238373631303365653833363030363631316565363536356238313531383131303631303366653537363130336665363131656432353635623031363032303031353136306638316339303162393139303931313739303630303130313631303363333536356235303566383636303236383135313831313036313034326135373631303432613631316564323536356230313630323030313531393139373630303136303031363066383162303331393930393231363135313539363530393039343530353035303530353035363562356638303832353136303265313436313034383035373832353136303430353136336363393264616131363065303162383135323633666666666666666639303931313636303034383230313532363032653630323438323031353236303434303136313032626235363562356638303562363030323831313031353631303463663537363130343937383136303031363131656138353635623631303461323930363030383631316562623536356236316666666631363835383238313531383131303631303462383537363130346238363131656432353635623031363032303031353136306638316339303162393139303931313739303630303130313631303438333536356235303631666666663831313631353631303466393537363034303531363334303762353837333630653031623831353236316666666638323136363030343832303135323630323430313631303262623536356235663830356236303034383131303135363130353534353736313035313038313630303336313165613835363562363130353162393036303038363131656262353635623633666666666666666631363836363130353264383336303032363131656536353635623831353138313130363130353364353736313035336436313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130346663353635623530363366666666666666663831313631353631303537613537363034303531363335623630383932663630653031623831353236303034303136303430353138303931303339306664356235663830356236303230383131303135363130356366353736313035393138313630316636313165613835363562363130353963393036303038363131656262353635623837363130356138383336303036363131656536353635623831353138313130363130356238353736313035623836313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130353764353635623530356638303562363030383831313031353631303632653537363130356537383136303037363131656138353635623631303566323930363030383631316562623536356236303031363030313630343031623033313638383631303630373833363032363631316565363536356238313531383131303631303631373537363130363137363131656432353635623031363032303031353136306638316339303162393139303931313739303630303130313631303564333536356235303930393639303935353039333530353035303530353635623566383135313630323631343631303637303537383135313630343035313633636339326461613136306530316238313532363366666666666666663930393131363630303438323031353236303236363032343832303135323630343430313631303262623536356235663830356236303032383131303135363130366266353736313036383738313630303136313165613835363562363130363932393036303038363131656262353635623631666666663136383438323831353138313130363130366138353736313036613836313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130363733353635623530363166666666383131363135363130366539353736303430353136333430376235383733363065303162383135323631666666663832313636303034383230313532363032343031363130326262353635623566383035623630303438313130313536313037343435373631303730303831363030333631316561383536356236313037306239303630303836313165626235363562363366666666666666663136383536313037316438333630303236313165653635363562383135313831313036313037326435373631303732643631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313036656335363562353036336666666666666666383131363135363130373661353736303430353136333562363038393266363065303162383135323630303430313630343035313830393130333930666435623566383035623630323038313130313536313037626635373631303738313831363031663631316561383536356236313037386339303630303836313165626235363562383636313037393838333630303636313165653635363562383135313831313036313037613835373631303761383631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313037366435363562353039343933353035303530353035363562356638303566383335313630333631343631303766663537383335313630343035313633636339326461613136306530316238313532363366666666666666663930393131363630303438323031353236303336363032343832303135323630343430313631303262623536356235663830356236303032383131303135363130383465353736313038313638313630303136313165613835363562363130383231393036303038363131656262353635623631666666663136383638323831353138313130363130383337353736313038333736313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130383032353635623530363166666666383131363135363130383738353736303430353136333430376235383733363065303162383135323631666666663832313636303034383230313532363032343031363130326262353635623566383035623630303438313130313536313038643335373631303838663831363030333631316561383536356236313038396139303630303836313165626235363562363366666666666666663136383736313038616338333630303236313165653635363562383135313831313036313038626335373631303862633631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313038376235363562353036336666666666666666383131363630303331343631303866623537363034303531363335623630383932663630653031623831353236303034303136303430353138303931303339306664356235663830356236303230383131303135363130393530353736313039313238313630316636313165613835363562363130393164393036303038363131656262353635623838363130393239383336303036363131656536353635623831353138313130363130393339353736313039333936313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130386665353635623530356638303562363030383831313031353631303961663537363130393638383136303037363131656138353635623631303937333930363030383631316562623536356236303031363030313630343031623033313638393631303938383833363032363631316565363536356238313531383131303631303939383537363130393938363131656432353635623031363032303031353136306638316339303162393139303931313739303630303130313631303935343536356235303566383035623630303838313130313536313061306535373631303963373831363030373631316561383536356236313039643239303630303836313165626235363562363030313630303136303430316230333136386136313039653738333630326536313165653635363562383135313831313036313039663735373631303966373631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313039623335363562353039313938393039373530393039353530393335303530353035303536356238303531363032303830383330313531363034303830383530313531363036303836383130313531353139323531356639353831303138363930353236303232383130313936393039363532363034323836303139333930393335323630303536306532316236303632383630313532366266666666666666666666666666666666666666666666666631393930383331623136363036363835303135323630653031623630303136303031363065303162303331393136363037613834303135323931363037653031363034303531363032303831383330333033383135323930363034303532393035303566356238333630363030313531353138313130313536313062353935373831383436303630303135313832383135313831313036313061626135373631306162613631316564323536356236303230303236303230303130313531356630313531353138353630363030313531383338313531383131303631306164633537363130616463363131656432353635623630323030323630323030313031353135663031353138363630363030313531383438313531383131303631306166643537363130616664363131656432353635623630323030323630323030313031353136303230303135313837363036303031353138353831353138313130363130623166353736313062316636313165643235363562363032303032363032303031303135313630343030313531363034303531363032303031363130623366393539343933393239313930363131656639353635623630343038303531363031663139383138343033303138313532393139303532393135303630303130313631306139363536356235303932393135303530353635623631306236383631313731323536356235663631306237313631313731323536356235663830356236303032383131303135363130626366353736313062383838313630303136313165613835363562363130623933393036303038363131656262353635623631666666663136383636313062613836336666666666666666383731363834363131656536353635623831353138313130363130626238353736313062623836313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130623734353635623530363166666666383131363135363130626639353736303430353136333430376235383733363065303162383135323631666666663832313636303034383230313532363032343031363130326262353635623631306330343630303238343631316637323536356239323530353035663830356236303034383131303135363130633639353736313063316538313630303336313165613835363562363130633239393036303038363131656262353635623633666666666666666631363836383536336666666666666666313638333631306334323931393036313165653635363562383135313831313036313063353235373631306335323631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313063306135363562353036336666666666666666383131363630303131343631306339313537363034303531363335623630383932663630653031623831353236303034303136303430353138303931303339306664356236313063396336303034383436313166373235363562393235303530356638303562363032303831313031353631306366393537363130636236383136303166363131656138353635623631306363313930363030383631316562623536356238363631306364323633666666666666666638373136383436313165653635363562383135313831313036313063653235373631306365323631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313063613235363562353038303832353236313064303836303230383436313166373235363562393235303530356638303562363030343831313031353631306436643537363130643232383136303033363131656138353635623631306432643930363030383631316562623536356236336666666666666666313638363835363366666666666666663136383336313064343639313930363131656536353635623831353138313130363130643536353736313064353636313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130643065353635623530363130643739363030343834363131663732353635623932353035663831363366666666666666663136363030313630303136303430316230333831313131353631306439613537363130643961363131373663353635623630343035313930383038323532383036303166303136303166313931363630323030313832303136303430353238303135363130646334353736303230383230313831383033363833333730313930353035623530393035303566356238323633666666666666666631363831313031353631306533333537383636313064653836336666666666666666383731363833363131656536353635623831353138313130363130646638353736313064663836313165643235363562363032303031303135313630663831633630663831623832383238313531383131303631306531353537363130653135363131656432353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530363030313031363130646339353635623530363032303833303138313930353236313065343538323835363131663732353635623630343038303531363033303830383235323630363038323031393039323532393139353530356639323530363032303832303138313830333638333337303139303530353039303530356635623630333038313130313536313065643135373836363130653836363366666666666666663837313638333631316565363536356238313531383131303631306539363537363130653936363131656432353635623630323030313031353136306638316336306638316238323832383135313831313036313065623335373631306562333631316564323536356236303230303130313930363030313630303136306638316230333139313639303831356631613930353335303630303130313631306536633536356235303630343038333031383139303532363130656534363033303835363131663732353635623933353035303566383035623630303838313130313536313066346135373631306566653831363030373631316561383536356236313066303939303630303836313165626235363562363030313630303136303430316230333136383736313066323336336666666666666666383831363834363131656536353635623831353138313130363130663333353736313066333336313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130656561353635623530363030313630303136303430316230333831313636303630383430313532363130663635363030383835363131663732353635623933353035303566383035663562363030343831313031353631306663623537363130663830383136303033363131656138353635623631306638623930363030383631316562623536356236336666666666666666313638383837363366666666666666663136383336313066613439313930363131656536353635623831353138313130363130666234353736313066623436313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363130663663353635623530363130666437363030343836363131663732353635623934353035663562363030343831313031353631313033613537363130666566383136303033363131656138353635623631306666613930363030383631316562623536356236336666666666666666313638383837363366666666666666663136383336313130313339313930363131656536353635623831353138313130363131303233353736313130323336313165643235363562303136303230303135313630663831633930316239323930393231373931363030313031363130666462353635623530363131303436363030343836363131663732353635623934353035663832363366666666666666663136363030313630303136303430316230333831313131353631313036373537363131303637363131373663353635623630343035313930383038323532383036303230303236303230303138323031363034303532383031353631313039303537383136303230303136303230383230323830333638333337303139303530356235303930353035663562383336336666666666666666313638313130313536313131373835373630343038303531363031343830383235323831383330313930393235323566393136303230383230313831383033363833333730313930353035303930353035663562363031343831313031353631313132613537386136313130646636336666666666666666386231363833363131656536353635623831353138313130363131306566353736313130656636313165643235363562363032303031303135313630663831633630663831623832383238313531383131303631313130633537363131313063363131656432353635623630323030313031393036303031363030313630663831623033313931363930383135663161393035333530363030313031363131306335353635623530356636303134383230313531393035303830383438343831353138313130363131313436353736313131343636313165643235363562363030313630303136306130316230333930393231363630323039323833303239313930393130313930393130313532363131313639363031343861363131663732353635623938353035303530383036303031303139303530363131303935353635623530363034303830353138303832303139303931353236336666666666666666393039323136383235323630323038323031353236303830383430313532356638303830356236303034383131303135363131316661353736313131616638313630303336313165613835363562363131316261393036303038363131656262353635623633666666666666666631363839383836336666666666666666313638333631313164333931393036313165653635363562383135313831313036313131653335373631313165333631316564323536356230313630323030313531363066383163393031623931393039313137393036303031303136313131396235363562353036313132303636303034383736313166373235363562393535303566356236303034383131303135363131323639353736313132316538313630303336313165613835363562363131323239393036303038363131656262353635623633666666666666666631363839383836336666666666666666313638333631313234323931393036313165653635363562383135313831313036313132353235373631313235323631316564323536356230313630323030313531363066383163393031623932393039323137393136303031303136313132306135363562353036313132373536303034383736313166373235363562393535303566383236336666666666666666313636303031363030313630343031623033383131313135363131323936353736313132393636313137366335363562363034303531393038303832353238303630323030323630323030313832303136303430353238303135363131326266353738313630323030313630323038323032383033363833333730313930353035623530393035303566356238333633666666666666666631363831313031353631313361373537363034303830353136303134383038323532383138333031393039323532356639313630323038323031383138303336383333373031393035303530393035303566356236303134383131303135363131333539353738623631313330653633666666666666666638633136383336313165653635363562383135313831313036313133316535373631313331653631316564323536356236303230303130313531363066383163363066383162383238323831353138313130363131333362353736313133336236313165643235363562363032303031303139303630303136303031363066383162303331393136393038313566316139303533353036303031303136313132663435363562353035663630313438323031353139303530383038343834383135313831313036313133373535373631313337353631316564323536356236303031363030313630613031623033393039323136363032303932383330323931393039313031393039313031353236313133393836303134386236313166373235363562393935303530353038303630303130313930353036313132633435363562353036303430383035313830383230313930393135323633666666666666666639303932313638323532363032303832303135323630613038353031353235663631313364313832383436313166373235363562363131336463393036303134363131663866353635623631313365373835363037613631316637323536356236313133663139313930363131663732353635623930353038303633666666666666666631363838353131343631313432643537383735313630343035313633636339326461613136306530316238313532363366666666666666663931383231363630303438323031353239303832313636303234383230313532363034343031363130326262353635623566383035623630303838313130313536313134393035373631313434343831363030373631316561383536356236313134346639303630303836313165626235363562363030313630303136303430316230333136386136313134363936336666666666666666386231363834363131656536353635623831353138313130363131343739353736313134373936313165643235363562303136303230303135313630663831633930316239313930393131373930363030313031363131343330353635623530363030313630303136303430316230333136363063303836303135323530393239363935353035303530353035303530353635623630343035313566363032303832303135323630303136306531316236303232383230313532363032363831303138333930353238313135313536306638316236303436383230313532363036303930363034373031356236303430353136303230383138333033303338313532393036303430353239303530356239323931353035303536356236303430353135663630323038323031383139303532363032323832303135323630323638313031383339303532363030313630303136306330316230333139363063303833393031623136363034363832303135323630363039303630346530313631313464373536356235663630363038323630343030313531353136303330313436313135346535373630343035313633313830666661306436306530316238313532363030343031363034303531383039313033393066643562383235313630323038303835303135313830353136303430383038383031353136303630383930313531363038303861303135313830353139303837303135313531393335313566393836313135386639383861393836303031393839323937393239363930393539303934393039333930393239313031363131666237353635623630343035313630323038313833303330333831353239303630343035323930353035663562383436303830303135313630323030313531353138313130313536313136303135373831383536303830303135313630323030313531383238313531383131303631313563653537363131356365363131656432353635623630323030323630323030313031353136303430353136303230303136313135653739323931393036313230373135363562363034303830353136303166313938313834303330313831353239313930353239313530363030313031363131356132353635623530363061303834303135313830353136303230393138323031353135313630343035313631313632313933383539333932393130313631323061373536356236303430353136303230383138333033303338313532393036303430353239303530356635623834363061303031353136303230303135313531383131303135363131363933353738313835363061303031353136303230303135313832383135313831313036313136363035373631313636303631316564323536356236303230303236303230303130313531363034303531363032303031363131363739393239313930363132303731353635623630343038303531363031663139383138343033303138313532393139303532393135303630303130313631313633343536356235303630633038343031353136303430353136313136616139313833393136303230303136313230653235363562363034303531363032303831383330333033383135323930363034303532393035303630303238313630343035313631313663623931393036313231313335363562363032303630343035313830383330333831383535616661313538303135363131366536353733643566383033653364356666643562353035303530363034303531336436303166313936303166383230313136383230313830363034303532353038313031393036313137303939313930363132313265353635623934393039333530393135303530353635623630343038303531363065303831303138323532356638303832353236303630363032303830383430313832393035323833383530313832393035323831383430313833393035323834353138303836303138363532383338313532383038323031383339303532363038303835303135323834353138303836303139303935353239313834353239303833303135323930363061303832303139303831353235663630323039303931303135323930353635623633346534383762373136306530316235663532363034313630303435323630323435666664356236303430353136303830383130313630303136303031363034303162303338313131383238323130313731353631313761323537363131376132363131373663353635623630343035323930353635623630343035313630363038313031363030313630303136303430316230333831313138323832313031373135363131376132353736313137613236313137366335363562363034303830353139303831303136303031363030313630343031623033383131313832383231303137313536313137613235373631313761323631313736633536356236303430353136306530383130313630303136303031363034303162303338313131383238323130313731353631313761323537363131376132363131373663353635623630343035313630316638323031363031663139313638313031363030313630303136303430316230333831313138323832313031373135363131383336353736313138333636313137366335363562363034303532393139303530353635623566383236303166383330313132363131383464353735663830666435623831333536303031363030313630343031623033383131313135363131383636353736313138363636313137366335363562363131383739363031663832303136303166313931363630323030313631313830653536356238313831353238343630323038333836303130313131313536313138386435373566383066643562383136303230383530313630323038333031333735663931383130313630323030313931393039313532393339323530353035303536356235663630323038323834303331323135363131386239353735663830666435623831333536303031363030313630343031623033383131313135363131386365353735663830666435623631313864613834383238353031363131383365353635623934393335303530353035303536356235663630323038323834303331323135363131386632353735663830666435623530333539313930353035363562356635623833383131303135363131393133353738313831303135313833383230313532363032303031363131386662353635623530353035663931303135323536356235663831353138303834353236313139333238313630323038363031363032303836303136313138663935363562363031663031363031663139313639323930393230313630323030313932393135303530353635623630323038313532356636313139353836303230383330313834363131393162353635623933393235303530353035363562383033353630303136303031363034303162303338313136383131343631313937353537356638306664356239313930353035363562356638303566363036303834383630333132313536313139386335373566383066643562383333353932353036313139396336303230383530313631313935663536356239313530363131396161363034303835303136313139356635363562393035303932353039323530393235363562383033353630303136303031363061303162303338313136383131343631313937353537356638306664356235663630303136303031363034303162303338323131313536313139653135373631313965313631313736633536356235303630303531623630323030313930353635623566363032303830383338353033313231353631313966633537356638306664356238323335363030313630303136303430316230333830383231313135363131613132353735663830666435623930383430313930363038303832383730333132313536313161323535373566383066643562363131613264363131373830353635623832333538313532383338333031333538343832303135323631316134353630343038343031363131396233353635623630343038323031353236303630383038343031333538333831313131353631316135633537356638306664356238303835303139343530353038373630316638353031313236313161373035373566383066643562383333353631316138333631316137653832363131396339353635623631313830653536356238313831353236303035393139303931316238353031383630313930383638313031393038613833313131353631316161313537356638306664356238373837303135623833383131303135363131623361353738303335383738313131313536313161626235373566383066643562383830313830386430333630316631393031383631333135363131616366353735663830666435623631316164373631313761383536356238613832303133353839383131313135363131616537353735663830666435623631316166353866386438333836303130313631313833653536356238323532353036303430383230313335383938313131313536313162303935373566383066643562363131623137386638643833383630313031363131383365353635623863383330313532353036313162323738373833303136313139356635363562363034303832303135323834353235303931383830313931383830313631316161353536356235303630363038353031353235303931393839373530353035303530353035303530353035363562356636303430383330313633666666666666666638333531313638343532363032303830383430313531363034303630323038373031353238323831353138303835353236303630383830313931353036303230383330313934353035663932353035623830383331303135363131626139353738343531363030313630303136306130316230333136383235323933383330313933363030313932393039323031393139303833303139303631316238303536356235303936393535303530353035303530353035363562363032303831353238313531363032303832303135323566363032303833303135313630653036303430383430313532363131626461363130313030383430313832363131393162353635623930353036303430383430313531363031663139383038353834303330313630363038363031353236313162663838333833363131393162353635623932353036303031363030313630343031623033363036303837303135313136363038303836303135323630383038363031353139313530383038353834303330313630613038363031353236313163323838333833363131623465353635623932353036306130383630313531393135303830383538343033303136306330383630313532353036313163343638323832363131623465353635623931353035303630633038343031353136313163363336306530383530313832363030313630303136303430316230333136393035323536356235303933393235303530353035363562356638303630343038333835303331323135363131633763353735663830666435623832333539313530363032303833303133353830313531353831313436313163393235373566383066643562383039313530353039323530393239303530353635623566383036303430383338353033313231353631316361653537356638306664356238323335393135303631316362653630323038343031363131393566353635623930353039323530393239303530353635623566363034303832383430333132313536313163643735373566383066643562363131636466363131376361353635623930353038313335363366666666666666663831313638313134363131636634353735663830666435623831353236303230383238313031333536303031363030313630343031623033383131313135363131643066353735663830666435623833303136303166383130313835313336313164316635373566383066643562383033353631316432643631316137653832363131396339353635623831383135323630303539313930393131623832303138333031393038333831303139303837383331313135363131643462353735663830666435623932383430313932356238323834313031353631316437303537363131643631383436313139623335363562383235323932383430313932393038343031393036313164353035363562383038353837303135323530353035303530353039323931353035303536356235663630323038323834303331323135363131643930353735663830666435623831333536303031363030313630343031623033383038323131313536313164613635373566383066643562393038333031393036306530383238363033313231353631316462393537356638306664356236313164633136313137656335363562383233353831353236303230383330313335383238313131313536313164643635373566383066643562363131646532383738323836303136313138336535363562363032303833303135323530363034303833303133353832383131313135363131646639353735663830666435623631316530353837383238363031363131383365353635623630343038333031353235303631316531373630363038343031363131393566353635623630363038323031353236303830383330313335383238313131313536313165326435373566383066643562363131653339383738323836303136313163633735363562363038303833303135323530363061303833303133353832383131313135363131653530353735663830666435623631316535633837383238363031363131636337353635623630613038333031353235303631316536653630633038343031363131393566353635623630633038323031353239353934353035303530353035303536356238323831353236303430363032303832303135323566363131386461363034303833303138343631313931623536356236333465343837623731363065303162356635323630313136303034353236303234356666643562383138313033383138313131313536313134653935373631313465393631316539343536356238303832303238313135383238323034383431343137363131346539353736313134653936313165393435363562363334653438376237313630653031623566353236303332363030343532363032343566666435623830383230313830383231313135363131346539353736313134653936313165393435363562356638363531363131663061383138343630323038623031363131386639353635623630653038373930316236303031363030313630653031623033313931363930383330313930383135323835353136313166333238313630303438343031363032303861303136313138663935363562383535313931303139303631316634383831363030343834303136303230383930313631313866393536356236306330393439303934316236303031363030313630633031623033313931363630303439313930393430313930383130313933393039333532353035303630306330313934393335303530353035303536356236336666666666666666383138313136383338323136303139303830383231313135363130623539353736313062353936313165393435363562363366666666666666663831383131363833383231363032383038323136393139303832383131343631316661663537363131666166363131653934353635623530353039323931353035303536356236316666666636306630316238613630663031623136383135323566363366666666666666663630653031623830386236306530316231363630303238343031353238393630303638343031353238303839363065303162313636303236383430313532353038363531363131666664383136303261383530313630323038623031363131386639353635623836353139303833303139303631323031343831363032613834303136303230386230313631313866393536356236306330383739303162363030313630303136306330316230333139313636303261393239303931303139313832303135323631323034363630333238323031383636306530316236303031363030313630653031623033313931363930353235363562363132303566363033363832303138353630653031623630303136303031363065303162303331393136393035323536356236303361303139623961353035303530353035303530353035303530353035303536356235663833353136313230383238313834363032303838303136313138663935363562363036303933393039333162366266666666666666666666666666666666666666666666666631393136393139303932303139303831353236303134303139323931353035303536356235663834353136313230623838313834363032303839303136313138663935363562363030313630303136306530316230333139363065303935383631623831313639313930393330313930383135323932393039333162313636303034383230313532363030383031393239313530353035363562356638333531363132306633383138343630323038383031363131386639353635623630633039333930393331623630303136303031363063303162303331393136393139303932303139303831353236303038303139323931353035303536356235663832353136313231323438313834363032303837303136313138663935363562393139303931303139323931353035303536356235663630323038323834303331323135363132313365353735663830666435623530353139313930353035366665613136343733366636633633343330303038313930303061222c0a2020202020202020202020202262616c616e6365223a2022307830222c0a202020202020202020202020226e6f6e6365223a2022307831220a20202020202020207d2c0a20202020202020202263306666656531323334353637383930616263646566313233343536373839306162636465663334223a207b0a20202020202020202020202022636f6465223a202230783630383036303430353236303034333631303631303037623537363030303335363065303163383036333936323336303964313136313030346535373830363339363233363039643134363130313131353738303633393961383865633431343631303132343537383036336632666465333862313436313031343435373830363366336237646561643134363130313634353736303030383066643562383036333230346531633761313436313030383035373830363337313530313861363134363130306263353738303633376566663237356531343631303064333537383036333864613563623562313436313030663335373562363030303830666435623334383031353631303038633537363030303830666435623530363130306130363130303962333636303034363130343939353635623631303138343536356236303430353136303031363030313630613031623033393039313136383135323630323030313630343035313830393130333930663335623334383031353631303063383537363030303830666435623530363130306431363130323135353635623030356233343830313536313030646635373630303038306664356235303631303064313631303065653336363030343631303462643536356236313032323935363562333438303135363130306666353736303030383066643562353036303030353436303031363030313630613031623033313636313030613035363562363130306431363130313166333636303034363130353063353635623631303239313536356233343830313536313031333035373630303038306664356235303631303064313631303133663336363030343631303462643536356236313033303035363562333438303135363130313530353736303030383066643562353036313030643136313031356633363630303436313034393935363562363130333336353635623334383031353631303137303537363030303830666435623530363130306130363130313766333636303034363130343939353635623631303362343536356236303030383036303030383336303031363030313630613031623033313636303430353136313031616139303633356336306461316236306530316238313532363030343031393035363562363030303630343035313830383330333831383535616661393135303530336438303630303038313134363130316535353736303430353139313530363031663139363033663364303131363832303136303430353233643832353233643630303036303230383430313365363130316561353635623630363039313530356235303931353039313530383136313031663935373630303038306664356238303830363032303031393035313831303139303631303230643931393036313035653235363562393439333530353035303530353635623631303231643631303364613536356236313032323736303030363130343334353635623536356236313032333136313033646135363562363034303531363330386632383339373630653431623831353236303031363030313630613031623033383238313136363030343833303135323833313639303633386632383339373039303630323430313562363030303630343035313830383330333831363030303837383033623135383031353631303237353537363030303830666435623530356166313135383031353631303238393537336436303030383033653364363030306664356235303530353035303530353035363562363130323939363130336461353635623630343035313633323738663739343336306531316238313532363030313630303136306130316230333834313639303633346631656632383639303334393036313032633939303836393038363930363030343031363130356666353635623630303036303430353138303833303338313835383838303362313538303135363130326532353736303030383066643562353035616631313538303135363130326636353733643630303038303365336436303030666435623530353035303530353035303530353035363562363130333038363130336461353635623630343035313633316232636537663336306531316238313532363030313630303136306130316230333832383131363630303438333031353238333136393036333336353963666536393036303234303136313032356235363562363130333365363130336461353635623630303136303031363061303162303338313136363130336138353736303430353136323436316263643630653531623831353236303230363030343832303135323630323636303234383230313532376634663737366536313632366336353361323036653635373732303666373736653635373232303639373332303734363836353230376136353732366632303631363034343832303135323635363436343732363537333733363064303162363036343832303135323630383430313562363034303531383039313033393066643562363130336231383136313034333435363562353035363562363030303830363030303833363030313630303136306130316230333136363034303531363130316161393036333033653134363931363065363162383135323630303430313930353635623630303035343630303136303031363061303162303331363333313436313032323735373630343035313632343631626364363065353162383135323630323036303034383230313831393035323630323438323031353237663466373736653631363236633635336132303633363136633663363537323230363937333230366536663734323037343638363532303666373736653635373236303434383230313532363036343031363130333966353635623630303038303534363030313630303136306130316230333833383131363630303136303031363061303162303331393833313638313137383435353630343035313931393039323136393238333931376638626530303739633533313635393134313334346364316664306134663238343139343937663937323261336461616665336234313836663662363435376530393139306133353035303536356236303031363030313630613031623033383131363831313436313033623135373630303038306664356236303030363032303832383430333132313536313034616235373630303038306664356238313335363130346236383136313034383435363562393339323530353035303536356236303030383036303430383338353033313231353631303464303537363030303830666435623832333536313034646238313631303438343536356239313530363032303833303133353631303465623831363130343834353635623830393135303530393235303932393035303536356236333465343837623731363065303162363030303532363034313630303435323630323436303030666435623630303038303630303036303630383438363033313231353631303532313537363030303830666435623833333536313035326338313631303438343536356239323530363032303834303133353631303533633831363130343834353635623931353036303430383430313335363766666666666666666666666666666666383038323131313536313035353935373630303038306664356238313836303139313530383636303166383330313132363130353664353736303030383066643562383133353831383131313135363130353766353736313035376636313034663635363562363034303531363031663832303136303166313939303831313636303366303131363831303139303833383231313831383331303137313536313035613735373631303561373631303466363536356238313630343035323832383135323839363032303834383730313031313131353631303563303537363030303830666435623832363032303836303136303230383330313337363030303630323038343833303130313532383039353530353035303530353035303932353039323530393235363562363030303630323038323834303331323135363130356634353736303030383066643562383135313631303462363831363130343834353635623630303138303630613031623033383331363831353236303030363032303630343036303230383430313532383335313830363034303835303135323630303035623831383131303135363130363363353738353831303138333031353138353832303136303630303135323832303136313036323035363562353036303030363036303832383630313031353236303630363031663139363031663833303131363835303130313932353035303530393339323530353035303536666561323634363937303636373335383232313232303139663339393833613666643135663363666661373634656664366662303233346666653864373130353162336562646463306236626439396638376661393736343733366636633633343330303038313930303333222c0a2020202020202020202020202273746f72616765223a207b0a2020202020202020202020202020202022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030223a2022307830303030303030303030303030303030303030303030303038646239376337636563653234396332623938626463303232366363346332613537626635326663220a2020202020202020202020207d2c0a2020202020202020202020202262616c616e6365223a2022307830222c0a202020202020202020202020226e6f6e6365223a2022307831220a20202020202020207d0a202020207d2c0a202020202261697264726f7048617368223a2022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a202020202261697264726f70416d6f756e74223a206e756c6c2c0a20202020226e756d626572223a2022307830222c0a202020202267617355736564223a2022307830222c0a2020202022706172656e7448617368223a2022307830303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030222c0a202020202262617365466565506572476173223a206e756c6c2c0a2020202022657863657373426c6f62476173223a206e756c6c2c0a2020202022626c6f6247617355736564223a206e756c6c0a7d0000000a000000010000000000000002000000090000000151f9b7d0d57976387d7383be36a37b83639b634f6404caa6a76c49d53edd3bfa123bf20951643a8e17a1541b3f8f0cfbf19fdaa3e91e51f02c6b2a8b5d5170bd01000000090000000151f9b7d0d57976387d7383be36a37b83639b634f6404caa6a76c49d53edd3bfa123bf20951643a8e17a1541b3f8f0cfbf19fdaa3e91e51f02c6b2a8b5d5170bd01b955cfdf" + + +addValidators=($addValidator1 $addValidator2 $addValidator3 $addValidator4 $addValidator5) + +curl -X POST --data '{ + "jsonrpc": "2.0", + "method": "platform.issueTx", + "params": { + "tx":"'${createSubnet}'", + "encoding": "hex" + }, + "id": 1 +}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P + + +sleep 1 + +for v in "${addValidators[@]}"; do + curl -X POST --data '{ + "jsonrpc": "2.0", + "method": "platform.issueTx", + "params": { + "tx":"'${v}'", + "encoding": "hex" + }, + "id": 1 + }' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P + sleep 3 +done + +sleep 3 + + +curl -X POST --data '{ + "jsonrpc": "2.0", + "method": "platform.issueTx", + "params": { + "tx":"'${createChain}'", + "encoding": "hex" + }, + "id": 1 +}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P + + +#0x479f66c8be895830547e70b4b298cafd433dba6e1ebdfb85 +#0xde31b4d8b22991d51aa6aa1fc733f23a851a8c9427f780c8 +#0xe9094f73698002fd52c90819b457b9fbc866ab80727952c7 +#0xaa18d3991cf637aa6c162f5e95cf163f69cd82913f89fa2e +#0xf29bce5f34a74301eb0de716d5194e4a4aea5d7ae0cb875e + + + diff --git a/scripts/run_simplex.sh b/scripts/run_simplex.sh new file mode 100755 index 000000000000..4cdd7bc82dc2 --- /dev/null +++ b/scripts/run_simplex.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +set -euo pipefail + +AVALANCHE_BINARY="${AVALANCHE_BINARY:-./build/avalanchego} --network-no-ingress-connections-grace-period 9000m --log-level trace --track-subnets=BKBZ6xXTnT86B4L5fp8rvtcmNSpvtNz8En9jG61ywV2uWyeHy" + +pgrep avalanchego && pkill avalanchego + +rm -rf local* +rm -rf *.wal + +mkdir -p ./local1/plugins +mkdir -p ./local2/plugins +mkdir -p ./local3/plugins +mkdir -p ./local4/plugins +mkdir -p ./local5/plugins + +ln /Users/yacov.manevich/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ./local1/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +ln /Users/yacov.manevich/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ./local2/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +ln /Users/yacov.manevich/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ./local3/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +ln /Users/yacov.manevich/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ./local4/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy +ln /Users/yacov.manevich/.avalanchego/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy ./local5/plugins/srEXiWaHuhNyGwPUi444Tu47ZEDwxTWrbQiuD7FmgSAQ6X7Dy + +sleep 3 + +${AVALANCHE_BINARY} --data-dir ./local1 --network-id=local --db-dir=./local1 --public-ip=127.0.0.1 --http-port=9650 --staking-port=9651 --staking-tls-cert-file=./staking/local/staker1.crt --staking-tls-key-file=./staking/local/staker1.key --staking-signer-key-file=./staking/local/signer1.key --bootstrap-ips="" --bootstrap-ids="" &> node1.log & +${AVALANCHE_BINARY} --data-dir ./local2 --network-id=local --db-dir=./local2 --public-ip=127.0.0.1 --http-port=9660 --staking-port=9661 --staking-tls-cert-file=./staking/local/staker2.crt --staking-tls-key-file=./staking/local/staker2.key --staking-signer-key-file=./staking/local/signer2.key --bootstrap-ips="127.0.0.1:9651" --bootstrap-ids="NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg" &> node2.log & +${AVALANCHE_BINARY} --data-dir ./local3 --network-id=local --db-dir=./local3 --public-ip=127.0.0.1 --http-port=9670 --staking-port=9671 --staking-tls-cert-file=./staking/local/staker3.crt --staking-tls-key-file=./staking/local/staker3.key --staking-signer-key-file=./staking/local/signer3.key --bootstrap-ips="127.0.0.1:9651" --bootstrap-ids="NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg" &> node3.log & +${AVALANCHE_BINARY} --data-dir ./local4 --network-id=local --db-dir=./local4 --public-ip=127.0.0.1 --http-port=9680 --staking-port=9681 --staking-tls-cert-file=./staking/local/staker4.crt --staking-tls-key-file=./staking/local/staker4.key --staking-signer-key-file=./staking/local/signer4.key --bootstrap-ips="127.0.0.1:9651" --bootstrap-ids="NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg" &> node4.log & +${AVALANCHE_BINARY} --data-dir ./local5 --network-id=local --db-dir=./local5 --public-ip=127.0.0.1 --bootstrap-ips="127.0.0.1:9651" --bootstrap-ids="NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg" --http-port=9690 --staking-port=9691 --staking-tls-cert-file=./staking/local/staker5.crt --staking-tls-key-file=./staking/local/staker5.key --staking-signer-key-file=./staking/local/signer5.key &> node5.log & + + + + + + + + diff --git a/simplex/api.go b/simplex/api.go new file mode 100644 index 000000000000..6bd9c9196fc3 --- /dev/null +++ b/simplex/api.go @@ -0,0 +1,4 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex diff --git a/simplex/bb.go b/simplex/bb.go new file mode 100644 index 000000000000..64d983920fec --- /dev/null +++ b/simplex/bb.go @@ -0,0 +1,67 @@ +package simplex + +import ( + "context" + "fmt" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "go.uber.org/zap" + "simplex" + "time" +) + +type BlockBuilder struct { + e *Engine + Logger simplex.Logger + VM block.ChainVM +} + +func (b *BlockBuilder) BuildBlock(ctx context.Context, metadata simplex.ProtocolMetadata) (simplex.VerifiedBlock, bool) { + fmt.Println("Building block") + defer fmt.Println("Finished building block") + + b.IncomingBlock(ctx) + start := time.Now() + defer fmt.Println("Block building elapsed in", time.Since(start)) + + block, err := b.VM.BuildBlock(ctx) + if err != nil { + b.Logger.Error("Error building block:", zap.Error(err)) + return nil, false + } + + if err := block.Verify(context.Background()); err != nil { + b.Logger.Error("Error verifying block I have built myself: %s", zap.Error(err)) + return nil, false + } + + var vb VerifiedBlock + vb.metadata = metadata + vb.innerBlock = block.Bytes() + md := vb.BlockHeader() + b.e.observeDigestToIDMapping(md.Digest, block.ID()) + vb.accept = func(ctx context.Context) error { + b.e.removeDigestToIDMapping(md.Digest) + b.e.blockTracker.rejectSiblingsAndUncles(md.Round, md.Digest) + defer b.VM.SetPreference(context.Background(), block.ID()) + return block.Accept(ctx) + } + + return &vb, true +} + +func (b *BlockBuilder) IncomingBlock(ctx context.Context) { + b.e.ctx.Log.Info("Waiting for incoming block") + for { + msg := b.VM.SubscribeToEvents(ctx) + if msg == common.PendingTxs { + b.e.ctx.Log.Info("Received pending transactions") + return + } + select { + case <-ctx.Done(): + return + } + b.Logger.Warn("Received message we should not have received", zap.String("msg", msg.String())) + } +} diff --git a/simplex/block.go b/simplex/block.go new file mode 100644 index 000000000000..c4815c09f7f4 --- /dev/null +++ b/simplex/block.go @@ -0,0 +1,212 @@ +package simplex + +import ( + "bytes" + "context" + "crypto/sha256" + "encoding/binary" + "fmt" + "simplex" + "sync" + "time" + + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" +) + +type Block struct { + e *Engine + verifiedBlock VerifiedBlock + vm block.ChainVM +} + +func (b *Block) BlockHeader() simplex.BlockHeader { + return b.verifiedBlock.BlockHeader() +} + +func (b *Block) Verify(ctx context.Context) (simplex.VerifiedBlock, error) { + ctx, cancel := context.WithTimeout(ctx, time.Second*30) + defer cancel() + + block, err := b.vm.ParseBlock(ctx, b.verifiedBlock.innerBlock) + if err != nil { + return nil, err + } + + md := b.BlockHeader() + rejection := func(ctx context.Context) error { + b.e.removeDigestToIDMapping(md.Digest) + return block.Reject(ctx) + } + b.e.blockTracker.trackBlock(md.Round, md.Digest, rejection) + b.verifiedBlock.accept = func(ctx context.Context) error { + b.e.removeDigestToIDMapping(md.Digest) + b.e.ChainVM.SetPreference(context.Background(), block.ID()) + b.e.blockTracker.rejectSiblingsAndUncles(md.Round, md.Digest) + return block.Accept(ctx) + } + + err = block.Verify(ctx) + + if err == nil { + b.e.observeDigestToIDMapping(md.Digest, block.ID()) + } + + return &b.verifiedBlock, err +} + +type VerifiedBlock struct { + computeDigestOnce sync.Once + digest simplex.Digest // cached, not serialized + + metadata simplex.ProtocolMetadata + innerBlock []byte + accept func(context.Context) error +} + +func (v *VerifiedBlock) BlockHeader() simplex.BlockHeader { + v.computeDigestOnce.Do(v.computeDigest) + return simplex.BlockHeader{ + ProtocolMetadata: v.metadata, + Digest: v.digest, + } +} + +func (v *VerifiedBlock) FromBytes(buff []byte) error { + if len(buff) < 57 { + return fmt.Errorf("buff too small, expected at least 57 bytes, got %d", len(buff)) + } + v.metadataFromBytes(buff) + v.innerBlock = buff[57:] + return nil +} + +func (v *VerifiedBlock) metadataFromBytes(buff []byte) { + var pos int + + v.metadata.Version = buff[pos] + pos++ + + v.metadata.Epoch = binary.BigEndian.Uint64(buff[pos:]) + pos += 8 + + v.metadata.Round = binary.BigEndian.Uint64(buff[pos:]) + pos += 8 + + v.metadata.Seq = binary.BigEndian.Uint64(buff[pos:]) + pos += 8 + + copy(v.metadata.Prev[:], buff[pos:pos+32]) +} + +func (v *VerifiedBlock) Bytes() []byte { + mdBytes := v.metadataBytes() + buff := make([]byte, len(mdBytes)+len(v.innerBlock)) + copy(buff, mdBytes) + copy(buff[len(mdBytes):], v.innerBlock) + return buff +} + +func (v *VerifiedBlock) computeDigest() { + mdBytes := v.metadataBytes() + h := sha256.New() + h.Write(v.innerBlock) + h.Write(mdBytes) + digest := h.Sum(nil) + v.digest = simplex.Digest(digest[:]) +} + +func (v *VerifiedBlock) metadataBytes() []byte { + buff := make([]byte, 57) + var pos int + + buff[pos] = v.metadata.Version + pos++ + + binary.BigEndian.PutUint64(buff[pos:], v.metadata.Epoch) + pos += 8 + + binary.BigEndian.PutUint64(buff[pos:], v.metadata.Round) + pos += 8 + + binary.BigEndian.PutUint64(buff[pos:], v.metadata.Seq) + pos += 8 + + copy(buff[pos:], v.metadata.Prev[:]) + return buff +} + +type blockDeserializer struct { + vm block.ChainVM +} + +func (b *blockDeserializer) DeserializeBlock(bytes []byte) (simplex.VerifiedBlock, error) { + var vb VerifiedBlock + if err := vb.FromBytes(bytes); err != nil { + return nil, err + } + + _, err := b.vm.ParseBlock(context.Background(), vb.innerBlock) + if err != nil { + return nil, err + } + + vb.accept = func(ctx context.Context) error { + panic("should not be called yet") + } + + return &vb, vb.FromBytes(bytes) +} + +type blockRejection struct { + digest simplex.Digest + reject func(context.Context) error +} + +// blockTracker maps rounds to blocks verified in that round that may be rejected +type blockTracker struct { + lock sync.Mutex + round2Rejection map[uint64][]blockRejection +} + +func (bt *blockTracker) init() { + bt.round2Rejection = make(map[uint64][]blockRejection) +} + +func (bt *blockTracker) rejectSiblingsAndUncles(round uint64, acceptedDigest simplex.Digest) { + bt.lock.Lock() + defer bt.lock.Unlock() + + bt.disposeOfUncles(round) + bt.disposeOfSiblings(round, acceptedDigest) + // Completely get rid of the round, to make sure that the accepted block is not rejected in future rounds. + delete(bt.round2Rejection, round) +} + +func (bt *blockTracker) disposeOfSiblings(round uint64, acceptedDigest simplex.Digest) { + for _, rejection := range bt.round2Rejection[round] { + if !bytes.Equal(rejection.digest[:], acceptedDigest[:]) { + rejection.reject(context.Background()) + } + } +} + +func (bt *blockTracker) disposeOfUncles(round uint64) { + for r, rejections := range bt.round2Rejection { + if r < round { + for _, rejection := range rejections { + rejection.reject(context.Background()) + } + delete(bt.round2Rejection, r) + } + } +} + +func (bt *blockTracker) trackBlock(round uint64, digest simplex.Digest, reject func(context.Context) error) { + bt.lock.Lock() + defer bt.lock.Unlock() + + bt.round2Rejection[round] = append(bt.round2Rejection[round], blockRejection{ + digest: digest, + reject: reject, + }) +} diff --git a/simplex/bls.go b/simplex/bls.go new file mode 100644 index 000000000000..910a3ffcf8ba --- /dev/null +++ b/simplex/bls.go @@ -0,0 +1,201 @@ +package simplex + +import ( + "encoding/base64" + "encoding/binary" + "fmt" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "simplex" +) + +var ( + simplexLabel = []byte("") +) + +type BLSSigner struct { + ChainID ids.ID + NetworkID ids.ID + SignBLS func(msg []byte) (*bls.Signature, error) + NodeID ids.NodeID +} + +func (s *BLSSigner) Sign(message []byte) ([]byte, error) { + message2Sign := encodeMessageToSign(message, s.ChainID, s.NetworkID) + sig, err := s.SignBLS(message2Sign) + if err != nil { + return nil, err + } + + sigBytes := bls.SignatureToBytes(sig) + + buff := make([]byte, ids.NodeIDLen+len(sigBytes)) + copy(buff, s.NodeID[:]) + copy(buff[len(s.NodeID):], sigBytes) + + return sigBytes, nil +} + +func encodeMessageToSign(message []byte, chainID ids.ID, networkID ids.ID) []byte { + message2Sign := make([]byte, len(message)+len(simplexLabel)+ids.IDLen+ids.IDLen+4) + msgLenBuff := make([]byte, 4) + binary.BigEndian.PutUint32(msgLenBuff, uint32(len(message))) + copy(message2Sign, simplexLabel) + copy(message2Sign[len(simplexLabel):], chainID[:]) + copy(message2Sign[len(simplexLabel)+ids.IDLen:], networkID[:]) + copy(message2Sign[len(simplexLabel)+ids.IDLen+ids.IDLen:], msgLenBuff) + copy(message2Sign[len(simplexLabel)+ids.IDLen+ids.IDLen+4:], message) + return message2Sign +} + +type NodePK struct { + NodeID ids.NodeID + PublicKey *bls.PublicKey +} + +type BLSVerifier struct { + nodeID2PK map[ids.NodeID]bls.PublicKey + networkID ids.ID + chainID ids.ID +} + +func (v BLSVerifier) Verify(message []byte, signature []byte, signer simplex.NodeID) error { + if len(signer) != ids.NodeIDLen { + return fmt.Errorf("expected signer to be %d bytes but got %d bytes", ids.NodeIDLen, len(signer)) + } + + key := ids.NodeID(signer) + pk, exists := v.nodeID2PK[key] + if !exists { + return fmt.Errorf("signer %x is not found in the membership set", signer) + } + + sig, err := bls.SignatureFromBytes(signature) + if err != nil { + return fmt.Errorf("failed to parse signature: %w", err) + } + + message2Verify := encodeMessageToSign(message, v.chainID, v.networkID) + + if !bls.Verify(&pk, sig, message2Verify) { + return fmt.Errorf("signature verification failed") + } + + return nil +} + +type QC struct { + v BLSVerifier + sig bls.Signature + signers []simplex.NodeID +} + +func (qc *QC) Signers() []simplex.NodeID { + return qc.signers +} + +func (qc *QC) Verify(msg []byte) error { + pks := make([]*bls.PublicKey, 0, len(qc.signers)) + for _, signer := range qc.signers { + pk, exists := qc.v.nodeID2PK[ids.NodeID(signer)] + if !exists { + return fmt.Errorf("signer %x is not found in the membership set", signer) + } + pks = append(pks, &pk) + } + + aggPK, err := bls.AggregatePublicKeys(pks) + if err != nil { + return fmt.Errorf("failed to aggregate public keys: %w", err) + } + + message2Verify := encodeMessageToSign(msg, qc.v.chainID, qc.v.networkID) + + if !bls.Verify(aggPK, &qc.sig, message2Verify) { + return fmt.Errorf("signature verification failed") + } + + return nil +} + +func (qc *QC) Bytes() []byte { + sigBytes := bls.SignatureToBytes(&qc.sig) + buff := make([]byte, len(sigBytes)+len(qc.signers)*ids.NodeIDLen) + var pos int + for _, signer := range qc.signers { + copy(buff[pos:], signer[:ids.NodeIDLen]) + pos += ids.NodeIDLen + } + + copy(buff[pos:], sigBytes) + + return buff +} + +type QCDeserializer BLSVerifier + +func (d QCDeserializer) DeserializeQuorumCertificate(bytes []byte) (simplex.QuorumCertificate, error) { + quorumSize := simplex.Quorum(len(d.nodeID2PK)) + expectedMinimalSize := quorumSize * ids.NodeIDLen + if len(bytes) < expectedMinimalSize { + return nil, fmt.Errorf("expected at least %d bytes but got %d bytes", expectedMinimalSize, len(bytes)) + } + + signers := make([]simplex.NodeID, 0, quorumSize) + + var pos int + for range quorumSize { + signers = append(signers, bytes[pos:pos+ids.NodeIDLen]) + pos += ids.NodeIDLen + } + + sig, err := bls.SignatureFromBytes(bytes[pos:]) + if err != nil { + fmt.Println(">>>", base64.StdEncoding.EncodeToString(bytes)) + return nil, fmt.Errorf("failed to parse signature: %w", err) + } + + return &QC{ + v: BLSVerifier(d), + signers: signers, + sig: *sig, + }, nil +} + +type SignatureAggregator BLSVerifier + +func (a SignatureAggregator) Aggregate(signatures []simplex.Signature) (simplex.QuorumCertificate, error) { + quorumSize := simplex.Quorum(len(a.nodeID2PK)) + if len(signatures) < quorumSize { + return nil, fmt.Errorf("expected at least %d signatures but got %d", quorumSize, len(signatures)) + } + + signatures = signatures[:quorumSize] + + signers := make([]simplex.NodeID, 0, quorumSize) + sigs := make([]*bls.Signature, 0, quorumSize) + for _, signature := range signatures { + signer := signature.Signer + _, exists := a.nodeID2PK[ids.NodeID(signer)] + if !exists { + return nil, fmt.Errorf("signer %x is not found in the membership set", signer) + } + signers = append(signers, signer) + sig, err := bls.SignatureFromBytes(signature.Value) + if err != nil { + return nil, fmt.Errorf("failed to parse signature: %w", err) + } + sigs = append(sigs, sig) + } + + aggregatedSig, err := bls.AggregateSignatures(sigs) + if err != nil { + return nil, fmt.Errorf("failed to aggregate signatures: %w", err) + } + + return &QC{ + v: BLSVerifier(a), + signers: signers, + sig: *aggregatedSig, + }, nil +} diff --git a/simplex/bls_signer_verifier_test.go b/simplex/bls_signer_verifier_test.go new file mode 100644 index 000000000000..080c7b3f0420 --- /dev/null +++ b/simplex/bls_signer_verifier_test.go @@ -0,0 +1,125 @@ +package simplex + +import ( + "encoding/base64" + "fmt" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/avalanchego/utils/crypto/bls/signer/localsigner" + "github.com/stretchr/testify/require" + blst "github.com/supranational/blst/bindings/go" + "simplex" + "testing" +) + +func TestBLSSignVerify(t *testing.T) { + ls, err := localsigner.New() + require.NoError(t, err) + + pkBytes := bls.PublicKeyToCompressedBytes(ls.PublicKey()) + nodeID, err := ids.ToShortID(pkBytes[:ids.NodeIDLen]) + require.NoError(t, err) + + signer := BLSSigner{ + NodeID: ids.NodeID(nodeID), + SignBLS: ls.Sign, + } + + msg := "Begin at the beginning, and go on till you come to the end: then stop" + sig, err := signer.Sign([]byte(msg)) + require.NoError(t, err) + + var v = BLSVerifier{ + nodeID2PK: map[ids.NodeID]bls.PublicKey{ + signer.NodeID: *ls.PublicKey(), + }, + } + + err = v.Verify([]byte(msg), sig, signer.NodeID[:]) + require.NoError(t, err) +} + +func TestVerifyChainHalt(t *testing.T) { + s := `R59myL6JWDBUfnC0spjK/UM9um6qGNOZHPY3qmwWL16VzxY/ac2Ckd4xtNiyKZHVGqaqH8cz8jqFGoyU6QlPc2mAAv1SyQgZtFe5+8hmq4Dym85fNKdDAesN5xbVGU5KSupdeoW+Z/kTGcuwEn9xJbkEqP0ohiM9PnrxoI9obiH3pG36W+gyJZTVYYsm4HqrbrFQzxZttFrdryz1KKnwaTwzbPrN/WplcV1v5TxUsFy3IzTXUsodjantybon/zakCA3FMA==` + bytes, err := base64.StdEncoding.DecodeString(s) + require.NoError(t, err) + + pos := ids.NodeIDLen * 4 + + fmt.Println(blst.BLST_P2_COMPRESS_BYTES, len(bytes[pos:])) + + sig, err := bls.SignatureFromBytes(bytes[pos:]) + require.NoError(t, err) + require.NotNil(t, sig) +} + +func TestBLSVerifyQC(t *testing.T) { + s1, pk1 := createBLSSigner(t) + s2, pk2 := createBLSSigner(t) + s3, pk3 := createBLSSigner(t) + s4, pk4 := createBLSSigner(t) + + msg := "If you don't know where you are going any road can take you there" + + sig1, err := s1.Sign([]byte(msg)) + require.NoError(t, err) + + sig2, err := s2.Sign([]byte(msg)) + require.NoError(t, err) + + sig4, err := s4.Sign([]byte(msg)) + require.NoError(t, err) + + var v = BLSVerifier{ + nodeID2PK: map[ids.NodeID]bls.PublicKey{ + s1.NodeID: pk1, + s2.NodeID: pk2, + s3.NodeID: pk3, + s4.NodeID: pk4, + }, + } + + err = v.Verify([]byte(msg), sig1, s1.NodeID[:]) + require.NoError(t, err) + + err = v.Verify([]byte(msg), sig2, s2.NodeID[:]) + require.NoError(t, err) + + err = v.Verify([]byte(msg), sig4, s4.NodeID[:]) + require.NoError(t, err) + + sa := SignatureAggregator(v) + qc, err := sa.Aggregate([]simplex.Signature{ + {Signer: s1.NodeID[:], Value: sig1}, + {Signer: s2.NodeID[:], Value: sig2}, + {Signer: s4.NodeID[:], Value: sig4}, + }) + require.NoError(t, err) + + err = qc.Verify([]byte(msg)) + require.NoError(t, err) + + qcd := QCDeserializer(v) + qc, err = qcd.DeserializeQuorumCertificate(qc.Bytes()) + require.NoError(t, err) + + err = qc.Verify([]byte(msg)) + require.NoError(t, err) + + msg = msg + "J" + err = qc.Verify([]byte(msg)) + require.Error(t, err) +} + +func createBLSSigner(t *testing.T) (BLSSigner, bls.PublicKey) { + ls, err := localsigner.New() + require.NoError(t, err) + + pkBytes := bls.PublicKeyToCompressedBytes(ls.PublicKey()) + nodeID, err := ids.ToShortID(pkBytes[:ids.NodeIDLen]) + require.NoError(t, err) + return BLSSigner{ + SignBLS: ls.Sign, + NodeID: ids.NodeID(nodeID), + }, *ls.PublicKey() +} diff --git a/simplex/comm.go b/simplex/comm.go new file mode 100644 index 000000000000..3cce1ecd4984 --- /dev/null +++ b/simplex/comm.go @@ -0,0 +1,116 @@ +package simplex + +import ( + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/subnets" + "github.com/ava-labs/avalanchego/utils/set" + "go.uber.org/zap" + "simplex" + "sort" +) + +type ValidatorLister interface { + GetValidatorIDs(subnetID ids.ID) []ids.NodeID +} + +type Sender interface { + Send( + msg message.OutboundMessage, + config common.SendConfig, + subnetID ids.ID, + allower subnets.Allower, + ) set.Set[ids.NodeID] +} + +type Comm struct { + logger simplex.Logger + subnetID ids.ID + chainID ids.ID + myNodeID simplex.NodeID + nodes []simplex.NodeID + sender Sender + msgBuilder message.OutboundMsgBuilder +} + +func NewComm(myNodeID simplex.NodeID, + subnetID ids.ID, + chainID ids.ID, + logger simplex.Logger, + validatorLister ValidatorLister, + sender Sender, + msgBuilder message.OutboundMsgBuilder) *Comm { + var nodes []simplex.NodeID + for _, id := range validatorLister.GetValidatorIDs(subnetID) { + nodes = append(nodes, id[:]) + } + + sortedNodes := sortNodes(nodes) + + var found bool + for i, node := range sortedNodes { + if node.Equals(myNodeID) { + logger.Info("Found my node ID", zap.Int("index", i)) + found = true + } + } + + if !found { + logger.Fatal("My node ID not found in validator list") + } + + c := &Comm{subnetID: subnetID, nodes: sortedNodes, myNodeID: myNodeID, logger: logger, sender: sender, msgBuilder: msgBuilder, chainID: chainID} + return c +} + +func sortNodes(nodes []simplex.NodeID) []simplex.NodeID { + sort.Slice(nodes, func(i, j int) bool { + return nodes[i].String() < nodes[j].String() + }) + return nodes +} + +func (c *Comm) ListNodes() []simplex.NodeID { + return c.nodes +} + +func (c *Comm) SendMessage(msg *simplex.Message, destination simplex.NodeID) { + var outboundMessage message.OutboundMessage + var err error + switch { + case msg.VerifiedBlockMessage != nil: + outboundMessage, err = c.msgBuilder.Block(c.chainID, msg.VerifiedBlockMessage.VerifiedBlock.Bytes(), msg.VerifiedBlockMessage.Vote.Vote.BlockHeader, msg.VerifiedBlockMessage.Vote.Signature) + case msg.VoteMessage != nil: + outboundMessage, err = c.msgBuilder.Vote(c.chainID, msg.VoteMessage.Vote.BlockHeader, msg.VoteMessage.Signature) + case msg.EmptyVoteMessage != nil: + outboundMessage, err = c.msgBuilder.EmptyVote(c.chainID, msg.EmptyVoteMessage.Vote.ProtocolMetadata, msg.EmptyVoteMessage.Signature) + case msg.Finalization != nil: + outboundMessage, err = c.msgBuilder.Finalization(c.chainID, msg.Finalization.Finalization.BlockHeader, msg.Finalization.Signature) + case msg.Notarization != nil: + outboundMessage, err = c.msgBuilder.Notarization(c.chainID, msg.Notarization.Vote.BlockHeader, msg.Notarization.QC.Bytes()) + case msg.EmptyNotarization != nil: + outboundMessage, err = c.msgBuilder.EmptyNotarization(c.chainID, msg.EmptyNotarization.Vote.ProtocolMetadata, msg.EmptyNotarization.QC.Bytes()) + case msg.FinalizationCertificate != nil: + outboundMessage, err = c.msgBuilder.FinalizationCertificate(c.chainID, msg.FinalizationCertificate.Finalization.BlockHeader, msg.FinalizationCertificate.QC.Bytes()) + } + + if err != nil { + c.logger.Error("Failed creating message: %w", zap.Error(err)) + return + } + + dest := ids.NodeID(destination) + + c.sender.Send(outboundMessage, common.SendConfig{NodeIDs: set.Of(dest)}, c.subnetID, subnets.NoOpAllower) +} + +func (c *Comm) Broadcast(msg *simplex.Message) { + for _, node := range c.nodes { + if node.Equals(c.myNodeID) { + continue + } + + c.SendMessage(msg, node) + } +} diff --git a/simplex/config.go b/simplex/config.go new file mode 100644 index 000000000000..3b81ab299c71 --- /dev/null +++ b/simplex/config.go @@ -0,0 +1,28 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/crypto/bls" +) + +// Config wraps all the parameters needed for a snowman engine +type Config struct { + GenesisData []byte + GetServer common.AllGetsServer + SignBLS func(msg []byte) (*bls.Signature, error) + Sender Sender + OutboundMsgBuilder message.OutboundMsgBuilder + DB database.Database + + Ctx *snow.ConsensusContext + VM block.ChainVM + Validators validators.Manager +} diff --git a/simplex/engine.go b/simplex/engine.go new file mode 100644 index 000000000000..274dba3d0d82 --- /dev/null +++ b/simplex/engine.go @@ -0,0 +1,512 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package simplex + +import ( + "context" + "crypto/sha256" + "encoding/json" + "fmt" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "simplex" + "simplex/wal" + "sync" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/proto/pb/p2p" + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/set" + "github.com/ava-labs/avalanchego/version" + "go.uber.org/zap" +) + +func CreateSimplexInstance(config *Config) (*simplex.Epoch, *BlockBuilder, *WALInterceptor, error) { + signer := BLSSigner{ + NetworkID: config.Ctx.SubnetID, + ChainID: config.Ctx.ChainID, + NodeID: config.Ctx.NodeID, + SignBLS: config.SignBLS, + } + + verifier := createVerifier(config) + + comm := NewComm(config.Ctx.NodeID[:], config.Ctx.SubnetID, config.Ctx.ChainID, config.Ctx.Log, config.Validators, config.Sender, config.OutboundMsgBuilder) + + h := sha256.New() + h.Write(config.Ctx.NodeID[:]) + h.Write(config.Ctx.ChainID[:]) + walDigest := h.Sum(nil) + walFileName := fmt.Sprintf("%x.wal", walDigest[:10]) + + var epochWAL simplex.WriteAheadLog + var err error + + epochWAL, err = wal.New(walFileName) + if err != nil { + return nil, nil, nil, err + } + + walInterceptor := &WALInterceptor{ + WriteAheadLog: epochWAL, + } + + storage, err := createStorage(config, err, verifier) + if err != nil { + return nil, nil, nil, err + } + + bb := &BlockBuilder{ + Logger: config.Ctx.Log, + VM: config.VM, + } + + conf := simplex.EpochConfig{ + BlockBuilder: bb, + Signer: &signer, + ID: config.Ctx.NodeID[:], + Verifier: verifier, + Logger: config.Ctx.Log, + QCDeserializer: QCDeserializer(verifier), + SignatureAggregator: SignatureAggregator(verifier), + Comm: comm, + WAL: walInterceptor, + Storage: storage, + StartTime: time.Now(), + MaxProposalWait: time.Second * 2, + BlockDeserializer: &blockDeserializer{ + vm: config.VM, + }, + } + + simplex, err := simplex.NewEpoch(conf) + if err != nil { + return nil, nil, nil, err + } + + return simplex, bb, walInterceptor, nil +} + +func createStorage(config *Config, err error, verifier BLSVerifier) (*Storage, error) { + storage, err := NewStorage(config.DB, QCDeserializer(verifier), config.VM, config.GenesisData) + if err != nil { + return nil, err + } + + return storage, nil +} + +func createVerifier(config *Config) BLSVerifier { + verifier := BLSVerifier{ + nodeID2PK: make(map[ids.NodeID]bls.PublicKey), + networkID: config.Ctx.SubnetID, + chainID: config.Ctx.ChainID, + } + + nodes := config.Validators.GetValidatorIDs(config.Ctx.SubnetID) + for _, node := range nodes { + validator, ok := config.Validators.GetValidator(config.Ctx.SubnetID, node) + if !ok { + continue + } + + verifier.nodeID2PK[node] = *validator.PublicKey + } + return verifier +} + +type Engine struct { + ctx *snow.ConsensusContext + common.AllGetsServer + e *simplex.Epoch + block.ChainVM + blockTracker blockTracker + + // simplex digest to VM digest cache + lock sync.RWMutex + digestCache map[simplex.Digest]ids.ID +} + +func CreateEngine(config *Config) (*Engine, error) { + e, bb, wal, err := CreateSimplexInstance(config) + if err != nil { + return nil, err + } + + engine := &Engine{ + digestCache: make(map[simplex.Digest]ids.ID), + ctx: config.Ctx, + e: e, + ChainVM: config.VM, + AllGetsServer: config.GetServer, + } + + wal.Intercept = func(digest simplex.Digest) { + engine.lock.Lock() + defer engine.lock.Unlock() + + if id, ok := engine.digestCache[digest]; ok { + config.VM.SetPreference(context.Background(), id) + } + } + + bb.e = engine + + engine.blockTracker.init() + + return engine, nil +} + +func (e *Engine) StateSummaryFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, summary []byte) error { + return nil +} + +func (e *Engine) GetStateSummaryFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) AcceptedStateSummary(ctx context.Context, nodeID ids.NodeID, requestID uint32, summaryIDs set.Set[ids.ID]) error { + return nil +} + +func (e *Engine) GetAcceptedStateSummaryFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) AcceptedFrontier(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID) error { + return nil +} + +func (e *Engine) GetAcceptedFrontierFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) Accepted(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerIDs set.Set[ids.ID]) error { + return nil +} + +func (e *Engine) GetAcceptedFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) Ancestors(ctx context.Context, nodeID ids.NodeID, requestID uint32, containers [][]byte) error { + return nil +} + +func (e *Engine) GetAncestorsFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) Put(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte) error { + return nil +} + +func (e *Engine) GetFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) PullQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, containerID ids.ID, requestedHeight uint64) error { + return nil +} + +func (e *Engine) PushQuery(ctx context.Context, nodeID ids.NodeID, requestID uint32, container []byte, requestedHeight uint64) error { + return nil +} + +func (e *Engine) Chits(ctx context.Context, nodeID ids.NodeID, requestID uint32, preferredID ids.ID, preferredIDAtHeight ids.ID, acceptedID ids.ID, acceptedHeight uint64) error { + return nil +} + +func (e *Engine) QueryFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32) error { + return nil +} + +func (e *Engine) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { + return nil +} + +func (e *Engine) Disconnected(ctx context.Context, nodeID ids.NodeID) error { + return nil +} + +func (e *Engine) Gossip(ctx context.Context) error { + return nil +} + +func (e *Engine) Shutdown(ctx context.Context) error { + e.e.Stop() + return nil +} + +func (e *Engine) Notify(ctx context.Context, msg common.Message) error { + return nil +} + +func (e *Engine) Start(context.Context, uint32) error { + e.ctx.Log.Info("Starting the engine") + err := e.e.Start() + + if err == nil { + e.startTicker() + } + + return err +} + +func (e *Engine) startTicker() { + ticker := time.NewTicker(time.Millisecond * 500) + go func() { + for { + tick := <-ticker.C + e.e.AdvanceTime(tick) + } + }() +} + +func (e *Engine) HealthCheck(context.Context) (interface{}, error) { + return json.MarshalIndent(e.e.Metadata(), "\t", "\t") +} + +func (e *Engine) SimplexMessage(from ids.NodeID, msg *p2p.SimplexMessage) error { + simplexMessage := e.simplexMessageToSimplexMessage(msg) + if simplexMessage == nil { + e.ctx.Log.Warn("Failed converting p2p.SimplexMessage to simplex.Message") + return nil + } + e.e.Logger.Info("Received simplex message", zap.Any("message", simplexMessage)) + err := e.e.HandleMessage(simplexMessage, from[:]) + if err != nil { + e.ctx.Log.Error("Failed to handle simplex message", zap.Error(err)) + } + return err +} + +func (e *Engine) simplexMessageToSimplexMessage(message *p2p.SimplexMessage) *simplex.Message { + switch { + case message.GetBlock() != nil: + return e.convertBlockMessage(message) + case message.GetVote() != nil: + return convertVoteMessage(message) + case message.GetEmptyVote() != nil: + return convertEmptyVoteMessage(message) + case message.GetFinalization() != nil: + return convertFinalizationMessage(message) + case message.GetNotarization() != nil: + return convertNotarizationMessage(message, e.e.EpochConfig.QCDeserializer) + case message.GetEmptyNotarization() != nil: + return convertEmptyNotarizationMessage(message, e.e.EpochConfig.QCDeserializer) + case message.GetFinalizationCertificate() != nil: + return convertFinalizationCertificateMessage(message, e.e.EpochConfig.QCDeserializer) + default: + e.ctx.Log.Warn("Unknown message type", zap.Any("message", message)) + return nil + } +} + +func convertFinalizationCertificateMessage(message *p2p.SimplexMessage, deserializer simplex.QCDeserializer) *simplex.Message { + fc := message.GetFinalizationCertificate() + qc, err := deserializer.DeserializeQuorumCertificate(fc.QuorumCertificate) + if err != nil { + panic(err) // TODO: fix this + } + + metadata := fc.Finalization.Vote.Metadata + + msg := &simplex.Message{ + FinalizationCertificate: &simplex.FinalizationCertificate{ + QC: qc, + Finalization: simplex.ToBeSignedFinalization{ + BlockHeader: metadataToBlockHeader(metadata), + }, + }, + } + + copy(msg.FinalizationCertificate.Finalization.Digest[:], fc.Finalization.Vote.Digest) + copy(msg.FinalizationCertificate.Finalization.Prev[:], metadata.Prev) + + return msg +} + +func convertNotarizationMessage(message *p2p.SimplexMessage, deserializer simplex.QCDeserializer) *simplex.Message { + notarization := message.GetNotarization() + qc, err := deserializer.DeserializeQuorumCertificate(notarization.QuorumCertificate) + if err != nil { + panic(err) // TODO: fix this + } + + metadata := notarization.Vote.Metadata + + msg := &simplex.Message{ + Notarization: &simplex.Notarization{ + Vote: simplex.ToBeSignedVote{ + BlockHeader: metadataToBlockHeader(metadata), + }, + }, + } + + copy(msg.Notarization.Vote.Digest[:], notarization.Vote.Digest) + copy(msg.Notarization.Vote.Prev[:], metadata.Prev) + msg.Notarization.QC = qc + + return msg +} + +func convertEmptyNotarizationMessage(message *p2p.SimplexMessage, deserializer simplex.QCDeserializer) *simplex.Message { + emptyNotarization := message.GetEmptyNotarization() + qc, err := deserializer.DeserializeQuorumCertificate(emptyNotarization.QuorumCertificate) + if err != nil { + panic(err) // TODO: fix this + } + + metadata := emptyNotarization.EmptyVote.Metadata + + msg := &simplex.Message{ + EmptyNotarization: &simplex.EmptyNotarization{ + Vote: simplex.ToBeSignedEmptyVote{ + ProtocolMetadata: simplex.ProtocolMetadata{ + Round: metadata.Round, + Epoch: metadata.Epoch, + Seq: metadata.Seq, + }, + }, + }, + } + + copy(msg.EmptyNotarization.Vote.Prev[:], metadata.Prev) + msg.EmptyNotarization.QC = qc + + return msg +} + +func metadataToBlockHeader(metadata *p2p.ProtocolMetadata) simplex.BlockHeader { + return simplex.BlockHeader{ + ProtocolMetadata: simplex.ProtocolMetadata{ + Round: metadata.Round, + Epoch: metadata.Epoch, + Seq: metadata.Seq, + }, + } +} + +func convertVoteMessage(message *p2p.SimplexMessage) *simplex.Message { + vote := message.GetVote() + v := &simplex.Vote{ + Signature: simplex.Signature{ + Signer: vote.Signature.Signer, + Value: vote.Signature.Value, + }, + Vote: simplex.ToBeSignedVote{ + BlockHeader: metadataToBlockHeader(vote.Vote.Metadata), + }, + } + copy(v.Vote.Digest[:], vote.Vote.Digest) // TODO: check for nil + copy(v.Vote.Prev[:], vote.Vote.Metadata.Prev) // TODO: check for nil + return &simplex.Message{ + VoteMessage: v, + } +} + +func convertFinalizationMessage(message *p2p.SimplexMessage) *simplex.Message { + finalization := message.GetFinalization() + msg := &simplex.Message{ + Finalization: &simplex.Finalization{ + Signature: simplex.Signature{ + Signer: finalization.Signature.Signer, + Value: finalization.Signature.Value, + }, + Finalization: simplex.ToBeSignedFinalization{ + BlockHeader: metadataToBlockHeader(finalization.Vote.Metadata), + }, + }, + } + + copy(msg.Finalization.Finalization.Prev[:], finalization.Vote.Metadata.Prev) + copy(msg.Finalization.Finalization.Digest[:], finalization.Vote.Digest) + + return msg +} + +func convertEmptyVoteMessage(message *p2p.SimplexMessage) *simplex.Message { + vote := message.GetEmptyVote() + v := convertEmptyVote(&p2p.EmptyVote{ + Vote: vote.Vote, + Signature: vote.Signature, + }) + return &simplex.Message{ + EmptyVoteMessage: &simplex.EmptyVote{ + Vote: simplex.ToBeSignedEmptyVote{ + ProtocolMetadata: v.Vote.ProtocolMetadata, + }, + Signature: v.Signature, + }, + } +} + +func convertEmptyVote(vote *p2p.EmptyVote) *simplex.EmptyVote { + v := &simplex.EmptyVote{ + Signature: simplex.Signature{ + Signer: vote.Signature.Signer, + Value: vote.Signature.Value, + }, + Vote: simplex.ToBeSignedEmptyVote{ + ProtocolMetadata: metadataToBlockHeader(vote.Vote).ProtocolMetadata, + }, + } + copy(v.Vote.Prev[:], vote.Vote.Prev) // TODO: check for nil + return v +} + +func convertVote(vote *p2p.Vote) *simplex.Vote { + v := &simplex.Vote{ + Signature: simplex.Signature{ + Signer: vote.Signature.Signer, + Value: vote.Signature.Value, + }, + Vote: simplex.ToBeSignedVote{ + BlockHeader: metadataToBlockHeader(vote.Vote.Metadata), + }, + } + copy(v.Vote.Digest[:], vote.Vote.Digest) // TODO: check for nil + copy(v.Vote.Prev[:], vote.Vote.Metadata.Prev) // TODO: check for nil + return v +} + +func (e *Engine) removeDigestToIDMapping(digest simplex.Digest) { + e.lock.Lock() + defer e.lock.Unlock() + + delete(e.digestCache, digest) +} + +func (e *Engine) observeDigestToIDMapping(digest simplex.Digest, blockID ids.ID) { + e.lock.Lock() + defer e.lock.Unlock() + + // the block ID is input to the entire simplex block, therefore + // if the leader equivocates the simplex digest will be different. + e.digestCache[digest] = blockID +} + +func (e *Engine) convertBlockMessage(message *p2p.SimplexMessage) *simplex.Message { + e.e.Logger.Info("converting block message", zap.Int("size", len(message.GetBlock().Block))) + var block Block + if err := block.verifiedBlock.FromBytes(message.GetBlock().Block); err != nil { + e.ctx.Log.Warn("failed to parse block", zap.Error(err)) + return nil + } + + e.e.Logger.Info("converted block message", zap.Int("inner block size", len(block.verifiedBlock.innerBlock))) + + block.vm = e.ChainVM + block.e = e + + return &simplex.Message{ + BlockMessage: &simplex.BlockMessage{ + Block: &block, + Vote: *convertVote(message.GetBlock().Vote), + }, + } +} diff --git a/simplex/storage.go b/simplex/storage.go new file mode 100644 index 000000000000..e9ce7ebed7f1 --- /dev/null +++ b/simplex/storage.go @@ -0,0 +1,160 @@ +package simplex + +import ( + "context" + "encoding/binary" + "errors" + "fmt" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "simplex" + "sync/atomic" + + "github.com/ava-labs/avalanchego/database" + "github.com/ava-labs/avalanchego/database/prefixdb" + "github.com/ava-labs/avalanchego/database/versiondb" +) + +type Storage struct { + height atomic.Uint64 + db *versiondb.Database + vm block.ChainVM + d QCDeserializer + genesisData []byte +} + +func (s *Storage) Height() uint64 { + return s.height.Load() +} + +// Retrieve returns the block and finalization certificate at [seq]. +// If [seq] is not found, returns false. +func (s *Storage) Retrieve(seq uint64) (simplex.VerifiedBlock, simplex.FinalizationCertificate, bool) { + if seq == 0 { + return &VerifiedBlock{innerBlock: s.genesisData, metadata: simplex.ProtocolMetadata{}}, simplex.FinalizationCertificate{}, true + } + + id, err := s.vm.GetBlockIDAtHeight(context.Background(), seq+1) + if err != nil { + return nil, simplex.FinalizationCertificate{}, false + } + + block, err := s.vm.GetBlock(context.Background(), id) + if err != nil { + return nil, simplex.FinalizationCertificate{}, false + } + + if seq == 0 { + return &VerifiedBlock{innerBlock: block.Bytes()}, simplex.FinalizationCertificate{}, true + } + + seqBuff := make([]byte, 8) + binary.BigEndian.PutUint64(seqBuff, seq) + fCertBytes, err := s.db.Get(seqBuff) + if err != nil { + return nil, simplex.FinalizationCertificate{}, false + } + + fCert, err := fCertFromBytes(fCertBytes, s.d) + if err != nil { + panic(err) + } + + vb := &VerifiedBlock{innerBlock: block.Bytes(), metadata: fCert.Finalization.ProtocolMetadata} + + return vb, fCert, true +} +func (s *Storage) Index(block simplex.VerifiedBlock, fCert simplex.FinalizationCertificate) { + currentHeight := s.height.Load() + newHeight := currentHeight + 1 + s.height.Store(newHeight) + + heightBuff, seqBuff := encodeHeightAndSeq(currentHeight) + + if err := s.db.Put([]byte("height"), heightBuff); err != nil { + panic(err) + } + + var fCertBuff []byte + + if currentHeight > 0 { + fCertBuff = fCertToBytes(fCert) + } + + if err := s.db.Put(seqBuff, fCertBuff); err != nil { + panic(err) + } + + fmt.Println(">>>> block.(*VerifiedBlock):", block.(*VerifiedBlock)) + fmt.Println(">>>> block.(*VerifiedBlock).accept:", fmt.Sprintf("%p", block.(*VerifiedBlock).accept)) + if err := block.(*VerifiedBlock).accept(context.Background()); err != nil { + panic(err) + } +} + +func encodeHeightAndSeq(seq uint64) ([]byte, []byte) { + heightBuff := make([]byte, 8) + binary.BigEndian.PutUint64(heightBuff, seq+1) + seqBuff := make([]byte, 8) + binary.BigEndian.PutUint64(seqBuff, seq) + return heightBuff, seqBuff +} + +func NewStorage(db database.Database, d QCDeserializer, vm block.ChainVM, genesisData []byte) (*Storage, error) { + var s Storage + + vdb := versiondb.New(prefixdb.New([]byte("simplex"), db)) + + height, err := initHeight(vdb) + if err != nil { + return nil, err + } + + s.height.Store(height) + s.db = vdb + s.d = d + s.vm = vm + s.genesisData = genesisData + + return &s, nil +} + +func initHeight(vdb *versiondb.Database) (uint64, error) { + var height uint64 + heightBytes, err := vdb.Get([]byte("height")) + if !errors.Is(err, database.ErrNotFound) { + return 0, fmt.Errorf("failed retrieving height from DB: %w", err) + } + if err == nil { + height = binary.BigEndian.Uint64(heightBytes) + } else { + buff := make([]byte, 8) + binary.BigEndian.PutUint64(buff, 1) + err = vdb.Put([]byte("height"), buff) + height = 1 + } + return height, err +} + +func fCertToBytes(fCert simplex.FinalizationCertificate) []byte { + blockHeaderBytes := fCert.Finalization.Bytes() + qcBytes := fCert.QC.Bytes() + buff := make([]byte, len(blockHeaderBytes)+len(qcBytes)) + copy(buff, blockHeaderBytes) + copy(buff[len(blockHeaderBytes):], qcBytes) + return buff +} + +func fCertFromBytes(bytes []byte, d QCDeserializer) (simplex.FinalizationCertificate, error) { + var fCert simplex.FinalizationCertificate + if err := fCert.Finalization.FromBytes(bytes[:89]); err != nil { + return simplex.FinalizationCertificate{}, err + } + + qc, err := d.DeserializeQuorumCertificate(bytes[89:]) + if err != nil { + return simplex.FinalizationCertificate{}, err + } + + fCert.QC = qc + return fCert, nil +} diff --git a/simplex/storage_test.go b/simplex/storage_test.go new file mode 100644 index 000000000000..7c586032e629 --- /dev/null +++ b/simplex/storage_test.go @@ -0,0 +1,96 @@ +package simplex + +import ( + "context" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/snow/consensus/snowman/snowmantest" + "github.com/ava-labs/avalanchego/snow/engine/snowman/block/blocktest" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "simplex" + "testing" + + "github.com/ava-labs/avalanchego/database/memdb" + "github.com/stretchr/testify/require" +) + +func TestStorage(t *testing.T) { + s1, pk1 := createBLSSigner(t) + s2, pk2 := createBLSSigner(t) + s3, pk3 := createBLSSigner(t) + s4, pk4 := createBLSSigner(t) + + var v = BLSVerifier{ + nodeID2PK: map[ids.NodeID]bls.PublicKey{ + s1.NodeID: pk1, + s2.NodeID: pk2, + s3.NodeID: pk3, + s4.NodeID: pk4, + }, + } + + vmIDStorage := make(map[uint64]ids.ID) + vmBlockStorage := make(map[ids.ID]*snowmantest.Block) + + memDB := memdb.New() + vm := &blocktest.VM{} + s, err := NewStorage(memDB, QCDeserializer(v), vm, []byte{1, 2, 3}) + require.NoError(t, err) + + msg := "Begin at the beginning, and go on till you come to the end: then stop." + + sig1, err := s1.Sign([]byte(msg)) + require.NoError(t, err) + + sig2, err := s2.Sign([]byte(msg)) + require.NoError(t, err) + + sig4, err := s4.Sign([]byte(msg)) + require.NoError(t, err) + + qc, err := SignatureAggregator(v).Aggregate([]simplex.Signature{ + {Signer: s1.NodeID[:], Value: sig1}, + {Signer: s2.NodeID[:], Value: sig2}, + {Signer: s4.NodeID[:], Value: sig4}, + }) + + blockID2 := ids.GenerateTestID() + + vm.GetBlockIDAtHeightF = func(ctx context.Context, height uint64) (ids.ID, error) { + return vmIDStorage[height], nil + } + + vm.GetBlockF = func(ctx context.Context, id ids.ID) (snowman.Block, error) { + return vmBlockStorage[id], nil + } + + s.Index(&VerifiedBlock{ + accept: func(ctx context.Context) error { + vmIDStorage[2] = blockID2 + vmBlockStorage[blockID2] = &snowmantest.Block{ + BytesV: []byte{4, 5, 6}, + } + return nil + }, + innerBlock: []byte{4, 5, 6}, + }, simplex.FinalizationCertificate{QC: qc}) + require.Equal(t, uint64(2), s.Height()) + + block0, fCert, ok := s.Retrieve(0) + require.True(t, ok) + require.Equal(t, simplex.FinalizationCertificate{}, fCert) + + var vb VerifiedBlock + err = vb.FromBytes(block0.Bytes()) + require.NoError(t, err) + require.Equal(t, []byte{1, 2, 3}, vb.innerBlock) + + block1, fCert, ok := s.Retrieve(1) + require.True(t, ok) + + err = vb.FromBytes(block1.Bytes()) + require.NoError(t, err) + require.Equal(t, []byte{4, 5, 6}, vb.innerBlock) + require.Equal(t, qc.Bytes(), fCert.QC.Bytes()) + +} diff --git a/simplex/wal.go b/simplex/wal.go new file mode 100644 index 000000000000..2d2889fd2994 --- /dev/null +++ b/simplex/wal.go @@ -0,0 +1,39 @@ +package simplex + +import ( + "encoding/asn1" + "encoding/binary" + "errors" + "simplex" + "simplex/record" +) + +type WALInterceptor struct { + Intercept func(digest simplex.Digest) + simplex.WriteAheadLog +} + +func (w *WALInterceptor) Append(data []byte) error { + if len(data) < 2 { + return errors.New("data too short, expected at least 2 bytes") + } + + recordType := binary.BigEndian.Uint16(data[:2]) + recordWithoutType := data[2:] + + if recordType == record.NotarizationRecordType { + var qr simplex.QuorumRecord + if _, err := asn1.Unmarshal(recordWithoutType, &qr); err != nil { + return err + } + + var vote simplex.ToBeSignedVote + if err := vote.FromBytes(qr.Vote); err != nil { + return err + } + + w.Intercept(vote.Digest) + } + + return w.WriteAheadLog.Append(data) +} diff --git a/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go b/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go index 19c2c4290475..6ce57991d2d8 100644 --- a/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go +++ b/snow/engine/avalanche/vertex/vertexmock/linearizable_vm.go @@ -29,7 +29,6 @@ import ( type LinearizableVM struct { ctrl *gomock.Controller recorder *LinearizableVMMockRecorder - isgomock struct{} } // LinearizableVMMockRecorder is the mock recorder for LinearizableVM. @@ -50,59 +49,59 @@ func (m *LinearizableVM) EXPECT() *LinearizableVMMockRecorder { } // AppGossip mocks base method. -func (m *LinearizableVM) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { +func (m *LinearizableVM) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppGossip", ctx, nodeID, msg) + ret := m.ctrl.Call(m, "AppGossip", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // AppGossip indicates an expected call of AppGossip. -func (mr *LinearizableVMMockRecorder) AppGossip(ctx, nodeID, msg any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) AppGossip(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*LinearizableVM)(nil).AppGossip), ctx, nodeID, msg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*LinearizableVM)(nil).AppGossip), arg0, arg1, arg2) } // AppRequest mocks base method. -func (m *LinearizableVM) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { +func (m *LinearizableVM) AppRequest(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 time.Time, arg4 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequest", ctx, nodeID, requestID, deadline, request) + ret := m.ctrl.Call(m, "AppRequest", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(error) return ret0 } // AppRequest indicates an expected call of AppRequest. -func (mr *LinearizableVMMockRecorder) AppRequest(ctx, nodeID, requestID, deadline, request any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*LinearizableVM)(nil).AppRequest), ctx, nodeID, requestID, deadline, request) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*LinearizableVM)(nil).AppRequest), arg0, arg1, arg2, arg3, arg4) } // AppRequestFailed mocks base method. -func (m *LinearizableVM) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { +func (m *LinearizableVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequestFailed", ctx, nodeID, requestID, appErr) + ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *LinearizableVMMockRecorder) AppRequestFailed(ctx, nodeID, requestID, appErr any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*LinearizableVM)(nil).AppRequestFailed), ctx, nodeID, requestID, appErr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*LinearizableVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } // AppResponse mocks base method. -func (m *LinearizableVM) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { +func (m *LinearizableVM) AppResponse(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppResponse", ctx, nodeID, requestID, response) + ret := m.ctrl.Call(m, "AppResponse", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppResponse indicates an expected call of AppResponse. -func (mr *LinearizableVMMockRecorder) AppResponse(ctx, nodeID, requestID, response any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*LinearizableVM)(nil).AppResponse), ctx, nodeID, requestID, response) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*LinearizableVM)(nil).AppResponse), arg0, arg1, arg2, arg3) } // BuildBlock mocks base method. @@ -121,17 +120,17 @@ func (mr *LinearizableVMMockRecorder) BuildBlock(arg0 any) *gomock.Call { } // Connected mocks base method. -func (m *LinearizableVM) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { +func (m *LinearizableVM) Connected(arg0 context.Context, arg1 ids.NodeID, arg2 *version.Application) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Connected", ctx, nodeID, nodeVersion) + ret := m.ctrl.Call(m, "Connected", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // Connected indicates an expected call of Connected. -func (mr *LinearizableVMMockRecorder) Connected(ctx, nodeID, nodeVersion any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*LinearizableVM)(nil).Connected), ctx, nodeID, nodeVersion) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*LinearizableVM)(nil).Connected), arg0, arg1, arg2) } // CreateHandlers mocks base method. @@ -150,47 +149,47 @@ func (mr *LinearizableVMMockRecorder) CreateHandlers(arg0 any) *gomock.Call { } // Disconnected mocks base method. -func (m *LinearizableVM) Disconnected(ctx context.Context, nodeID ids.NodeID) error { +func (m *LinearizableVM) Disconnected(arg0 context.Context, arg1 ids.NodeID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Disconnected", ctx, nodeID) + ret := m.ctrl.Call(m, "Disconnected", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Disconnected indicates an expected call of Disconnected. -func (mr *LinearizableVMMockRecorder) Disconnected(ctx, nodeID any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*LinearizableVM)(nil).Disconnected), ctx, nodeID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*LinearizableVM)(nil).Disconnected), arg0, arg1) } // GetBlock mocks base method. -func (m *LinearizableVM) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) { +func (m *LinearizableVM) GetBlock(arg0 context.Context, arg1 ids.ID) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlock", ctx, blkID) + ret := m.ctrl.Call(m, "GetBlock", arg0, arg1) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlock indicates an expected call of GetBlock. -func (mr *LinearizableVMMockRecorder) GetBlock(ctx, blkID any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) GetBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*LinearizableVM)(nil).GetBlock), ctx, blkID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*LinearizableVM)(nil).GetBlock), arg0, arg1) } // GetBlockIDAtHeight mocks base method. -func (m *LinearizableVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error) { +func (m *LinearizableVM) GetBlockIDAtHeight(arg0 context.Context, arg1 uint64) (ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockIDAtHeight", ctx, height) + ret := m.ctrl.Call(m, "GetBlockIDAtHeight", arg0, arg1) ret0, _ := ret[0].(ids.ID) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *LinearizableVMMockRecorder) GetBlockIDAtHeight(ctx, height any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*LinearizableVM)(nil).GetBlockIDAtHeight), ctx, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*LinearizableVM)(nil).GetBlockIDAtHeight), arg0, arg1) } // HealthCheck mocks base method. @@ -209,17 +208,17 @@ func (mr *LinearizableVMMockRecorder) HealthCheck(arg0 any) *gomock.Call { } // Initialize mocks base method. -func (m *LinearizableVM) Initialize(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes, upgradeBytes, configBytes []byte, toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender) error { +func (m *LinearizableVM) Initialize(arg0 context.Context, arg1 *snow.Context, arg2 database.Database, arg3, arg4, arg5 []byte, arg6 []*common.Fx, arg7 common.AppSender) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Initialize", ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender) + ret := m.ctrl.Call(m, "Initialize", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) ret0, _ := ret[0].(error) return ret0 } // Initialize indicates an expected call of Initialize. -func (mr *LinearizableVMMockRecorder) Initialize(ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*LinearizableVM)(nil).Initialize), ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*LinearizableVM)(nil).Initialize), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } // LastAccepted mocks base method. @@ -238,75 +237,75 @@ func (mr *LinearizableVMMockRecorder) LastAccepted(arg0 any) *gomock.Call { } // Linearize mocks base method. -func (m *LinearizableVM) Linearize(ctx context.Context, stopVertexID ids.ID) error { +func (m *LinearizableVM) Linearize(arg0 context.Context, arg1 ids.ID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Linearize", ctx, stopVertexID) + ret := m.ctrl.Call(m, "Linearize", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Linearize indicates an expected call of Linearize. -func (mr *LinearizableVMMockRecorder) Linearize(ctx, stopVertexID any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) Linearize(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Linearize", reflect.TypeOf((*LinearizableVM)(nil).Linearize), ctx, stopVertexID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Linearize", reflect.TypeOf((*LinearizableVM)(nil).Linearize), arg0, arg1) } // ParseBlock mocks base method. -func (m *LinearizableVM) ParseBlock(ctx context.Context, blockBytes []byte) (snowman.Block, error) { +func (m *LinearizableVM) ParseBlock(arg0 context.Context, arg1 []byte) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ParseBlock", ctx, blockBytes) + ret := m.ctrl.Call(m, "ParseBlock", arg0, arg1) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // ParseBlock indicates an expected call of ParseBlock. -func (mr *LinearizableVMMockRecorder) ParseBlock(ctx, blockBytes any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) ParseBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*LinearizableVM)(nil).ParseBlock), ctx, blockBytes) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*LinearizableVM)(nil).ParseBlock), arg0, arg1) } // ParseTx mocks base method. -func (m *LinearizableVM) ParseTx(ctx context.Context, txBytes []byte) (snowstorm.Tx, error) { +func (m *LinearizableVM) ParseTx(arg0 context.Context, arg1 []byte) (snowstorm.Tx, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ParseTx", ctx, txBytes) + ret := m.ctrl.Call(m, "ParseTx", arg0, arg1) ret0, _ := ret[0].(snowstorm.Tx) ret1, _ := ret[1].(error) return ret0, ret1 } // ParseTx indicates an expected call of ParseTx. -func (mr *LinearizableVMMockRecorder) ParseTx(ctx, txBytes any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) ParseTx(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseTx", reflect.TypeOf((*LinearizableVM)(nil).ParseTx), ctx, txBytes) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseTx", reflect.TypeOf((*LinearizableVM)(nil).ParseTx), arg0, arg1) } // SetPreference mocks base method. -func (m *LinearizableVM) SetPreference(ctx context.Context, blkID ids.ID) error { +func (m *LinearizableVM) SetPreference(arg0 context.Context, arg1 ids.ID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetPreference", ctx, blkID) + ret := m.ctrl.Call(m, "SetPreference", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // SetPreference indicates an expected call of SetPreference. -func (mr *LinearizableVMMockRecorder) SetPreference(ctx, blkID any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) SetPreference(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*LinearizableVM)(nil).SetPreference), ctx, blkID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*LinearizableVM)(nil).SetPreference), arg0, arg1) } // SetState mocks base method. -func (m *LinearizableVM) SetState(ctx context.Context, state snow.State) error { +func (m *LinearizableVM) SetState(arg0 context.Context, arg1 snow.State) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetState", ctx, state) + ret := m.ctrl.Call(m, "SetState", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // SetState indicates an expected call of SetState. -func (mr *LinearizableVMMockRecorder) SetState(ctx, state any) *gomock.Call { +func (mr *LinearizableVMMockRecorder) SetState(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*LinearizableVM)(nil).SetState), ctx, state) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*LinearizableVM)(nil).SetState), arg0, arg1) } // Shutdown mocks base method. @@ -323,6 +322,20 @@ func (mr *LinearizableVMMockRecorder) Shutdown(arg0 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*LinearizableVM)(nil).Shutdown), arg0) } +// SubscribeToEvents mocks base method. +func (m *LinearizableVM) SubscribeToEvents(arg0 context.Context) common.Message { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubscribeToEvents", arg0) + ret0, _ := ret[0].(common.Message) + return ret0 +} + +// SubscribeToEvents indicates an expected call of SubscribeToEvents. +func (mr *LinearizableVMMockRecorder) SubscribeToEvents(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToEvents", reflect.TypeOf((*LinearizableVM)(nil).SubscribeToEvents), arg0) +} + // Version mocks base method. func (m *LinearizableVM) Version(arg0 context.Context) (string, error) { m.ctrl.T.Helper() diff --git a/snow/engine/avalanche/vertex/vm.go b/snow/engine/avalanche/vertex/vm.go index 9987fe164d35..e1375cecf2fc 100644 --- a/snow/engine/avalanche/vertex/vm.go +++ b/snow/engine/avalanche/vertex/vm.go @@ -8,7 +8,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowstorm" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" ) @@ -30,7 +29,6 @@ type LinearizableVMWithEngine interface { Linearize( ctx context.Context, stopVertexID ids.ID, - toEngine chan<- common.Message, ) error } diff --git a/snow/engine/common/engine.go b/snow/engine/common/engine.go index d1ad325b5d21..2c56d5f79e56 100644 --- a/snow/engine/common/engine.go +++ b/snow/engine/common/engine.go @@ -5,6 +5,7 @@ package common import ( "context" + "github.com/ava-labs/avalanchego/proto/pb/p2p" "time" "github.com/ava-labs/avalanchego/api/health" @@ -427,3 +428,7 @@ type InternalHandler interface { // Notify this engine of a message from the virtual machine. Notify(context.Context, Message) error } + +type SimplexHandler interface { + SimplexMessage(nodeID ids.NodeID, message *p2p.SimplexMessage) error +} diff --git a/snow/engine/common/notifier.go b/snow/engine/common/notifier.go new file mode 100644 index 000000000000..d601cf339f17 --- /dev/null +++ b/snow/engine/common/notifier.go @@ -0,0 +1,70 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import ( + "context" + "github.com/ava-labs/avalanchego/utils/logging" + "go.uber.org/zap" + "sync" +) + +type Notifier interface { + Notify(context.Context, Message) error +} + +type NotificationForwarder struct { + closeChan chan struct{} + Notifier Notifier + Subscribe Subscription + Log logging.Logger + + lock sync.Mutex + cancel context.CancelFunc +} + +func (nf *NotificationForwarder) Start() { + nf.closeChan = make(chan struct{}) + go nf.run() +} + +func (nf *NotificationForwarder) run() { + for { + select { + case <-nf.closeChan: + return + default: + } + + ctx := nf.getContext() + msg := nf.Subscribe(ctx) + nf.cancel() + + if err := nf.Notifier.Notify(ctx, msg); err != nil { + nf.Log.Error("Failed notifying engine", zap.Error(err)) + } + } +} + +func (nf *NotificationForwarder) getContext() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + + nf.lock.Lock() + nf.cancel = cancel + nf.lock.Unlock() + return ctx +} + +func (nf *NotificationForwarder) Close() { + select { + case <-nf.closeChan: + default: + close(nf.closeChan) + nf.lock.Lock() + if nf.cancel != nil { + nf.cancel() + } + nf.lock.Unlock() + } +} diff --git a/snow/engine/common/subscription.go b/snow/engine/common/subscription.go new file mode 100644 index 000000000000..6d2a70b15a0f --- /dev/null +++ b/snow/engine/common/subscription.go @@ -0,0 +1,227 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import ( + "context" + "sync" +) + +type Subscriber interface { + // SubscribeToEvents blocks until either the given context is cancelled, or a message is returned. + SubscribeToEvents(ctx context.Context) Message +} + +// Subscription is a function that blocks until either the given context is cancelled, or a message is returned. +type Subscription func(ctx context.Context) Message + +type SimpleSubscriber struct { + lock sync.Mutex + signal sync.Cond + + msg *Message + closed bool +} + +func NewSimpleSubscriber() *SimpleSubscriber { + ss := &SimpleSubscriber{} + ss.signal = *sync.NewCond(&ss.lock) + return ss +} + +func (ss *SimpleSubscriber) Publish(msg Message) { + ss.lock.Lock() + defer ss.lock.Unlock() + + ss.msg = &msg + ss.signal.Broadcast() +} + +func (ss *SimpleSubscriber) Close() { + ss.lock.Lock() + defer ss.lock.Unlock() + + ss.closed = true + ss.signal.Broadcast() +} + +func (ss *SimpleSubscriber) SubscribeToEvents(ctx context.Context) Message { + ss.lock.Lock() + defer ss.lock.Unlock() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + go func() { + <-ctx.Done() + ss.signal.Broadcast() + }() + + for { + if ss.closed { + return 0 + } + if ss.msg != nil { + msg := *ss.msg + ss.msg = nil + return msg + } + + select { + case <-ctx.Done(): + return 0 + default: + ss.signal.Wait() + } + } +} + +type SubscriptionDelayer struct { + lock sync.Mutex + signal sync.Cond + + absorbedMsg *Message + releasedMsg *Message + + closed bool + subscribe Subscription + onClose context.CancelFunc +} + +func NewSubscriptionDelayer(s Subscription) *SubscriptionDelayer { + sd := &SubscriptionDelayer{ + subscribe: s, + } + + sd.signal = *sync.NewCond(&sd.lock) + + go sd.forward() + + return sd +} + +func (sd *SubscriptionDelayer) Close() { + sd.lock.Lock() + defer sd.lock.Unlock() + + if sd.onClose != nil { + sd.onClose() + } + + sd.closed = true + sd.onClose = nil +} + +func (sd *SubscriptionDelayer) isClosed() bool { + sd.lock.Lock() + defer sd.lock.Unlock() + + return sd.closed +} + +func (sd *SubscriptionDelayer) forward() { + for !sd.isClosed() { + ctx := sd.createContext() + if sd.isClosed() { + return + } + if sd.subscribe == nil { + panic("subscription is nil") + } + msg := sd.subscribe(ctx) + if sd.isClosed() { + return + } + sd.SetAbsorbedMsg(msg) + sd.signal.Broadcast() + } +} + +func (sd *SubscriptionDelayer) Absorb(ctx context.Context) { + sd.lock.Lock() + defer sd.lock.Unlock() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + go func() { + <-ctx.Done() + sd.signal.Broadcast() + }() + + for { + select { + case <-ctx.Done(): + return + default: + } + + if sd.absorbedMsg != nil { + return + } + + sd.signal.Wait() + } + +} + +func (sd *SubscriptionDelayer) Release() { + sd.lock.Lock() + defer sd.lock.Unlock() + + if sd.absorbedMsg != nil { + sd.releasedMsg = sd.absorbedMsg + sd.absorbedMsg = nil + } + + sd.signal.Broadcast() +} + +func (sd *SubscriptionDelayer) SetAbsorbedMsg(msg Message) { + sd.lock.Lock() + defer sd.lock.Unlock() + + sd.absorbedMsg = &msg + sd.signal.Broadcast() +} + +func (sd *SubscriptionDelayer) createContext() context.Context { + sd.lock.Lock() + ctx, cancel := context.WithCancel(context.Background()) + sd.onClose = cancel + sd.lock.Unlock() + return ctx +} + +func (sd *SubscriptionDelayer) SubscribeToEvents(ctx context.Context) Message { + sd.lock.Lock() + defer sd.lock.Unlock() + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + go func() { + <-ctx.Done() + sd.signal.Broadcast() + }() + + for { + if sd.closed { + return 0 + } + + if sd.releasedMsg != nil { + msg := *sd.releasedMsg + sd.releasedMsg = nil + return msg + } + + select { + case <-ctx.Done(): + return 0 + default: + sd.signal.Wait() + } + } +} diff --git a/snow/engine/common/subscription_test.go b/snow/engine/common/subscription_test.go new file mode 100644 index 000000000000..a2f2b4709339 --- /dev/null +++ b/snow/engine/common/subscription_test.go @@ -0,0 +1,91 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package common + +import ( + "context" + "github.com/stretchr/testify/require" + "sync" + "testing" + "time" +) + +func TestSimpleSubscriber(t *testing.T) { + subscriber := NewSimpleSubscriber() + ctx, cancel := context.WithCancel(context.Background()) + + t.Run("TestSubscribe after publish", func(t *testing.T) { + subscriber.Publish(PendingTxs) + msg := subscriber.SubscribeToEvents(ctx) + require.Equal(t, PendingTxs, msg) + }) + + t.Run("TestSubscribe before publish", func(t *testing.T) { + go func() { + time.Sleep(time.Millisecond * 10) + subscriber.Publish(StateSyncDone) + }() + + msg := subscriber.SubscribeToEvents(ctx) + require.Equal(t, StateSyncDone, msg) + }) + + t.Run("TestSubscribe but abort", func(t *testing.T) { + go func() { + time.Sleep(time.Millisecond * 10) + cancel() + }() + msg := subscriber.SubscribeToEvents(ctx) + require.Equal(t, Message(0), msg) + }) + +} + +func TestSubscriptionDelayer(t *testing.T) { + msgs := make(chan Message) + subscription := func(ctx context.Context) Message { + msg := <-msgs + return msg + } + + sd := NewSubscriptionDelayer(subscription) + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + start := time.Now() + + var wg sync.WaitGroup + wg.Add(2) + + go func() { + defer wg.Done() + msg := sd.SubscribeToEvents(ctx) + require.Equal(t, PendingTxs, msg) + require.True(t, time.Since(start) > time.Millisecond*20) + }() + + go func() { + defer wg.Done() + time.Sleep(time.Millisecond * 10) + msgs <- PendingTxs + }() + + sd.Absorb(ctx) + require.True(t, time.Since(start) > time.Millisecond*10) + time.Sleep(time.Millisecond * 10) + sd.Release() + + wg.Wait() + + go func() { + time.Sleep(time.Millisecond * 10) + sd.SetAbsorbedMsg(StateSyncDone) + sd.Absorb(ctx) + sd.Release() + }() + + msg := sd.SubscribeToEvents(ctx) + require.Equal(t, StateSyncDone, msg) +} diff --git a/snow/engine/common/vm.go b/snow/engine/common/vm.go index 65cbfb158656..5c89027c6015 100644 --- a/snow/engine/common/vm.go +++ b/snow/engine/common/vm.go @@ -51,7 +51,6 @@ type VM interface { genesisBytes []byte, upgradeBytes []byte, configBytes []byte, - toEngine chan<- Message, fxs []*Fx, appSender AppSender, ) error @@ -77,4 +76,7 @@ type VM interface { // it have an extension called `accounts`, where clients could get // information about their accounts. CreateHandlers(context.Context) (map[string]http.Handler, error) + + // SubscribeToEvents blocks until either the given context is cancelled, or a message is returned. + SubscribeToEvents(ctx context.Context) Message } diff --git a/snow/engine/enginetest/vm.go b/snow/engine/enginetest/vm.go index f3c430e58404..eac33420cdc2 100644 --- a/snow/engine/enginetest/vm.go +++ b/snow/engine/enginetest/vm.go @@ -45,18 +45,26 @@ type VM struct { CantHealthCheck, CantConnected, CantDisconnected, CantVersion, CantAppRequest, CantAppResponse, CantAppGossip, CantAppRequestFailed bool - InitializeF func(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes []byte, upgradeBytes []byte, configBytes []byte, msgChan chan<- common.Message, fxs []*common.Fx, appSender common.AppSender) error - SetStateF func(ctx context.Context, state snow.State) error - ShutdownF func(context.Context) error - CreateHandlersF func(context.Context) (map[string]http.Handler, error) - ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error - DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error - HealthCheckF func(context.Context) (interface{}, error) - AppRequestF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error - AppResponseF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error - AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error - AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error - VersionF func(context.Context) (string, error) + SubscribeToEventsF func(ctx context.Context) common.Message + InitializeF func(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes []byte, upgradeBytes []byte, configBytes []byte, fxs []*common.Fx, appSender common.AppSender) error + SetStateF func(ctx context.Context, state snow.State) error + ShutdownF func(context.Context) error + CreateHandlersF func(context.Context) (map[string]http.Handler, error) + ConnectedF func(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error + DisconnectedF func(ctx context.Context, nodeID ids.NodeID) error + HealthCheckF func(context.Context) (interface{}, error) + AppRequestF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) error + AppResponseF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error + AppGossipF func(ctx context.Context, nodeID ids.NodeID, msg []byte) error + AppRequestFailedF func(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error + VersionF func(context.Context) (string, error) +} + +func (vm *VM) SubscribeToEvents(ctx context.Context) common.Message { + if vm.SubscribeToEventsF != nil { + return vm.SubscribeToEventsF(ctx) + } + return 0 } func (vm *VM) Default(cant bool) { @@ -81,7 +89,6 @@ func (vm *VM) Initialize( genesisBytes, upgradeBytes, configBytes []byte, - msgChan chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -93,7 +100,6 @@ func (vm *VM) Initialize( genesisBytes, upgradeBytes, configBytes, - msgChan, fxs, appSender, ) diff --git a/snow/engine/snowman/block/blockmock/chain_vm.go b/snow/engine/snowman/block/blockmock/chain_vm.go index 051287561454..3c4758018247 100644 --- a/snow/engine/snowman/block/blockmock/chain_vm.go +++ b/snow/engine/snowman/block/blockmock/chain_vm.go @@ -28,7 +28,6 @@ import ( type ChainVM struct { ctrl *gomock.Controller recorder *ChainVMMockRecorder - isgomock struct{} } // ChainVMMockRecorder is the mock recorder for ChainVM. @@ -49,59 +48,59 @@ func (m *ChainVM) EXPECT() *ChainVMMockRecorder { } // AppGossip mocks base method. -func (m *ChainVM) AppGossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error { +func (m *ChainVM) AppGossip(arg0 context.Context, arg1 ids.NodeID, arg2 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppGossip", ctx, nodeID, msg) + ret := m.ctrl.Call(m, "AppGossip", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // AppGossip indicates an expected call of AppGossip. -func (mr *ChainVMMockRecorder) AppGossip(ctx, nodeID, msg any) *gomock.Call { +func (mr *ChainVMMockRecorder) AppGossip(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*ChainVM)(nil).AppGossip), ctx, nodeID, msg) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppGossip", reflect.TypeOf((*ChainVM)(nil).AppGossip), arg0, arg1, arg2) } // AppRequest mocks base method. -func (m *ChainVM) AppRequest(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error { +func (m *ChainVM) AppRequest(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 time.Time, arg4 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequest", ctx, nodeID, requestID, deadline, request) + ret := m.ctrl.Call(m, "AppRequest", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(error) return ret0 } // AppRequest indicates an expected call of AppRequest. -func (mr *ChainVMMockRecorder) AppRequest(ctx, nodeID, requestID, deadline, request any) *gomock.Call { +func (mr *ChainVMMockRecorder) AppRequest(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*ChainVM)(nil).AppRequest), ctx, nodeID, requestID, deadline, request) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequest", reflect.TypeOf((*ChainVM)(nil).AppRequest), arg0, arg1, arg2, arg3, arg4) } // AppRequestFailed mocks base method. -func (m *ChainVM) AppRequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *common.AppError) error { +func (m *ChainVM) AppRequestFailed(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 *common.AppError) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppRequestFailed", ctx, nodeID, requestID, appErr) + ret := m.ctrl.Call(m, "AppRequestFailed", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppRequestFailed indicates an expected call of AppRequestFailed. -func (mr *ChainVMMockRecorder) AppRequestFailed(ctx, nodeID, requestID, appErr any) *gomock.Call { +func (mr *ChainVMMockRecorder) AppRequestFailed(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*ChainVM)(nil).AppRequestFailed), ctx, nodeID, requestID, appErr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppRequestFailed", reflect.TypeOf((*ChainVM)(nil).AppRequestFailed), arg0, arg1, arg2, arg3) } // AppResponse mocks base method. -func (m *ChainVM) AppResponse(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error { +func (m *ChainVM) AppResponse(arg0 context.Context, arg1 ids.NodeID, arg2 uint32, arg3 []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AppResponse", ctx, nodeID, requestID, response) + ret := m.ctrl.Call(m, "AppResponse", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // AppResponse indicates an expected call of AppResponse. -func (mr *ChainVMMockRecorder) AppResponse(ctx, nodeID, requestID, response any) *gomock.Call { +func (mr *ChainVMMockRecorder) AppResponse(arg0, arg1, arg2, arg3 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*ChainVM)(nil).AppResponse), ctx, nodeID, requestID, response) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AppResponse", reflect.TypeOf((*ChainVM)(nil).AppResponse), arg0, arg1, arg2, arg3) } // BuildBlock mocks base method. @@ -120,17 +119,17 @@ func (mr *ChainVMMockRecorder) BuildBlock(arg0 any) *gomock.Call { } // Connected mocks base method. -func (m *ChainVM) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *version.Application) error { +func (m *ChainVM) Connected(arg0 context.Context, arg1 ids.NodeID, arg2 *version.Application) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Connected", ctx, nodeID, nodeVersion) + ret := m.ctrl.Call(m, "Connected", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // Connected indicates an expected call of Connected. -func (mr *ChainVMMockRecorder) Connected(ctx, nodeID, nodeVersion any) *gomock.Call { +func (mr *ChainVMMockRecorder) Connected(arg0, arg1, arg2 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*ChainVM)(nil).Connected), ctx, nodeID, nodeVersion) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*ChainVM)(nil).Connected), arg0, arg1, arg2) } // CreateHandlers mocks base method. @@ -149,47 +148,47 @@ func (mr *ChainVMMockRecorder) CreateHandlers(arg0 any) *gomock.Call { } // Disconnected mocks base method. -func (m *ChainVM) Disconnected(ctx context.Context, nodeID ids.NodeID) error { +func (m *ChainVM) Disconnected(arg0 context.Context, arg1 ids.NodeID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Disconnected", ctx, nodeID) + ret := m.ctrl.Call(m, "Disconnected", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // Disconnected indicates an expected call of Disconnected. -func (mr *ChainVMMockRecorder) Disconnected(ctx, nodeID any) *gomock.Call { +func (mr *ChainVMMockRecorder) Disconnected(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*ChainVM)(nil).Disconnected), ctx, nodeID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnected", reflect.TypeOf((*ChainVM)(nil).Disconnected), arg0, arg1) } // GetBlock mocks base method. -func (m *ChainVM) GetBlock(ctx context.Context, blkID ids.ID) (snowman.Block, error) { +func (m *ChainVM) GetBlock(arg0 context.Context, arg1 ids.ID) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlock", ctx, blkID) + ret := m.ctrl.Call(m, "GetBlock", arg0, arg1) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlock indicates an expected call of GetBlock. -func (mr *ChainVMMockRecorder) GetBlock(ctx, blkID any) *gomock.Call { +func (mr *ChainVMMockRecorder) GetBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*ChainVM)(nil).GetBlock), ctx, blkID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*ChainVM)(nil).GetBlock), arg0, arg1) } // GetBlockIDAtHeight mocks base method. -func (m *ChainVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error) { +func (m *ChainVM) GetBlockIDAtHeight(arg0 context.Context, arg1 uint64) (ids.ID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockIDAtHeight", ctx, height) + ret := m.ctrl.Call(m, "GetBlockIDAtHeight", arg0, arg1) ret0, _ := ret[0].(ids.ID) ret1, _ := ret[1].(error) return ret0, ret1 } // GetBlockIDAtHeight indicates an expected call of GetBlockIDAtHeight. -func (mr *ChainVMMockRecorder) GetBlockIDAtHeight(ctx, height any) *gomock.Call { +func (mr *ChainVMMockRecorder) GetBlockIDAtHeight(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*ChainVM)(nil).GetBlockIDAtHeight), ctx, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockIDAtHeight", reflect.TypeOf((*ChainVM)(nil).GetBlockIDAtHeight), arg0, arg1) } // HealthCheck mocks base method. @@ -208,17 +207,17 @@ func (mr *ChainVMMockRecorder) HealthCheck(arg0 any) *gomock.Call { } // Initialize mocks base method. -func (m *ChainVM) Initialize(ctx context.Context, chainCtx *snow.Context, db database.Database, genesisBytes, upgradeBytes, configBytes []byte, toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender) error { +func (m *ChainVM) Initialize(arg0 context.Context, arg1 *snow.Context, arg2 database.Database, arg3, arg4, arg5 []byte, arg6 []*common.Fx, arg7 common.AppSender) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Initialize", ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender) + ret := m.ctrl.Call(m, "Initialize", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) ret0, _ := ret[0].(error) return ret0 } // Initialize indicates an expected call of Initialize. -func (mr *ChainVMMockRecorder) Initialize(ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender any) *gomock.Call { +func (mr *ChainVMMockRecorder) Initialize(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*ChainVM)(nil).Initialize), ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Initialize", reflect.TypeOf((*ChainVM)(nil).Initialize), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } // LastAccepted mocks base method. @@ -237,46 +236,46 @@ func (mr *ChainVMMockRecorder) LastAccepted(arg0 any) *gomock.Call { } // ParseBlock mocks base method. -func (m *ChainVM) ParseBlock(ctx context.Context, blockBytes []byte) (snowman.Block, error) { +func (m *ChainVM) ParseBlock(arg0 context.Context, arg1 []byte) (snowman.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ParseBlock", ctx, blockBytes) + ret := m.ctrl.Call(m, "ParseBlock", arg0, arg1) ret0, _ := ret[0].(snowman.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // ParseBlock indicates an expected call of ParseBlock. -func (mr *ChainVMMockRecorder) ParseBlock(ctx, blockBytes any) *gomock.Call { +func (mr *ChainVMMockRecorder) ParseBlock(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*ChainVM)(nil).ParseBlock), ctx, blockBytes) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParseBlock", reflect.TypeOf((*ChainVM)(nil).ParseBlock), arg0, arg1) } // SetPreference mocks base method. -func (m *ChainVM) SetPreference(ctx context.Context, blkID ids.ID) error { +func (m *ChainVM) SetPreference(arg0 context.Context, arg1 ids.ID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetPreference", ctx, blkID) + ret := m.ctrl.Call(m, "SetPreference", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // SetPreference indicates an expected call of SetPreference. -func (mr *ChainVMMockRecorder) SetPreference(ctx, blkID any) *gomock.Call { +func (mr *ChainVMMockRecorder) SetPreference(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*ChainVM)(nil).SetPreference), ctx, blkID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPreference", reflect.TypeOf((*ChainVM)(nil).SetPreference), arg0, arg1) } // SetState mocks base method. -func (m *ChainVM) SetState(ctx context.Context, state snow.State) error { +func (m *ChainVM) SetState(arg0 context.Context, arg1 snow.State) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SetState", ctx, state) + ret := m.ctrl.Call(m, "SetState", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } // SetState indicates an expected call of SetState. -func (mr *ChainVMMockRecorder) SetState(ctx, state any) *gomock.Call { +func (mr *ChainVMMockRecorder) SetState(arg0, arg1 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*ChainVM)(nil).SetState), ctx, state) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetState", reflect.TypeOf((*ChainVM)(nil).SetState), arg0, arg1) } // Shutdown mocks base method. @@ -293,6 +292,20 @@ func (mr *ChainVMMockRecorder) Shutdown(arg0 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Shutdown", reflect.TypeOf((*ChainVM)(nil).Shutdown), arg0) } +// SubscribeToEvents mocks base method. +func (m *ChainVM) SubscribeToEvents(arg0 context.Context) common.Message { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubscribeToEvents", arg0) + ret0, _ := ret[0].(common.Message) + return ret0 +} + +// SubscribeToEvents indicates an expected call of SubscribeToEvents. +func (mr *ChainVMMockRecorder) SubscribeToEvents(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToEvents", reflect.TypeOf((*ChainVM)(nil).SubscribeToEvents), arg0) +} + // Version mocks base method. func (m *ChainVM) Version(arg0 context.Context) (string, error) { m.ctrl.T.Helper() diff --git a/snow/engine/snowman/bootstrap/bootstrapper.go b/snow/engine/snowman/bootstrap/bootstrapper.go index bf178cd1f8da..0405c4183e50 100644 --- a/snow/engine/snowman/bootstrap/bootstrapper.go +++ b/snow/engine/snowman/bootstrap/bootstrapper.go @@ -69,6 +69,8 @@ var ( type Bootstrapper struct { Config + nf *common.NotificationForwarder + *metrics TimeoutRegistrar common.TimeoutRegistrar // list of NoOpsHandler for messages dropped by bootstrapper @@ -149,6 +151,11 @@ func New(config Config, onFinished func(ctx context.Context, lastReqID uint32) e } } bs.TimeoutRegistrar = common.NewTimeoutScheduler(timeout, config.BootstrapTracker.AllBootstrapped()) + bs.nf = &common.NotificationForwarder{ + Subscribe: bs.VM.SubscribeToEvents, + Log: bs.Config.Ctx.Log, + Notifier: bs, + } return bs, err } @@ -165,6 +172,7 @@ func (b *Bootstrapper) Clear(context.Context) error { } func (b *Bootstrapper) Start(ctx context.Context, startReqID uint32) error { + b.nf.Start() b.Ctx.State.Set(snow.EngineState{ Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, State: snow.Bootstrapping, @@ -718,6 +726,7 @@ func (b *Bootstrapper) tryStartExecuting(ctx context.Context) error { b.TimeoutRegistrar.RegisterTimeout(bootstrappingDelay) return nil } + b.nf.Close() return b.onFinished(ctx, b.requestID) } @@ -742,6 +751,7 @@ func (b *Bootstrapper) Timeout() error { if !b.Config.BootstrapTracker.IsBootstrapped() { return b.restartBootstrapping(context.TODO()) } + b.nf.Close() return b.onFinished(context.TODO(), b.requestID) } @@ -779,6 +789,7 @@ func (b *Bootstrapper) HealthCheck(ctx context.Context) (interface{}, error) { func (b *Bootstrapper) Shutdown(ctx context.Context) error { b.Ctx.Log.Info("shutting down bootstrapper") + b.nf.Close() b.Ctx.Lock.Lock() defer b.Ctx.Lock.Unlock() diff --git a/snow/engine/snowman/engine.go b/snow/engine/snowman/engine.go index 7771f3c50bf7..3cfa394f273e 100644 --- a/snow/engine/snowman/engine.go +++ b/snow/engine/snowman/engine.go @@ -48,6 +48,8 @@ type Engine struct { Config *metrics + nf *common.NotificationForwarder + // list of NoOpsHandler for messages dropped by engine common.StateSummaryFrontierHandler common.AcceptedStateSummaryHandler @@ -133,7 +135,7 @@ func New(config Config) (*Engine, error) { return nil, err } - return &Engine{ + engine := &Engine{ Config: config, metrics: metrics, StateSummaryFrontierHandler: common.NewNoOpStateSummaryFrontierHandler(config.Ctx.Log), @@ -151,7 +153,15 @@ func New(config Config) (*Engine, error) { polls: polls, blkReqs: bimap.New[common.Request, ids.ID](), blkReqSourceMetric: make(map[common.Request]prometheus.Counter), - }, nil + } + + engine.nf = &common.NotificationForwarder{ + Log: config.Ctx.Log, + Subscribe: config.VM.SubscribeToEvents, + Notifier: engine, + } + + return engine, nil } func (e *Engine) Gossip(ctx context.Context) error { @@ -438,10 +448,15 @@ func (e *Engine) Shutdown(ctx context.Context) error { e.Ctx.Lock.Lock() defer e.Ctx.Lock.Unlock() + e.nf.Close() + return e.VM.Shutdown(ctx) } func (e *Engine) Notify(ctx context.Context, msg common.Message) error { + e.Ctx.Lock.Lock() + defer e.Ctx.Lock.Unlock() + switch msg { case common.PendingTxs: // the pending txs message means we should attempt to build a block. @@ -463,6 +478,8 @@ func (e *Engine) Context() *snow.ConsensusContext { } func (e *Engine) Start(ctx context.Context, startReqID uint32) error { + e.nf.Start() + e.requestID = startReqID lastAcceptedID, err := e.VM.LastAccepted(ctx) if err != nil { diff --git a/snow/engine/snowman/engine_test.go b/snow/engine/snowman/engine_test.go index c9a3cbc0d5f3..ae926da44cce 100644 --- a/snow/engine/snowman/engine_test.go +++ b/snow/engine/snowman/engine_test.go @@ -2418,7 +2418,6 @@ func TestEngineVoteStallRegression(t *testing.T) { []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { @@ -2643,7 +2642,6 @@ func TestEngineEarlyTerminateVoterRegression(t *testing.T) { []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { @@ -2794,7 +2792,6 @@ func TestEngineRegistersInvalidVoterDependencyRegression(t *testing.T) { []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { diff --git a/snow/engine/snowman/syncer/state_syncer.go b/snow/engine/snowman/syncer/state_syncer.go index 7e669fee2534..f41ec9181068 100644 --- a/snow/engine/snowman/syncer/state_syncer.go +++ b/snow/engine/snowman/syncer/state_syncer.go @@ -39,6 +39,8 @@ type weightedSummary struct { type stateSyncer struct { Config + nf *common.NotificationForwarder + // list of NoOpsHandler for messages dropped by state syncer common.AcceptedFrontierHandler common.AcceptedHandler @@ -95,7 +97,7 @@ func New( onDoneStateSyncing func(ctx context.Context, lastReqID uint32) error, ) common.StateSyncer { ssVM, _ := cfg.VM.(block.StateSyncableVM) - return &stateSyncer{ + ss := &stateSyncer{ Config: cfg, AcceptedFrontierHandler: common.NewNoOpAcceptedFrontierHandler(cfg.Ctx.Log), AcceptedHandler: common.NewNoOpAcceptedHandler(cfg.Ctx.Log), @@ -107,11 +109,21 @@ func New( stateSyncVM: ssVM, onDoneStateSyncing: onDoneStateSyncing, } + + ss.nf = &common.NotificationForwarder{ + Subscribe: cfg.VM.SubscribeToEvents, + Notifier: ss, + Log: cfg.Ctx.Log, + } + + return ss } func (ss *stateSyncer) Start(ctx context.Context, startReqID uint32) error { ss.Ctx.Log.Info("starting state sync") + ss.nf.Start() + ss.Ctx.State.Set(snow.EngineState{ Type: p2p.EngineType_ENGINE_TYPE_SNOWMAN, State: snow.StateSyncing, diff --git a/snow/networking/handler/handler.go b/snow/networking/handler/handler.go index d25d6b8a1493..3bd17985dedf 100644 --- a/snow/networking/handler/handler.go +++ b/snow/networking/handler/handler.go @@ -88,7 +88,6 @@ type handler struct { // since peerTracker is already tracking validators validators validators.Manager // Receives messages from the VM - msgFromVMChan <-chan common.Message gossipFrequency time.Duration engineManager *EngineManager @@ -129,7 +128,6 @@ type handler struct { func New( ctx *snow.ConsensusContext, validators validators.Manager, - msgFromVMChan <-chan common.Message, gossipFrequency time.Duration, threadPoolSize int, resourceTracker tracker.ResourceTracker, @@ -143,7 +141,6 @@ func New( haltBootstrapping: haltBootstrapping, ctx: ctx, validators: validators, - msgFromVMChan: msgFromVMChan, gossipFrequency: gossipFrequency, closingChan: make(chan struct{}), closed: make(chan struct{}), @@ -214,6 +211,9 @@ func (h *handler) selectStartingGear(ctx context.Context) (common.Engine, error) return nil, errNoStartingGear } if engines.StateSyncer == nil { + if engines.Bootstrapper == nil { + return engines.Consensus, nil + } return engines.Bootstrapper, nil } @@ -384,6 +384,9 @@ func (h *handler) dispatchChans(ctx context.Context) { h.closeDispatcher(ctx) }() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + // Handle messages generated by the handler and the VM for { var msg message.InboundMessage @@ -391,9 +394,6 @@ func (h *handler) dispatchChans(ctx context.Context) { case <-h.closingChan: return - case vmMSG := <-h.msgFromVMChan: - msg = message.InternalVMMessage(h.ctx.NodeID, uint32(vmMSG)) - case <-gossiper.C: msg = message.InternalGossipRequest(h.ctx.NodeID) } @@ -474,7 +474,7 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { // The peer is requesting an engine type that hasn't been initialized // yet. This means we know that this isn't a response, so we can safely // drop the message. - h.ctx.Log.Debug("dropping sync message", + h.ctx.Log.Warn("dropping sync message", zap.String("reason", "uninitialized engine type"), zap.String("messageOp", op), zap.Stringer("currentEngineType", currentState.Type), @@ -504,7 +504,7 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { // This should only happen if the peer is not following the protocol. // This can happen if the chain only has a Snowman engine and the peer // requested an Avalanche engine handle the message. - h.ctx.Log.Debug("dropping sync message", + h.ctx.Log.Warn("dropping sync message", zap.String("reason", "uninitialized engine state"), zap.String("messageOp", op), zap.Stringer("currentEngineType", currentState.Type), @@ -631,6 +631,8 @@ func (h *handler) handleSyncMsg(ctx context.Context, msg Message) error { case *p2ppb.Ancestors: return engine.Ancestors(ctx, nodeID, msg.RequestId, msg.Containers) + case *p2ppb.SimplexMessage: + return engine.(common.SimplexHandler).SimplexMessage(nodeID, msg) case *p2ppb.Get: containerID, err := ids.ToID(msg.ContainerId) @@ -901,10 +903,7 @@ func (h *handler) handleChanMsg(msg message.InboundMessage) error { ) } - switch msg := body.(type) { - case *message.VMMessage: - return engine.Notify(context.TODO(), common.Message(msg.Notification)) - + switch body.(type) { case *message.GossipRequest: return engine.Gossip(context.TODO()) diff --git a/snow/networking/handler/handler_test.go b/snow/networking/handler/handler_test.go index 39947a0c9503..ba8f5cc828c7 100644 --- a/snow/networking/handler/handler_test.go +++ b/snow/networking/handler/handler_test.go @@ -6,7 +6,6 @@ package handler import ( "context" "errors" - "sync" "testing" "time" @@ -69,7 +68,6 @@ func TestHandlerDropsTimedOutMessages(t *testing.T) { handlerIntf, err := New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -176,7 +174,6 @@ func TestHandlerClosesOnError(t *testing.T) { handlerIntf, err := New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -279,7 +276,6 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { handlerIntf, err := New( ctx, vdrs, - nil, 1, testThreadPoolSize, resourceTracker, @@ -340,89 +336,6 @@ func TestHandlerDropsGossipDuringBootstrapping(t *testing.T) { } } -// Test that messages from the VM are handled -func TestHandlerDispatchInternal(t *testing.T) { - require := require.New(t) - - snowCtx := snowtest.Context(t, snowtest.CChainID) - ctx := snowtest.ConsensusContext(snowCtx) - msgFromVMChan := make(chan common.Message) - vdrs := validators.NewManager() - require.NoError(vdrs.AddStaker(ctx.SubnetID, ids.GenerateTestNodeID(), nil, ids.Empty, 1)) - - resourceTracker, err := tracker.NewResourceTracker( - prometheus.NewRegistry(), - resource.NoUsage, - meter.ContinuousFactory{}, - time.Second, - ) - require.NoError(err) - - peerTracker, err := p2p.NewPeerTracker( - logging.NoLog{}, - "", - prometheus.NewRegistry(), - nil, - version.CurrentApp, - ) - require.NoError(err) - - handler, err := New( - ctx, - vdrs, - msgFromVMChan, - time.Second, - testThreadPoolSize, - resourceTracker, - subnets.New(ctx.NodeID, subnets.Config{}), - commontracker.NewPeers(), - peerTracker, - prometheus.NewRegistry(), - func() {}, - ) - require.NoError(err) - - bootstrapper := &enginetest.Bootstrapper{ - Engine: enginetest.Engine{ - T: t, - }, - } - bootstrapper.Default(false) - - engine := &enginetest.Engine{T: t} - engine.Default(false) - engine.ContextF = func() *snow.ConsensusContext { - return ctx - } - - wg := &sync.WaitGroup{} - engine.NotifyF = func(context.Context, common.Message) error { - wg.Done() - return nil - } - - handler.SetEngineManager(&EngineManager{ - Snowman: &Engine{ - Bootstrapper: bootstrapper, - Consensus: engine, - }, - }) - - ctx.State.Set(snow.EngineState{ - Type: p2ppb.EngineType_ENGINE_TYPE_SNOWMAN, - State: snow.NormalOp, // assumed bootstrap is done - }) - - bootstrapper.StartF = func(context.Context, uint32) error { - return nil - } - - wg.Add(1) - handler.Start(context.Background(), false) - msgFromVMChan <- 0 - wg.Wait() -} - // Tests that messages are routed to the correct engine type func TestDynamicEngineTypeDispatch(t *testing.T) { tests := []struct { @@ -546,7 +459,6 @@ func TestDynamicEngineTypeDispatch(t *testing.T) { handler, err := New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -629,7 +541,6 @@ func TestHandlerStartError(t *testing.T) { handler, err := New( ctx, validators.NewManager(), - nil, time.Second, testThreadPoolSize, resourceTracker, diff --git a/snow/networking/handler/health_test.go b/snow/networking/handler/health_test.go index 4e7e5732b8de..99ec89e012b8 100644 --- a/snow/networking/handler/health_test.go +++ b/snow/networking/handler/health_test.go @@ -85,7 +85,6 @@ func TestHealthCheckSubnet(t *testing.T) { handlerIntf, err := New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, diff --git a/snow/networking/router/chain_router.go b/snow/networking/router/chain_router.go index 3893d2aeeb94..057b21e99bb1 100644 --- a/snow/networking/router/chain_router.go +++ b/snow/networking/router/chain_router.go @@ -207,10 +207,15 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes nodeID := msg.NodeID() op := msg.Op() + if op == message.Simplex { + cr.log.Info("we got a simplex message", + zap.Stringer("op", msg.Op())) + } + m := msg.Message() chainID, err := message.GetChainID(m) if err != nil { - cr.log.Debug("dropping message with invalid field", + cr.log.Warn("dropping message with invalid field", zap.Stringer("nodeID", nodeID), zap.Stringer("messageOp", op), zap.String("field", "ChainID"), @@ -222,14 +227,17 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes } requestID, ok := message.GetRequestID(m) - if !ok { - cr.log.Debug("dropping message with invalid field", + if !ok && msg.Op() != message.Simplex { + cr.log.Warn("dropping message with invalid field", zap.Stringer("nodeID", nodeID), zap.Stringer("messageOp", op), zap.String("field", "RequestID"), ) msg.OnFinishedHandling() + if op == message.Simplex { + cr.log.Warn("1111111111") + } return } @@ -250,7 +258,7 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes // Get the chain, if it exists chain, exists := cr.chainHandlers[chainID] if !exists { - cr.log.Debug("dropping message", + cr.log.Warn("dropping message", zap.Stringer("messageOp", op), zap.Stringer("nodeID", nodeID), zap.Stringer("chainID", chainID), @@ -261,7 +269,7 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes } if !chain.ShouldHandle(nodeID) { - cr.log.Debug("dropping message", + cr.log.Warn("dropping message", zap.Stringer("messageOp", op), zap.Stringer("nodeID", nodeID), zap.Stringer("chainID", chainID), @@ -274,7 +282,7 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes chainCtx := chain.Context() if message.UnrequestedOps.Contains(op) { if chainCtx.Executing.Get() { - cr.log.Debug("dropping message and skipping queue", + cr.log.Warn("dropping message and skipping queue", zap.String("reason", "the chain is currently executing"), zap.Stringer("messageOp", op), ) @@ -297,10 +305,11 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes } if expectedResponse, isFailed := message.FailedToResponseOps[op]; isFailed { + // Create the request ID of the request we sent that this message is in // response to. uniqueRequestID, req := cr.clearRequest(expectedResponse, nodeID, chainID, requestID) - if req == nil { + if req == nil && op != message.Simplex { // This was a duplicated response. msg.OnFinishedHandling() return @@ -317,11 +326,12 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes EngineType: req.engineType, }, ) + return } if chainCtx.Executing.Get() { - cr.log.Debug("dropping message and skipping queue", + cr.log.Warn("dropping message and skipping queue", zap.String("reason", "the chain is currently executing"), zap.Stringer("messageOp", op), ) @@ -331,24 +341,34 @@ func (cr *ChainRouter) HandleInbound(ctx context.Context, msg message.InboundMes } uniqueRequestID, req := cr.clearRequest(op, nodeID, chainID, requestID) - if req == nil { + if req == nil && op != message.Simplex { // We didn't request this message. msg.OnFinishedHandling() return } - // Calculate how long it took [nodeID] to reply - latency := cr.clock.Time().Sub(req.time) + var engineType p2p.EngineType + + if req != nil { + // Calculate how long it took [nodeID] to reply + latency := cr.clock.Time().Sub(req.time) + + // Tell the timeout manager we got a response + cr.timeoutManager.RegisterResponse(nodeID, chainID, uniqueRequestID, req.op, latency) - // Tell the timeout manager we got a response - cr.timeoutManager.RegisterResponse(nodeID, chainID, uniqueRequestID, req.op, latency) + engineType = req.engineType + } + + if op == message.Simplex { + engineType = p2p.EngineType_ENGINE_TYPE_UNSPECIFIED + } // Pass the response to the chain chain.Push( ctx, handler.Message{ InboundMessage: msg, - EngineType: req.engineType, + EngineType: engineType, }, ) } diff --git a/snow/networking/router/chain_router_test.go b/snow/networking/router/chain_router_test.go index 149be6dc7b52..b220ed9412c5 100644 --- a/snow/networking/router/chain_router_test.go +++ b/snow/networking/router/chain_router_test.go @@ -106,7 +106,6 @@ func TestShutdown(t *testing.T) { h, err := handler.New( chainCtx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -232,7 +231,6 @@ func TestConnectedAfterShutdownErrorLogRegression(t *testing.T) { h, err := handler.New( chainCtx, nil, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -365,7 +363,6 @@ func TestShutdownTimesOut(t *testing.T) { h, err := handler.New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -534,7 +531,6 @@ func TestRouterTimeout(t *testing.T) { h, err := handler.New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -1066,7 +1062,6 @@ func TestValidatorOnlyMessageDrops(t *testing.T) { h, err := handler.New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -1232,7 +1227,6 @@ func TestValidatorOnlyAllowedNodeMessageDrops(t *testing.T) { h, err := handler.New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, @@ -1484,7 +1478,6 @@ func newChainRouterTest(t *testing.T) (*ChainRouter, *enginetest.Engine) { h, err := handler.New( ctx, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, diff --git a/snow/networking/sender/sender_test.go b/snow/networking/sender/sender_test.go index 1f7469575690..1f6d67cdacb2 100644 --- a/snow/networking/sender/sender_test.go +++ b/snow/networking/sender/sender_test.go @@ -132,7 +132,6 @@ func TestTimeout(t *testing.T) { h, err := handler.New( ctx2, vdrs, - nil, time.Hour, testThreadPoolSize, resourceTracker, @@ -391,7 +390,6 @@ func TestReliableMessages(t *testing.T) { h, err := handler.New( ctx2, vdrs, - nil, 1, testThreadPoolSize, resourceTracker, @@ -548,7 +546,6 @@ func TestReliableMessagesToMyself(t *testing.T) { h, err := handler.New( ctx2, vdrs, - nil, time.Second, testThreadPoolSize, resourceTracker, diff --git a/subnets/config.go b/subnets/config.go index 5674473f9a5e..c640b81afffb 100644 --- a/subnets/config.go +++ b/subnets/config.go @@ -6,6 +6,7 @@ package subnets import ( "errors" "fmt" + "github.com/ava-labs/avalanchego/utils/logging" "time" "github.com/ava-labs/avalanchego/ids" @@ -16,6 +17,7 @@ import ( var errAllowedNodesWhenNotValidatorOnly = errors.New("allowedNodes can only be set when ValidatorOnly is true") type Config struct { + Logger logging.Logger // ValidatorOnly indicates that this Subnet's Chains are available to only subnet validators. // No chain related messages will go out to non-validators. // Validators will drop messages received from non-validators. diff --git a/tests/fixture/tmpnet/defaults.go b/tests/fixture/tmpnet/defaults.go index 02537b8dd6f3..b1a7f5355530 100644 --- a/tests/fixture/tmpnet/defaults.go +++ b/tests/fixture/tmpnet/defaults.go @@ -24,7 +24,7 @@ const ( DefaultNetworkTimeout = 2 * time.Minute // Minimum required to ensure connectivity-based health checks will pass - DefaultNodeCount = 2 + DefaultNodeCount = 4 // Arbitrary number of pre-funded keys to create by default DefaultPreFundedKeyCount = 50 @@ -57,7 +57,7 @@ func DefaultTmpnetFlags() FlagsMap { config.PublicIPKey: "127.0.0.1", config.HTTPHostKey: "127.0.0.1", config.StakingHostKey: "127.0.0.1", - config.LogDisplayLevelKey: logging.Off.String(), // Display logging not needed since nodes run headless + config.LogDisplayLevelKey: logging.Info.String(), // Display logging not needed since nodes run headless config.LogLevelKey: logging.Debug.String(), // Specific to e2e testing config.ProposerVMUseCurrentHeightKey: true, diff --git a/tests/fixture/tmpnet/node_process.go b/tests/fixture/tmpnet/node_process.go index 3a4f3494520a..b7524239f510 100644 --- a/tests/fixture/tmpnet/node_process.go +++ b/tests/fixture/tmpnet/node_process.go @@ -183,6 +183,7 @@ func (p *NodeProcess) IsHealthy(ctx context.Context) (bool, error) { if err != nil { return false, err } + fmt.Println(">>>", healthReply) return healthReply.Healthy, nil } diff --git a/vms/avm/block/builder/builder_test.go b/vms/avm/block/builder/builder_test.go index d86745748488..986e83da92a1 100644 --- a/vms/avm/block/builder/builder_test.go +++ b/vms/avm/block/builder/builder_test.go @@ -20,7 +20,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/crypto/secp256k1" "github.com/ava-labs/avalanchego/utils/logging" @@ -488,8 +487,7 @@ func TestBlockBuilderAddLocalTx(t *testing.T) { require := require.New(t) registerer := prometheus.NewRegistry() - toEngine := make(chan common.Message, 100) - mempool, err := mempool.New("mempool", registerer, toEngine) + mempool, err := mempool.New("mempool", registerer, func() {}) require.NoError(err) // add a tx to the mempool tx := transactions[0] diff --git a/vms/avm/block/executor/block_test.go b/vms/avm/block/executor/block_test.go index 027c12681046..804d19e79a82 100644 --- a/vms/avm/block/executor/block_test.go +++ b/vms/avm/block/executor/block_test.go @@ -847,7 +847,7 @@ func TestBlockReject(t *testing.T) { executionFailsTx, }) - mempool, err := mempool.New("", prometheus.NewRegistry(), nil) + mempool, err := mempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) lastAcceptedID := ids.GenerateTestID() @@ -900,7 +900,7 @@ func TestBlockReject(t *testing.T) { tx2, }) - mempool, err := mempool.New("", prometheus.NewRegistry(), nil) + mempool, err := mempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) lastAcceptedID := ids.GenerateTestID() diff --git a/vms/avm/environment_test.go b/vms/avm/environment_test.go index a967fe3fd42d..3d702cb4ed03 100644 --- a/vms/avm/environment_test.go +++ b/vms/avm/environment_test.go @@ -74,6 +74,7 @@ type environment struct { issuer chan common.Message vm *VM txBuilder *txstest.Builder + close chan struct{} } // setup the testing environment @@ -128,7 +129,6 @@ func setup(tb testing.TB, c *envConfig) *environment { ctx, prefixdb.New([]byte{1}, baseDB), genesisBytes, - nil, configBytes, nil, append( @@ -151,6 +151,7 @@ func setup(tb testing.TB, c *envConfig) *environment { issuer := make(chan common.Message, 1) env := &environment{ + close: make(chan struct{}), genesisBytes: genesisBytes, genesisTx: getCreateTxFromGenesisTest(tb, genesisBytes, assetName), sharedMemory: m, @@ -164,11 +165,21 @@ func setup(tb testing.TB, c *envConfig) *environment { return env } - require.NoError(vm.Linearize(context.Background(), stopVertexID, issuer)) + require.NoError(vm.Linearize(context.Background(), stopVertexID)) if c.notBootstrapped { return env } + go func() { + for { + select { + case <-env.close: + return + case issuer <- vm.SubscribeToEvents(context.Background()): + } + } + }() + require.NoError(vm.SetState(context.Background(), snow.NormalOp)) tb.Cleanup(func() { @@ -176,6 +187,7 @@ func setup(tb testing.TB, c *envConfig) *environment { defer env.vm.ctx.Lock.Unlock() require.NoError(env.vm.Shutdown(context.Background())) + close(env.close) }) return env diff --git a/vms/avm/network/gossip_test.go b/vms/avm/network/gossip_test.go index e84f259cbe37..3f6205a0cdcf 100644 --- a/vms/avm/network/gossip_test.go +++ b/vms/avm/network/gossip_test.go @@ -10,7 +10,6 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/vms/avm/fxs" "github.com/ava-labs/avalanchego/vms/avm/txs" @@ -58,9 +57,8 @@ func TestGossipMempoolAdd(t *testing.T) { require := require.New(t) metrics := prometheus.NewRegistry() - toEngine := make(chan common.Message, 1) - baseMempool, err := mempool.New("", metrics, toEngine) + baseMempool, err := mempool.New("", metrics, func() {}) require.NoError(err) parser, err := txs.NewParser(nil) @@ -95,9 +93,8 @@ func TestGossipMempoolAddVerified(t *testing.T) { require := require.New(t) metrics := prometheus.NewRegistry() - toEngine := make(chan common.Message, 1) - baseMempool, err := mempool.New("", metrics, toEngine) + baseMempool, err := mempool.New("", metrics, func() {}) require.NoError(err) parser, err := txs.NewParser(nil) diff --git a/vms/avm/network/network_test.go b/vms/avm/network/network_test.go index 1e3635d0b68f..7ff3f9e6c00a 100644 --- a/vms/avm/network/network_test.go +++ b/vms/avm/network/network_test.go @@ -181,7 +181,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "happy path", mempool: func() xmempool.Mempool { - mempool, err := xmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := xmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) return mempool }(), @@ -268,7 +268,7 @@ func TestNetworkIssueTxFromRPCWithoutVerification(t *testing.T) { { name: "happy path", mempool: func() xmempool.Mempool { - mempool, err := xmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := xmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) return mempool }(), diff --git a/vms/avm/txs/mempool/mempool.go b/vms/avm/txs/mempool/mempool.go index 5825c883371d..06a07f48fa1c 100644 --- a/vms/avm/txs/mempool/mempool.go +++ b/vms/avm/txs/mempool/mempool.go @@ -6,7 +6,6 @@ package mempool import ( "github.com/prometheus/client_golang/prometheus" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/avm/txs" txmempool "github.com/ava-labs/avalanchego/vms/txs/mempool" @@ -26,13 +25,13 @@ type Mempool interface { type mempool struct { txmempool.Mempool[*txs.Tx] - toEngine chan<- common.Message + notify func() } func New( namespace string, registerer prometheus.Registerer, - toEngine chan<- common.Message, + notify func(), ) (Mempool, error) { metrics, err := txmempool.NewMetrics(namespace, registerer) if err != nil { @@ -42,8 +41,8 @@ func New( metrics, ) return &mempool{ - Mempool: pool, - toEngine: toEngine, + Mempool: pool, + notify: notify, }, nil } @@ -52,8 +51,5 @@ func (m *mempool) RequestBuildBlock() { return } - select { - case m.toEngine <- common.PendingTxs: - default: - } + m.notify() } diff --git a/vms/avm/txs/mempool/mempool_test.go b/vms/avm/txs/mempool/mempool_test.go index 1979378267b5..02890d08c30e 100644 --- a/vms/avm/txs/mempool/mempool_test.go +++ b/vms/avm/txs/mempool/mempool_test.go @@ -10,26 +10,30 @@ import ( "github.com/stretchr/testify/require" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/vms/avm/txs" "github.com/ava-labs/avalanchego/vms/components/avax" ) -func newMempool(toEngine chan<- common.Message) (Mempool, error) { - return New("mempool", prometheus.NewRegistry(), toEngine) +func newMempool(notify func()) (Mempool, error) { + return New("mempool", prometheus.NewRegistry(), notify) } func TestRequestBuildBlock(t *testing.T) { require := require.New(t) - toEngine := make(chan common.Message, 1) - mempool, err := newMempool(toEngine) + notifications := make(chan struct{}, 1) + mempool, err := newMempool(func() { + select { + case notifications <- struct{}{}: + default: + } + }) require.NoError(err) mempool.RequestBuildBlock() select { - case <-toEngine: + case <-notifications: require.FailNow("should not have sent message to engine") default: } @@ -40,12 +44,12 @@ func TestRequestBuildBlock(t *testing.T) { mempool.RequestBuildBlock() mempool.RequestBuildBlock() // Must not deadlock select { - case <-toEngine: + case <-notifications: default: require.FailNow("should have sent message to engine") } select { - case <-toEngine: + case <-notifications: require.FailNow("should have only sent one message to engine") default: } diff --git a/vms/avm/vm.go b/vms/avm/vm.go index 4aa7a55c9aee..ef2bab5f216b 100644 --- a/vms/avm/vm.go +++ b/vms/avm/vm.go @@ -64,6 +64,8 @@ type VM struct { metrics avmmetrics.Metrics + common.Subscriber + avax.AddressManager ids.Aliaser utxo.Spender @@ -150,7 +152,6 @@ func (vm *VM) Initialize( genesisBytes []byte, _ []byte, configBytes []byte, - _ chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -368,13 +369,20 @@ func (vm *VM) GetBlockIDAtHeight(_ context.Context, height uint64) (ids.ID, erro ****************************************************************************** */ -func (vm *VM) Linearize(ctx context.Context, stopVertexID ids.ID, toEngine chan<- common.Message) error { +func (vm *VM) Linearize(ctx context.Context, stopVertexID ids.ID) error { time := vm.Config.Upgrades.CortinaTime if err := vm.state.InitializeChainState(stopVertexID, time); err != nil { return fmt.Errorf("failed to initialize chain state: %w", err) } - mempool, err := xmempool.New("mempool", vm.registerer, toEngine) + ss := common.NewSimpleSubscriber() + vm.Subscriber = ss + + notify := func() { + ss.Publish(common.PendingTxs) + } + + mempool, err := xmempool.New("mempool", vm.registerer, notify) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } diff --git a/vms/avm/vm_test.go b/vms/avm/vm_test.go index 843e69aef493..d443896f0341 100644 --- a/vms/avm/vm_test.go +++ b/vms/avm/vm_test.go @@ -38,14 +38,13 @@ func TestInvalidGenesis(t *testing.T) { err := vm.Initialize( context.Background(), - ctx, // context - memdb.New(), // database - nil, // genesisState - nil, // upgradeBytes - nil, // configBytes - make(chan common.Message, 1), // engineMessenger - nil, // fxs - nil, // AppSender + ctx, // context + memdb.New(), // database + nil, // genesisState + nil, // upgradeBytes + nil, // configBytes + nil, // fxs + nil, // AppSender ) require.ErrorIs(err, codec.ErrCantUnpackVersion) } @@ -64,12 +63,11 @@ func TestInvalidFx(t *testing.T) { genesisBytes := buildGenesisTest(t) err := vm.Initialize( context.Background(), - ctx, // context - memdb.New(), // database - genesisBytes, // genesisState - nil, // upgradeBytes - nil, // configBytes - make(chan common.Message, 1), // engineMessenger + ctx, // context + memdb.New(), // database + genesisBytes, // genesisState + nil, // upgradeBytes + nil, // configBytes []*common.Fx{ // fxs nil, }, @@ -92,12 +90,11 @@ func TestFxInitializationFailure(t *testing.T) { genesisBytes := buildGenesisTest(t) err := vm.Initialize( context.Background(), - ctx, // context - memdb.New(), // database - genesisBytes, // genesisState - nil, // upgradeBytes - nil, // configBytes - make(chan common.Message, 1), // engineMessenger + ctx, // context + memdb.New(), // database + genesisBytes, // genesisState + nil, // upgradeBytes + nil, // configBytes []*common.Fx{{ // fxs ID: ids.Empty, Fx: &FxTest{ diff --git a/vms/example/xsvm/builder/builder.go b/vms/example/xsvm/builder/builder.go index dd9648f8cae2..3398e65f5d8e 100644 --- a/vms/example/xsvm/builder/builder.go +++ b/vms/example/xsvm/builder/builder.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/linked" "github.com/ava-labs/avalanchego/vms/example/xsvm/chain" "github.com/ava-labs/avalanchego/vms/example/xsvm/execute" @@ -32,21 +31,20 @@ type Builder interface { type builder struct { chainContext *snow.Context - engineChan chan<- common.Message chain chain.Chain pendingTxs *linked.Hashmap[ids.ID, *tx.Tx] + notify func() preference ids.ID } -func New(chainContext *snow.Context, engineChan chan<- common.Message, chain chain.Chain) Builder { +func New(chainContext *snow.Context, notify func(), chain chain.Chain) Builder { return &builder{ chainContext: chainContext, - engineChan: engineChan, chain: chain, - - pendingTxs: linked.NewHashmap[ids.ID, *tx.Tx](), - preference: chain.LastAccepted(), + notify: notify, + pendingTxs: linked.NewHashmap[ids.ID, *tx.Tx](), + preference: chain.LastAccepted(), } } @@ -61,10 +59,7 @@ func (b *builder) AddTx(_ context.Context, newTx *tx.Tx) error { return err } b.pendingTxs.Put(txID, newTx) - select { - case b.engineChan <- common.PendingTxs: - default: - } + b.notify() return nil } @@ -83,10 +78,7 @@ func (b *builder) BuildBlock(ctx context.Context, blockContext *smblock.Context) if b.pendingTxs.Len() == 0 { return } - select { - case b.engineChan <- common.PendingTxs: - default: - } + b.notify() }() parentTimestamp := preferredBlk.Timestamp() diff --git a/vms/example/xsvm/vm.go b/vms/example/xsvm/vm.go index 967ee7dd6a03..502562c45ab3 100644 --- a/vms/example/xsvm/vm.go +++ b/vms/example/xsvm/vm.go @@ -44,10 +44,10 @@ type VM struct { chainContext *snow.Context db database.Database genesis *genesis.Genesis - engineChan chan<- common.Message chain chain.Chain builder builder.Builder + *common.SimpleSubscriber } func (vm *VM) Initialize( @@ -57,7 +57,6 @@ func (vm *VM) Initialize( genesisBytes []byte, _ []byte, _ []byte, - engineChan chan<- common.Message, _ []*common.Fx, appSender common.AppSender, ) error { @@ -107,14 +106,17 @@ func (vm *VM) Initialize( } vm.genesis = g - vm.engineChan = engineChan + + vm.SimpleSubscriber = common.NewSimpleSubscriber() vm.chain, err = chain.New(chainContext, vm.db) if err != nil { return fmt.Errorf("failed to initialize chain manager: %w", err) } - vm.builder = builder.New(chainContext, engineChan, vm.chain) + vm.builder = builder.New(chainContext, func() { + vm.SimpleSubscriber.Publish(common.PendingTxs) + }, vm.chain) chainContext.Log.Info("initialized xsvm", zap.Stringer("lastAcceptedID", vm.chain.LastAccepted()), diff --git a/vms/metervm/block_vm.go b/vms/metervm/block_vm.go index da64f9af01d2..39084a168430 100644 --- a/vms/metervm/block_vm.go +++ b/vms/metervm/block_vm.go @@ -58,7 +58,6 @@ func (vm *blockVM) Initialize( genesisBytes, upgradeBytes, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -72,7 +71,7 @@ func (vm *blockVM) Initialize( return err } - return vm.ChainVM.Initialize(ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, toEngine, fxs, appSender) + return vm.ChainVM.Initialize(ctx, chainCtx, db, genesisBytes, upgradeBytes, configBytes, fxs, appSender) } func (vm *blockVM) BuildBlock(ctx context.Context) (snowman.Block, error) { diff --git a/vms/metervm/vertex_vm.go b/vms/metervm/vertex_vm.go index 936a688de99d..74e1ccc1e610 100644 --- a/vms/metervm/vertex_vm.go +++ b/vms/metervm/vertex_vm.go @@ -45,7 +45,6 @@ func (vm *vertexVM) Initialize( genesisBytes, upgradeBytes, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -60,7 +59,6 @@ func (vm *vertexVM) Initialize( genesisBytes, upgradeBytes, configBytes, - toEngine, fxs, appSender, ) diff --git a/vms/platformvm/block/builder/helpers_test.go b/vms/platformvm/block/builder/helpers_test.go index 43b5e0ce2f93..39e9ba4574fd 100644 --- a/vms/platformvm/block/builder/helpers_test.go +++ b/vms/platformvm/block/builder/helpers_test.go @@ -142,7 +142,7 @@ func newEnvironment(t *testing.T, f upgradetest.Fork) *environment { //nolint:un metrics, err := metrics.New(registerer) require.NoError(err) - res.mempool, err = mempool.New("mempool", registerer, nil) + res.mempool, err = mempool.New("mempool", registerer, func() {}) require.NoError(err) res.blkManager = blockexecutor.NewManager( diff --git a/vms/platformvm/block/executor/rejector_test.go b/vms/platformvm/block/executor/rejector_test.go index 70696469d80f..e1329695964e 100644 --- a/vms/platformvm/block/executor/rejector_test.go +++ b/vms/platformvm/block/executor/rejector_test.go @@ -120,7 +120,7 @@ func TestRejectBlock(t *testing.T) { blk, err := tt.newBlockFunc() require.NoError(err) - mempool, err := mempool.New("", prometheus.NewRegistry(), nil) + mempool, err := mempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(err) state := state.NewMockState(ctrl) blkIDToState := map[ids.ID]*blockState{ diff --git a/vms/platformvm/network/gossip_test.go b/vms/platformvm/network/gossip_test.go index cdca67f2a2c0..0429505ebc00 100644 --- a/vms/platformvm/network/gossip_test.go +++ b/vms/platformvm/network/gossip_test.go @@ -91,7 +91,7 @@ func TestGossipAddBloomFilter(t *testing.T) { } txVerifier := testTxVerifier{} - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(err) gossipMempool, err := newGossipMempool( diff --git a/vms/platformvm/network/network_test.go b/vms/platformvm/network/network_test.go index b7354a3663e6..3acdf39a1765 100644 --- a/vms/platformvm/network/network_test.go +++ b/vms/platformvm/network/network_test.go @@ -72,7 +72,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "mempool has transaction", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) require.NoError(t, mempool.Add(&txs.Tx{Unsigned: &txs.BaseTx{}})) return mempool @@ -86,7 +86,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "transaction marked as dropped in mempool", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) mempool.MarkDropped(ids.Empty, errTest) return mempool @@ -101,7 +101,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "tx dropped", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) return mempool }(), @@ -116,7 +116,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "tx too big", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) return mempool }(), @@ -135,7 +135,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "tx conflicts", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) tx := &txs.Tx{ @@ -177,7 +177,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "mempool full", mempool: func() pmempool.Mempool { - m, err := pmempool.New("", prometheus.NewRegistry(), nil) + m, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) for i := 0; i < 1024; i++ { @@ -204,7 +204,7 @@ func TestNetworkIssueTxFromRPC(t *testing.T) { { name: "happy path", mempool: func() pmempool.Mempool { - mempool, err := pmempool.New("", prometheus.NewRegistry(), nil) + mempool, err := pmempool.New("", prometheus.NewRegistry(), func() {}) require.NoError(t, err) return mempool }(), diff --git a/vms/platformvm/txs/mempool/mempool.go b/vms/platformvm/txs/mempool/mempool.go index af93ac2c7129..c9a1406bb4a0 100644 --- a/vms/platformvm/txs/mempool/mempool.go +++ b/vms/platformvm/txs/mempool/mempool.go @@ -8,7 +8,6 @@ import ( "github.com/prometheus/client_golang/prometheus" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/vms/platformvm/txs" txmempool "github.com/ava-labs/avalanchego/vms/txs/mempool" @@ -35,13 +34,13 @@ type Mempool interface { type mempool struct { txmempool.Mempool[*txs.Tx] - toEngine chan<- common.Message + notify func() } func New( namespace string, registerer prometheus.Registerer, - toEngine chan<- common.Message, + notify func(), ) (Mempool, error) { metrics, err := txmempool.NewMetrics(namespace, registerer) if err != nil { @@ -51,8 +50,8 @@ func New( metrics, ) return &mempool{ - Mempool: pool, - toEngine: toEngine, + Mempool: pool, + notify: notify, }, nil } @@ -73,8 +72,5 @@ func (m *mempool) RequestBuildBlock(emptyBlockPermitted bool) { return } - select { - case m.toEngine <- common.PendingTxs: - default: - } + m.notify() } diff --git a/vms/platformvm/validator_set_property_test.go b/vms/platformvm/validator_set_property_test.go index 412fd66d9bb7..c7926b764d9e 100644 --- a/vms/platformvm/validator_set_property_test.go +++ b/vms/platformvm/validator_set_property_test.go @@ -641,7 +641,6 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { chainDB := prefixdb.New([]byte{0}, baseDB) atomicDB := prefixdb.New([]byte{1}, baseDB) - msgChan := make(chan common.Message, 1) ctx := snowtest.Context(t, snowtest.PChainID) m := atomic.NewMemory(atomicDB) @@ -667,7 +666,6 @@ func buildVM(t *testing.T) (*VM, ids.ID, error) { }), nil, nil, - msgChan, nil, appSender, ) diff --git a/vms/platformvm/vm.go b/vms/platformvm/vm.go index 824cb6065c3f..81d7f83afcfc 100644 --- a/vms/platformvm/vm.go +++ b/vms/platformvm/vm.go @@ -64,6 +64,10 @@ type VM struct { *network.Network validators.State + common.Subscriber + + closeSubscriber func() + metrics platformvmmetrics.Metrics // Used to get time. Useful for faking time during tests. @@ -100,7 +104,6 @@ func (vm *VM) Initialize( genesisBytes []byte, _ []byte, configBytes []byte, - toEngine chan<- common.Message, _ []*common.Fx, appSender common.AppSender, ) error { @@ -167,7 +170,14 @@ func (vm *VM) Initialize( Bootstrapped: &vm.bootstrapped, } - mempool, err := pmempool.New("mempool", registerer, toEngine) + ss := common.NewSimpleSubscriber() + vm.closeSubscriber = ss.Close + vm.Subscriber = ss + notifyEngine := func() { + ss.Publish(common.PendingTxs) + } + + mempool, err := pmempool.New("mempool", registerer, notifyEngine) if err != nil { return fmt.Errorf("failed to create mempool: %w", err) } @@ -396,6 +406,8 @@ func (vm *VM) Shutdown(context.Context) error { } } + vm.closeSubscriber() + return errors.Join( vm.state.Close(), vm.db.Close(), diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index 146a77ce9e98..5667be3b4587 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/network/p2p" "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/uptime" "github.com/ava-labs/avalanchego/snow/validators" @@ -349,7 +348,6 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { ctx.Lock.Unlock() }() - msgChan := make(chan common.Message, 1) require.NoError(vm.Initialize( context.Background(), ctx, @@ -357,7 +355,6 @@ func TestUnverifiedParentPanicRegression(t *testing.T) { genesistest.NewBytes(t, genesistest.Config{}), nil, nil, - msgChan, nil, nil, )) diff --git a/vms/platformvm/vm_test.go b/vms/platformvm/vm_test.go index f43d3a66b176..1d3f61900a46 100644 --- a/vms/platformvm/vm_test.go +++ b/vms/platformvm/vm_test.go @@ -151,7 +151,6 @@ func defaultVM(t *testing.T, f upgradetest.Fork) (*VM, database.Database, *mutab atomicDB := prefixdb.New([]byte{1}, db) vm.clock.Set(latestForkTime) - msgChan := make(chan common.Message, 1) ctx := snowtest.Context(t, snowtest.PChainID) m := atomic.NewMemory(atomicDB) @@ -179,7 +178,6 @@ func defaultVM(t *testing.T, f upgradetest.Fork) (*VM, database.Database, *mutab genesistest.NewBytes(t, genesistest.Config{}), nil, dynamicConfigBytes, - msgChan, nil, appSender, )) @@ -1052,7 +1050,6 @@ func TestRestartFullyAccepted(t *testing.T) { firstVM.clock.Set(initialClkTime) firstCtx.Lock.Lock() - firstMsgChan := make(chan common.Message, 1) require.NoError(firstVM.Initialize( context.Background(), firstCtx, @@ -1060,7 +1057,6 @@ func TestRestartFullyAccepted(t *testing.T) { genesisBytes, nil, nil, - firstMsgChan, nil, nil, )) @@ -1134,7 +1130,6 @@ func TestRestartFullyAccepted(t *testing.T) { }() secondDB := prefixdb.New([]byte{}, db) - secondMsgChan := make(chan common.Message, 1) require.NoError(secondVM.Initialize( context.Background(), secondCtx, @@ -1142,7 +1137,6 @@ func TestRestartFullyAccepted(t *testing.T) { genesisBytes, nil, nil, - secondMsgChan, nil, nil, )) @@ -1181,7 +1175,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { consensusCtx := snowtest.ConsensusContext(ctx) ctx.Lock.Lock() - msgChan := make(chan common.Message, 1) require.NoError(vm.Initialize( context.Background(), ctx, @@ -1189,7 +1182,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { genesistest.NewBytes(t, genesistest.Config{}), nil, nil, - msgChan, nil, nil, )) @@ -1357,7 +1349,6 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { h, err := handler.New( bootstrapConfig.Ctx, beacons, - msgChan, time.Hour, 2, cpuTracker, @@ -1390,6 +1381,8 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { engine, err := smeng.New(engineConfig) require.NoError(err) + defer engine.Shutdown(context.Background()) + bootstrapper, err := bootstrap.New( bootstrapConfig, engine.Start, @@ -1397,6 +1390,8 @@ func TestBootstrapPartiallyAccepted(t *testing.T) { require.NoError(err) bootstrapper.TimeoutRegistrar = &enginetest.Timer{} + defer bootstrapper.Shutdown(context.Background()) + h.SetEngineManager(&handler.EngineManager{ Avalanche: &handler.Engine{ StateSyncer: nil, @@ -1525,7 +1520,6 @@ func TestUnverifiedParent(t *testing.T) { ctx.Lock.Unlock() }() - msgChan := make(chan common.Message, 1) require.NoError(vm.Initialize( context.Background(), ctx, @@ -1533,7 +1527,6 @@ func TestUnverifiedParent(t *testing.T) { genesistest.NewBytes(t, genesistest.Config{}), nil, nil, - msgChan, nil, nil, )) @@ -1677,7 +1670,6 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { genesisBytes := genesistest.NewBytes(t, genesistest.Config{}) - firstMsgChan := make(chan common.Message, 1) require.NoError(firstVM.Initialize( context.Background(), firstCtx, @@ -1685,7 +1677,6 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { genesisBytes, nil, nil, - firstMsgChan, nil, nil, )) @@ -1729,7 +1720,6 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { m := atomic.NewMemory(atomicDB) secondCtx.SharedMemory = m.NewSharedMemory(secondCtx.ChainID) - secondMsgChan := make(chan common.Message, 1) require.NoError(secondVM.Initialize( context.Background(), secondCtx, @@ -1737,7 +1727,6 @@ func TestUptimeDisallowedWithRestart(t *testing.T) { genesisBytes, nil, nil, - secondMsgChan, nil, nil, )) @@ -1822,7 +1811,6 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { m := atomic.NewMemory(atomicDB) ctx.SharedMemory = m.NewSharedMemory(ctx.ChainID) - msgChan := make(chan common.Message, 1) appSender := &enginetest.Sender{T: t} require.NoError(vm.Initialize( context.Background(), @@ -1831,7 +1819,6 @@ func TestUptimeDisallowedAfterNeverConnecting(t *testing.T) { genesistest.NewBytes(t, genesistest.Config{}), nil, nil, - msgChan, nil, appSender, )) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index d8b50dc94e67..1b1c85738b45 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -938,7 +938,6 @@ func initTestRemoteProposerVM( []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { @@ -1029,7 +1028,6 @@ func initTestRemoteProposerVM( nil, nil, nil, - nil, )) // Initialize shouldn't be called again diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 91c8a9c23766..350b79e82fda 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -21,6 +21,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/consensus/snowman/snowmanmock" "github.com/ava-labs/avalanchego/snow/consensus/snowman/snowmantest" + "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/engine/snowman/block/blockmock" "github.com/ava-labs/avalanchego/snow/validators" @@ -32,6 +33,7 @@ import ( "github.com/ava-labs/avalanchego/vms/proposervm/proposer" "github.com/ava-labs/avalanchego/vms/proposervm/proposer/proposermock" "github.com/ava-labs/avalanchego/vms/proposervm/scheduler/schedulermock" + "github.com/ava-labs/avalanchego/vms/proposervm/subscribermock" ) // Assert that when the underlying VM implements ChainVMWithBuildBlockContext @@ -74,7 +76,13 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) + + subscriber := subscribermock.NewSelfSubscriber(ctrl) + scheduler := schedulermock.NewScheduler(ctrl) + vm := &VM{ + subscriber: subscriber, + Scheduler: scheduler, Config: Config{ Upgrades: upgradetest.GetConfig(upgradetest.Latest), StakingCertLeaf: &staking.Certificate{}, @@ -384,6 +392,13 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { scheduler := schedulermock.NewScheduler(ctrl) + subscriber := subscribermock.NewSelfSubscriber(ctrl) + subscriber.EXPECT().SetAbsorbedMsg(gomock.Any()).Do(func(message common.Message) { + subscriber.EXPECT().SubscribeToEvents(gomock.Any()).Return(common.PendingTxs).AnyTimes() + }).AnyTimes() + + innerVM := blockmock.NewChainVM(ctrl) + pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ @@ -393,7 +408,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { StakingLeafSigner: pk, Registerer: prometheus.NewRegistry(), }, - ChainVM: blockmock.NewChainVM(ctrl), + ChainVM: innerVM, ctx: &snow.Context{ NodeID: thisNodeID, ValidatorState: vdrState, @@ -401,6 +416,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { }, Windower: windower, Scheduler: scheduler, + subscriber: subscriber, proposerBuildSlotGauge: prometheus.NewGauge(prometheus.GaugeOpts{}), } vm.Clock.Set(now) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 0cce5076449f..64f55a905952 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -544,7 +544,6 @@ func TestOptionTimestampValidity(t *testing.T) { []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { @@ -592,7 +591,6 @@ func TestOptionTimestampValidity(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/scheduler/scheduler.go b/vms/proposervm/scheduler/scheduler.go index 8395596a55a8..62fc721ac1e7 100644 --- a/vms/proposervm/scheduler/scheduler.go +++ b/vms/proposervm/scheduler/scheduler.go @@ -4,10 +4,9 @@ package scheduler import ( + "context" "time" - "go.uber.org/zap" - "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/logging" ) @@ -26,27 +25,22 @@ type Scheduler interface { // when the engine should call BuildBlock. Namely, when this node is allowed to // propose a block under the congestion control mechanism. type scheduler struct { - log logging.Logger - // The VM sends a message on this channel when it wants to tell the engine - // that the engine should call the VM's BuildBlock method - fromVM <-chan common.Message - // The scheduler sends a message on this channel to notify the engine that - // it should call its VM's BuildBlock method - toEngine chan<- common.Message + log logging.Logger + subscriptionDelayer *common.SubscriptionDelayer + // When we receive a message on this channel, it means that we must refrain // from telling the engine to call its VM's BuildBlock method until the // given time newBuildBlockTime chan time.Time } -func New(log logging.Logger, toEngine chan<- common.Message) (Scheduler, chan<- common.Message) { - vmToEngine := make(chan common.Message, cap(toEngine)) +func New(log logging.Logger, subscription common.Subscription) (Scheduler, *common.SubscriptionDelayer) { + sd := common.NewSubscriptionDelayer(subscription) return &scheduler{ - log: log, - fromVM: vmToEngine, - toEngine: toEngine, - newBuildBlockTime: make(chan time.Time), - }, vmToEngine + subscriptionDelayer: sd, + log: log, + newBuildBlockTime: make(chan time.Time), + }, sd } func (s *scheduler) Dispatch(buildBlockTime time.Time) { @@ -73,21 +67,19 @@ waitloop: } for { + absorbed := make(chan struct{}) + ctx, cancel := context.WithCancel(context.Background()) + + go func() { + s.subscriptionDelayer.Absorb(ctx) + close(absorbed) + }() + select { - case msg := <-s.fromVM: - // Give the engine the message from the VM asking the engine to - // build a block - select { - case s.toEngine <- msg: - default: - // If the channel to the engine is full, drop the message - // from the VM to avoid deadlock - s.log.Debug("dropping message from VM", - zap.String("reason", "channel to engine is full"), - zap.Stringer("messageString", msg), - ) - } + case <-absorbed: + s.subscriptionDelayer.Release() case buildBlockTime, ok := <-s.newBuildBlockTime: + cancel() // The time at which we should notify the engine that it should // try to build a block has changed if !ok { diff --git a/vms/proposervm/scheduler/scheduler_test.go b/vms/proposervm/scheduler/scheduler_test.go index 77ed39a67330..58ab627fa900 100644 --- a/vms/proposervm/scheduler/scheduler_test.go +++ b/vms/proposervm/scheduler/scheduler_test.go @@ -4,6 +4,7 @@ package scheduler import ( + "context" "testing" "time" @@ -14,48 +15,57 @@ import ( ) func TestDelayFromNew(t *testing.T) { - toEngine := make(chan common.Message, 10) startTime := time.Now().Add(50 * time.Millisecond) - s, fromVM := New(logging.NoLog{}, toEngine) + msgs := make(chan common.Message, 1) + sub := func(ctx context.Context) common.Message { + return <-msgs + } + s, fromVM := New(logging.NoLog{}, sub) defer s.Close() go s.Dispatch(startTime) - fromVM <- common.PendingTxs + msgs <- common.PendingTxs + fromVM.SubscribeToEvents(context.Background()) - <-toEngine require.LessOrEqual(t, time.Until(startTime), time.Duration(0)) } func TestDelayFromSetTime(t *testing.T) { - toEngine := make(chan common.Message, 10) now := time.Now() startTime := now.Add(50 * time.Millisecond) - s, fromVM := New(logging.NoLog{}, toEngine) + msgs := make(chan common.Message, 1) + sub := func(ctx context.Context) common.Message { + return <-msgs + } + s, fromVM := New(logging.NoLog{}, sub) defer s.Close() go s.Dispatch(now) s.SetBuildBlockTime(startTime) - fromVM <- common.PendingTxs + msgs <- common.PendingTxs - <-toEngine + fromVM.SubscribeToEvents(context.Background()) require.LessOrEqual(t, time.Until(startTime), time.Duration(0)) } func TestReceipt(*testing.T) { - toEngine := make(chan common.Message, 10) + msgs := make(chan common.Message, 1) + sub := func(ctx context.Context) common.Message { + return <-msgs + } now := time.Now() startTime := now.Add(50 * time.Millisecond) - s, fromVM := New(logging.NoLog{}, toEngine) + s, fromVM := New(logging.NoLog{}, sub) defer s.Close() go s.Dispatch(now) - fromVM <- common.PendingTxs + msgs <- common.PendingTxs s.SetBuildBlockTime(startTime) - <-toEngine + fromVM.SubscribeToEvents(context.Background()) } diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 4e43fc7f2af8..4185d5ed1436 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -44,7 +44,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // load innerVM expectations innerVM.InitializeF = func(context.Context, *snow.Context, database.Database, - []byte, []byte, []byte, chan<- common.Message, + []byte, []byte, []byte, []*common.Fx, common.AppSender, ) error { return nil @@ -81,7 +81,6 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { nil, nil, nil, - nil, )) require.NoError(vm.SetState(context.Background(), snow.StateSyncing)) diff --git a/vms/proposervm/subscribermock/subscriber.go b/vms/proposervm/subscribermock/subscriber.go new file mode 100644 index 000000000000..bf46d1262fae --- /dev/null +++ b/vms/proposervm/subscribermock/subscriber.go @@ -0,0 +1,79 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/vms/proposervm (interfaces: SelfSubscriber) +// +// Generated by this command: +// +// mockgen -package=subscribermock -destination=subscribermock/subscriber.go -mock_names=SelfSubscriber=SelfSubscriber . SelfSubscriber +// + +// Package subscribermock is a generated GoMock package. +package subscribermock + +import ( + context "context" + reflect "reflect" + + common "github.com/ava-labs/avalanchego/snow/engine/common" + gomock "go.uber.org/mock/gomock" +) + +// SelfSubscriber is a mock of SelfSubscriber interface. +type SelfSubscriber struct { + ctrl *gomock.Controller + recorder *SelfSubscriberMockRecorder +} + +// SelfSubscriberMockRecorder is the mock recorder for SelfSubscriber. +type SelfSubscriberMockRecorder struct { + mock *SelfSubscriber +} + +// NewSelfSubscriber creates a new mock instance. +func NewSelfSubscriber(ctrl *gomock.Controller) *SelfSubscriber { + mock := &SelfSubscriber{ctrl: ctrl} + mock.recorder = &SelfSubscriberMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *SelfSubscriber) EXPECT() *SelfSubscriberMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *SelfSubscriber) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *SelfSubscriberMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*SelfSubscriber)(nil).Close)) +} + +// SetAbsorbedMsg mocks base method. +func (m *SelfSubscriber) SetAbsorbedMsg(arg0 common.Message) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetAbsorbedMsg", arg0) +} + +// SetAbsorbedMsg indicates an expected call of SetAbsorbedMsg. +func (mr *SelfSubscriberMockRecorder) SetAbsorbedMsg(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAbsorbedMsg", reflect.TypeOf((*SelfSubscriber)(nil).SetAbsorbedMsg), arg0) +} + +// SubscribeToEvents mocks base method. +func (m *SelfSubscriber) SubscribeToEvents(arg0 context.Context) common.Message { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SubscribeToEvents", arg0) + ret0, _ := ret[0].(common.Message) + return ret0 +} + +// SubscribeToEvents indicates an expected call of SubscribeToEvents. +func (mr *SelfSubscriberMockRecorder) SubscribeToEvents(arg0 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubscribeToEvents", reflect.TypeOf((*SelfSubscriber)(nil).SubscribeToEvents), arg0) +} diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index c59f6a790133..94297731c4db 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -46,6 +46,12 @@ const ( innerBlkCacheSize = 64 * units.MiB ) +type SelfSubscriber interface { + SubscribeToEvents(ctx context.Context) common.Message + SetAbsorbedMsg(txs common.Message) + Close() +} + var ( _ block.ChainVM = (*VM)(nil) _ block.BatchedChainVM = (*VM)(nil) @@ -72,9 +78,10 @@ type VM struct { scheduler.Scheduler mockable.Clock - ctx *snow.Context - db *versiondb.Database - toScheduler chan<- common.Message + subscriber SelfSubscriber + + ctx *snow.Context + db *versiondb.Database // Block ID --> Block // Each element is a block that passed verification but @@ -136,7 +143,6 @@ func (vm *VM) Initialize( genesisBytes []byte, upgradeBytes []byte, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -162,14 +168,6 @@ func (vm *VM) Initialize( } vm.innerBlkCache = innerBlkCache - scheduler, vmToEngine := scheduler.New(vm.ctx.Log, toEngine) - vm.Scheduler = scheduler - vm.toScheduler = vmToEngine - - go chainCtx.Log.RecoverAndPanic(func() { - scheduler.Dispatch(time.Now()) - }) - vm.verifiedBlocks = make(map[ids.ID]PostForkBlock) detachedCtx := context.WithoutCancel(ctx) context, cancel := context.WithCancel(detachedCtx) @@ -183,7 +181,6 @@ func (vm *VM) Initialize( genesisBytes, upgradeBytes, configBytes, - vmToEngine, fxs, appSender, ) @@ -191,6 +188,14 @@ func (vm *VM) Initialize( return err } + scheduler, subscriber := scheduler.New(vm.ctx.Log, vm.ChainVM.SubscribeToEvents) + vm.Scheduler = scheduler + vm.subscriber = subscriber + + go chainCtx.Log.RecoverAndPanic(func() { + scheduler.Dispatch(time.Now()) + }) + if err := vm.repairAcceptedChainByHeight(ctx); err != nil { return fmt.Errorf("failed to repair accepted chain by height: %w", err) } @@ -250,11 +255,16 @@ func (vm *VM) Initialize( ) } +func (vm *VM) SubscribeToEvents(ctx context.Context) common.Message { + return vm.subscriber.SubscribeToEvents(ctx) +} + // shutdown ops then propagate shutdown to innerVM func (vm *VM) Shutdown(ctx context.Context) error { vm.onShutdown() vm.Scheduler.Close() + vm.subscriber.Close() if err := vm.db.Commit(); err != nil { return err @@ -723,11 +733,7 @@ func (vm *VM) verifyAndRecordInnerBlk(ctx context.Context, blockCtx *block.Conte // notifyInnerBlockReady tells the scheduler that the inner VM is ready to build // a new block func (vm *VM) notifyInnerBlockReady() { - select { - case vm.toScheduler <- common.PendingTxs: - default: - vm.ctx.Log.Debug("dropping message to consensus engine") - } + vm.subscriber.SetAbsorbedMsg(common.PendingTxs) } // fujiOverridePChainHeightUntilHeight is the P-chain height at which the diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index d551addc0a2b..12a644730b95 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -106,7 +106,7 @@ func initTestProposerVM( } coreVM.InitializeF = func(context.Context, *snow.Context, database.Database, - []byte, []byte, []byte, chan<- common.Message, + []byte, []byte, []byte, []*common.Fx, common.AppSender, ) error { return nil @@ -198,7 +198,6 @@ func initTestProposerVM( nil, nil, nil, - nil, )) // Initialize shouldn't be called again @@ -845,9 +844,6 @@ func TestExpiredBuildBlock(t *testing.T) { ctx.NodeID = ids.NodeIDFromCert(pTestCert) ctx.ValidatorState = valState - toEngine := make(chan common.Message, 1) - var toScheduler chan<- common.Message - coreVM.InitializeF = func( _ context.Context, _ *snow.Context, @@ -855,11 +851,9 @@ func TestExpiredBuildBlock(t *testing.T) { _ []byte, _ []byte, _ []byte, - toEngineChan chan<- common.Message, _ []*common.Fx, _ common.AppSender, ) error { - toScheduler = toEngineChan return nil } @@ -871,7 +865,6 @@ func TestExpiredBuildBlock(t *testing.T) { nil, nil, nil, - toEngine, nil, nil, )) @@ -882,13 +875,26 @@ func TestExpiredBuildBlock(t *testing.T) { // Initialize shouldn't be called again coreVM.InitializeF = nil + testEnd := make(chan struct{}) + defer close(testEnd) + + events := make(chan common.Message, 1) + coreVM.SubscribeToEventsF = func(ctx context.Context) common.Message { + select { + case <-testEnd: + return 0 + case event := <-events: + return event + } + } + require.NoError(proVM.SetState(context.Background(), snow.NormalOp)) require.NoError(proVM.SetPreference(context.Background(), snowmantest.GenesisID)) // Notify the proposer VM of a new block on the inner block side - toScheduler <- common.PendingTxs + events <- common.PendingTxs // The first notification will be read from the consensus engine - <-toEngine + proVM.SubscribeToEvents(context.Background()) // Before calling BuildBlock, verify a remote block and set it as the // preferred block. @@ -947,7 +953,7 @@ func TestExpiredBuildBlock(t *testing.T) { // the window has started again. This is to guarantee that the inner VM has // build block called after it sent a pendingTxs message on its internal // engine channel. - <-toEngine + proVM.SubscribeToEvents(context.Background()) } type wrappedBlock struct { @@ -1092,7 +1098,6 @@ func TestInnerVMRollback(t *testing.T) { []byte, []byte, []byte, - chan<- common.Message, []*common.Fx, common.AppSender, ) error { @@ -1147,7 +1152,6 @@ func TestInnerVMRollback(t *testing.T) { nil, nil, nil, - nil, )) require.NoError(proVM.SetState(context.Background(), snow.NormalOp)) @@ -1225,7 +1229,6 @@ func TestInnerVMRollback(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1565,7 +1568,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { } coreVM.InitializeF = func(context.Context, *snow.Context, database.Database, - []byte, []byte, []byte, chan<- common.Message, + []byte, []byte, []byte, []*common.Fx, common.AppSender, ) error { return nil @@ -1651,7 +1654,6 @@ func TestRejectedHeightNotIndexed(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1734,7 +1736,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { } coreVM.InitializeF = func(context.Context, *snow.Context, database.Database, - []byte, []byte, []byte, chan<- common.Message, + []byte, []byte, []byte, []*common.Fx, common.AppSender, ) error { return nil @@ -1820,7 +1822,6 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1913,9 +1914,9 @@ func TestVMInnerBlkCache(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), ).Return(nil) innerVM.EXPECT().Shutdown(gomock.Any()).Return(nil) + innerVM.EXPECT().SubscribeToEvents(gomock.Any()).Return(common.Message(0)).AnyTimes() { innerBlk := snowmanmock.NewBlock(ctrl) @@ -1936,7 +1937,6 @@ func TestVMInnerBlkCache(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -2000,6 +2000,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // Create a VM innerVM := blockmock.NewChainVM(ctrl) + innerVM.EXPECT().SubscribeToEvents(gomock.Any()).Return(common.Message(0)).AnyTimes() vm := New( innerVM, Config{ @@ -2024,7 +2025,6 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), ).Return(nil) innerVM.EXPECT().Shutdown(gomock.Any()).Return(nil) @@ -2047,7 +2047,6 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(vm.Shutdown(context.Background())) @@ -2151,7 +2150,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM := &blocktest.VM{ VM: enginetest.VM{ T: t, - InitializeF: func(context.Context, *snow.Context, database.Database, []byte, []byte, []byte, chan<- common.Message, []*common.Fx, common.AppSender) error { + InitializeF: func(context.Context, *snow.Context, database.Database, []byte, []byte, []byte, []*common.Fx, common.AppSender) error { return nil }, }, @@ -2221,7 +2220,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { nil, nil, nil, - nil, )) lastAcceptedID, err := proVM.LastAccepted(context.Background()) @@ -2311,7 +2309,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { nil, nil, nil, - nil, )) lastAcceptedID, err = proVM.LastAccepted(context.Background()) @@ -2354,7 +2351,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { nil, nil, nil, - nil, )) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -2497,7 +2493,7 @@ func TestLocalParse(t *testing.T) { _ = vm.Initialize(context.Background(), &snow.Context{ Log: logging.NoLog{}, ChainID: chainID, - }, db, nil, nil, nil, nil, nil, nil) + }, db, nil, nil, nil, nil, nil) tests := []struct { name string diff --git a/vms/rpcchainvm/batched_vm_test.go b/vms/rpcchainvm/batched_vm_test.go index 274cecc845bf..fd9a9fbe361a 100644 --- a/vms/rpcchainvm/batched_vm_test.go +++ b/vms/rpcchainvm/batched_vm_test.go @@ -47,7 +47,6 @@ func batchedParseBlockCachingTestPlugin(t *testing.T, loadExpectations bool) blo vm.EXPECT().Initialize( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), ).Return(nil).Times(1), vm.EXPECT().LastAccepted(gomock.Any()).Return(preSummaryBlk.ID(), nil).Times(1), vm.EXPECT().GetBlock(gomock.Any(), gomock.Any()).Return(preSummaryBlk, nil).Times(1), @@ -81,7 +80,7 @@ func TestBatchedParseBlockCaching(t *testing.T) { ctx := snowtest.Context(t, snowtest.CChainID) - require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil, nil)) + require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil)) // Call should parse the first block blk, err := vm.ParseBlock(context.Background(), blkBytes1) diff --git a/vms/rpcchainvm/messenger/messenger_client.go b/vms/rpcchainvm/messenger/messenger_client.go index d392b9af79c6..5e2e209363c4 100644 --- a/vms/rpcchainvm/messenger/messenger_client.go +++ b/vms/rpcchainvm/messenger/messenger_client.go @@ -5,25 +5,121 @@ package messenger import ( "context" - - "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/logging" + "go.uber.org/zap" + "sync" + "time" messengerpb "github.com/ava-labs/avalanchego/proto/pb/messenger" ) // Client is an implementation of a messenger channel that talks over RPC. type Client struct { - client messengerpb.MessengerClient + client messengerpb.MessengerClient + log logging.Logger + getMessage func(ctx context.Context) messengerpb.Message + cancel context.CancelFunc + shutdown context.CancelFunc + shutdownContext context.Context } // NewClient returns a client that is connected to a remote channel -func NewClient(client messengerpb.MessengerClient) *Client { - return &Client{client: client} +func NewClient(client messengerpb.MessengerClient, log logging.Logger, getMessage func(ctx context.Context) messengerpb.Message) *Client { + shutdownCtx, shutdownCtxCancel := context.WithCancel(context.Background()) + return &Client{ + shutdownContext: shutdownCtx, + shutdown: shutdownCtxCancel, + log: log, + client: client, + getMessage: getMessage, + } +} + +func (c *Client) Run() { + var stream messengerpb.Messenger_NotifyClient + var err error + + for { + select { + case <-c.shutdownContext.Done(): + return + default: + + } + if stream == nil { + stream, err = c.client.Notify(c.shutdownContext) + if err != nil { + c.log.Error("Error creating stream", zap.Error(err)) + time.Sleep(time.Second) + continue + } + } + + req, err := stream.Recv() + if err != nil { + c.log.Error("Error receiving message", zap.Error(err)) + stream = nil + time.Sleep(time.Second) + continue + } + + c.handleRequest(req, stream) + } } -func (c *Client) Notify(msg common.Message) error { - _, err := c.client.Notify(context.Background(), &messengerpb.NotifyRequest{ - Message: messengerpb.Message(msg), - }) - return err +func (c *Client) Stop() { + select { + case <-c.shutdownContext.Done(): + return + default: + c.shutdown() + } +} + +func (c *Client) handleRequest(req *messengerpb.EventRequest, stream messengerpb.Messenger_NotifyClient) { + if req.GetStart() { + c.dispatchStart(stream) + return + } + + if req.GetStop() { + c.cancel() + } +} + +func (c *Client) dispatchStart(stream messengerpb.Messenger_NotifyClient) { + // First, cancel the previous execution + if c.cancel != nil { + c.cancel() + c.cancel = nil + } + + var wg sync.WaitGroup + wg.Add(1) + + ctx, cancel := context.WithCancel(stream.Context()) + c.cancel = func() { + cancel() + wg.Wait() + } + + go func() { + defer wg.Done() + c.sendMessageBack(ctx, stream) + }() +} + +func (c *Client) sendMessageBack(ctx context.Context, stream messengerpb.Messenger_NotifyClient) { + msg := c.getMessage(ctx) + + // If the context is prematurely cancelled, don't send anything back. + select { + case <-ctx.Done(): + return + default: + } + + if err := stream.Send(&messengerpb.Event{Message: msg}); err != nil { + c.log.Error("Error sending message", zap.Error(err)) + } } diff --git a/vms/rpcchainvm/messenger/messenger_server.go b/vms/rpcchainvm/messenger/messenger_server.go index fc28a0757bb2..cdbdb8e1ddc4 100644 --- a/vms/rpcchainvm/messenger/messenger_server.go +++ b/vms/rpcchainvm/messenger/messenger_server.go @@ -5,36 +5,103 @@ package messenger import ( "context" - "errors" - "github.com/ava-labs/avalanchego/snow/engine/common" + "sync" messengerpb "github.com/ava-labs/avalanchego/proto/pb/messenger" ) var ( - errFullQueue = errors.New("full message queue") - _ messengerpb.MessengerServer = (*Server)(nil) ) // Server is a messenger that is managed over RPC. type Server struct { messengerpb.UnsafeMessengerServer - messenger chan<- common.Message + stream messengerpb.Messenger_NotifyServer + events chan common.Message + + lock sync.Mutex + signal sync.Cond } // NewServer returns a messenger connected to a remote channel -func NewServer(messenger chan<- common.Message) *Server { - return &Server{messenger: messenger} +func NewServer() *Server { + s := &Server{ + events: make(chan common.Message), + } + + s.signal = sync.Cond{L: &s.lock} + + return s } -func (s *Server) Notify(_ context.Context, req *messengerpb.NotifyRequest) (*messengerpb.NotifyResponse, error) { - msg := common.Message(req.Message) +func (s *Server) SubscribeToEvents(ctx context.Context) common.Message { + // Wait for the stream to be connected + stream := s.acquireStream(ctx) + // If stream is nil, it means the context was done before the stream was connected + if stream == nil { + return 0 + } + + if err := stream.Send(&messengerpb.EventRequest{Event: &messengerpb.EventRequest_Start{Start: true}}); err != nil { + return 0 + } + select { - case s.messenger <- msg: - return &messengerpb.NotifyResponse{}, nil - default: - return nil, errFullQueue + case <-ctx.Done(): + stream.Send(&messengerpb.EventRequest{Event: &messengerpb.EventRequest_Stop{Stop: true}}) // TODO: handle send error + return 0 + case event := <-s.events: + return event + } +} + +func (s *Server) acquireStream(ctx context.Context) messengerpb.Messenger_NotifyServer { + var stream messengerpb.Messenger_NotifyServer + s.lock.Lock() + defer s.lock.Unlock() + + context, cancel := context.WithCancel(ctx) + go func() { + <-context.Done() + s.signal.Signal() + }() + + defer cancel() + + for { + select { + case <-context.Done(): + return nil + default: + } + + stream = s.stream + if stream == nil { + s.signal.Wait() + } else { + return stream + } + } +} + +func (s *Server) Notify(stream messengerpb.Messenger_NotifyServer) error { + s.lock.Lock() + s.stream = stream + s.signal.Signal() + s.lock.Unlock() + + for { + event, err := stream.Recv() + if err != nil { + return err + } + + select { + case s.events <- common.Message(event.GetMessage()): + case <-stream.Context().Done(): + return nil + } } } diff --git a/vms/rpcchainvm/messenger/messenger_test.go b/vms/rpcchainvm/messenger/messenger_test.go new file mode 100644 index 000000000000..2cbefa16c55a --- /dev/null +++ b/vms/rpcchainvm/messenger/messenger_test.go @@ -0,0 +1,130 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package messenger + +import ( + "context" + messengerpb "github.com/ava-labs/avalanchego/proto/pb/messenger" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" + "sync" + "testing" + "time" +) + +func TestMessenger(t *testing.T) { + events := make(chan messengerpb.Message, 2) + events <- messengerpb.Message_MESSAGE_BUILD_BLOCK + events <- messengerpb.Message_MESSAGE_STATE_SYNC_FINISHED + + server := NewServer() + getMsg := func(ctx context.Context) messengerpb.Message { + return <-events + } + client := NewClient(&fakeClient{server: server}, &logging.NoLog{}, getMsg) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + client.Run() + }() + msg := server.SubscribeToEvents(context.Background()) + require.Equal(t, messengerpb.Message_MESSAGE_BUILD_BLOCK, messengerpb.Message(msg)) + msg = server.SubscribeToEvents(context.Background()) + require.Equal(t, messengerpb.Message_MESSAGE_STATE_SYNC_FINISHED, messengerpb.Message(msg)) + client.Stop() + wg.Wait() +} + +func TestMessengerAbort(t *testing.T) { + events := make(chan messengerpb.Message, 1) + + server := NewServer() + getMsg := func(ctx context.Context) messengerpb.Message { + return <-events + } + client := NewClient(&fakeClient{server: server}, &logging.NoLog{}, getMsg) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + client.Run() + }() + context, cancel := context.WithCancel(context.Background()) + go cancel() + go func() { + time.Sleep(time.Second) + events <- messengerpb.Message_MESSAGE_BUILD_BLOCK + }() + msg := server.SubscribeToEvents(context) + require.Equal(t, messengerpb.Message_MESSAGE_UNSPECIFIED, messengerpb.Message(msg)) + client.Stop() + wg.Wait() +} + +type fakeClient struct { + server *Server +} + +func (f fakeClient) Notify(ctx context.Context, _ ...grpc.CallOption) (messengerpb.Messenger_NotifyClient, error) { + cs := &clientStream{ + ctx: ctx, + toServer: make(chan interface{}), + fromServer: make(chan interface{}), + } + go f.server.Notify(&serverStream{ + ctx: ctx, + fromClient: cs.toServer, + toClient: cs.fromServer, + }) + return cs, nil +} + +type serverStream struct { + ctx context.Context + grpc.ServerStream + toClient chan interface{} + fromClient chan interface{} +} + +func (ss *serverStream) Context() context.Context { + return ss.ctx +} + +func (ss *serverStream) Send(req *messengerpb.EventRequest) error { + ss.toClient <- req + return nil +} +func (ss *serverStream) Recv() (*messengerpb.Event, error) { + event := <-ss.fromClient + return event.(*messengerpb.Event), nil +} + +type clientStream struct { + ctx context.Context + grpc.ClientStream + toServer chan interface{} + fromServer chan interface{} +} + +func (cs *clientStream) Context() context.Context { + return cs.ctx +} + +func (cs *clientStream) Send(event *messengerpb.Event) error { + cs.toServer <- event + return nil +} + +func (cs *clientStream) Recv() (*messengerpb.EventRequest, error) { + select { + case req := <-cs.fromServer: + return req.(*messengerpb.EventRequest), nil + case <-cs.ctx.Done(): + return nil, cs.ctx.Err() + } +} diff --git a/vms/rpcchainvm/state_syncable_vm_test.go b/vms/rpcchainvm/state_syncable_vm_test.go index 879848accc3b..f3f2aa0bc525 100644 --- a/vms/rpcchainvm/state_syncable_vm_test.go +++ b/vms/rpcchainvm/state_syncable_vm_test.go @@ -238,7 +238,7 @@ func lastAcceptedBlockPostStateSummaryAcceptTestPlugin(t *testing.T, loadExpecta gomock.InOrder( ssVM.ChainVM.EXPECT().Initialize( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ).Return(nil).Times(1), ssVM.ChainVM.EXPECT().LastAccepted(gomock.Any()).Return(preSummaryBlk.ID(), nil).Times(1), @@ -473,7 +473,7 @@ func TestLastAcceptedBlockPostStateSummaryAccept(t *testing.T) { // Step 1: initialize VM and check initial LastAcceptedBlock ctx := snowtest.Context(t, snowtest.CChainID) - require.NoError(vm.Initialize(context.Background(), ctx, prefixdb.New([]byte{}, memdb.New()), nil, nil, nil, nil, nil, nil)) + require.NoError(vm.Initialize(context.Background(), ctx, prefixdb.New([]byte{}, memdb.New()), nil, nil, nil, nil, nil)) blkID, err := vm.LastAccepted(context.Background()) require.NoError(err) diff --git a/vms/rpcchainvm/vm_client.go b/vms/rpcchainvm/vm_client.go index 62dfd1ec5a97..54e0c2d243db 100644 --- a/vms/rpcchainvm/vm_client.go +++ b/vms/rpcchainvm/vm_client.go @@ -126,7 +126,6 @@ func (vm *VMClient) Initialize( genesisBytes []byte, upgradeBytes []byte, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -165,7 +164,7 @@ func (vm *VMClient) Initialize( zap.String("address", dbServerAddr), ) - vm.messenger = messenger.NewServer(toEngine) + vm.messenger = messenger.NewServer() vm.sharedMemory = gsharedmemory.NewServer(chainCtx.SharedMemory, db) vm.bcLookup = galiasreader.NewServer(chainCtx.BCLookup) vm.appSender = appsender.NewServer(appSender) @@ -291,6 +290,10 @@ func (vm *VMClient) newDBServer(db database.Database) *grpc.Server { return server } +func (vm *VMClient) SubscribeToEvents(ctx context.Context) common.Message { + return vm.messenger.SubscribeToEvents(ctx) +} + func (vm *VMClient) newInitServer() *grpc.Server { server := grpcutils.NewServer( grpcutils.WithUnaryInterceptor(vm.grpcServerMetrics.UnaryServerInterceptor()), diff --git a/vms/rpcchainvm/vm_server.go b/vms/rpcchainvm/vm_server.go index b4316ccfa28b..39c70e06d87a 100644 --- a/vms/rpcchainvm/vm_server.go +++ b/vms/rpcchainvm/vm_server.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "os" + "sync" "time" "github.com/prometheus/client_golang/prometheus/collectors" @@ -78,8 +79,10 @@ type VMServer struct { serverCloser grpcutils.ServerCloser connCloser wrappers.Closer - ctx *snow.Context - closed chan struct{} + ctx *snow.Context + closed chan struct{} + lock sync.Mutex + cancelSub func() } // NewServer returns a vm instance connected to a remote vm instance @@ -208,29 +211,20 @@ func (vm *VMServer) Initialize(ctx context.Context, req *vmpb.InitializeRequest) vm.connCloser.Add(clientConn) - msgClient := messenger.NewClient(messengerpb.NewMessengerClient(clientConn)) + subscribe := func(ctx context.Context) messengerpb.Message { + return messengerpb.Message(vm.vm.SubscribeToEvents(ctx)) + } + msgClient := messenger.NewClient(messengerpb.NewMessengerClient(clientConn), vm.log, subscribe) + defer func() { + go msgClient.Run() + }() sharedMemoryClient := gsharedmemory.NewClient(sharedmemorypb.NewSharedMemoryClient(clientConn)) bcLookupClient := galiasreader.NewClient(aliasreaderpb.NewAliasReaderClient(clientConn)) appSenderClient := appsender.NewClient(appsenderpb.NewAppSenderClient(clientConn)) validatorStateClient := gvalidators.NewClient(validatorstatepb.NewValidatorStateClient(clientConn)) warpSignerClient := gwarp.NewClient(warppb.NewSignerClient(clientConn)) - toEngine := make(chan common.Message, 1) vm.closed = make(chan struct{}) - go func() { - for { - select { - case msg, ok := <-toEngine: - if !ok { - return - } - // Nothing to do with the error within the goroutine - _ = msgClient.Notify(msg) - case <-vm.closed: - return - } - } - }() vm.ctx = &snow.Context{ NetworkID: req.NetworkId, @@ -258,10 +252,11 @@ func (vm *VMServer) Initialize(ctx context.Context, req *vmpb.InitializeRequest) ChainDataDir: req.ChainDataDir, } - if err := vm.vm.Initialize(ctx, vm.ctx, vm.db, req.GenesisBytes, req.UpgradeBytes, req.ConfigBytes, toEngine, nil, appSenderClient); err != nil { + if err := vm.vm.Initialize(ctx, vm.ctx, vm.db, req.GenesisBytes, req.UpgradeBytes, req.ConfigBytes, nil, appSenderClient); err != nil { // Ignore errors closing resources to return the original error _ = vm.connCloser.Close() close(vm.closed) + vm.abortSubscription() return nil, err } @@ -271,6 +266,7 @@ func (vm *VMServer) Initialize(ctx context.Context, req *vmpb.InitializeRequest) _ = vm.vm.Shutdown(ctx) _ = vm.connCloser.Close() close(vm.closed) + vm.abortSubscription() return nil, err } @@ -280,6 +276,7 @@ func (vm *VMServer) Initialize(ctx context.Context, req *vmpb.InitializeRequest) _ = vm.vm.Shutdown(ctx) _ = vm.connCloser.Close() close(vm.closed) + vm.abortSubscription() return nil, err } parentID := blk.Parent() @@ -292,6 +289,14 @@ func (vm *VMServer) Initialize(ctx context.Context, req *vmpb.InitializeRequest) }, nil } +func (vm *VMServer) getContext() context.Context { + ctx, cancel := context.WithCancel(context.Background()) + vm.lock.Lock() + vm.cancelSub = cancel + vm.lock.Unlock() + return ctx +} + func (vm *VMServer) SetState(ctx context.Context, stateReq *vmpb.SetStateRequest) (*vmpb.SetStateResponse, error) { err := vm.vm.SetState(ctx, snow.State(stateReq.State)) if err != nil { @@ -326,11 +331,21 @@ func (vm *VMServer) Shutdown(ctx context.Context, _ *emptypb.Empty) (*emptypb.Em errs := wrappers.Errs{} errs.Add(vm.vm.Shutdown(ctx)) close(vm.closed) + vm.abortSubscription() vm.serverCloser.Stop() errs.Add(vm.connCloser.Close()) return &emptypb.Empty{}, errs.Err } +func (vm *VMServer) abortSubscription() { + vm.lock.Lock() + if vm.cancelSub != nil { + vm.cancelSub() + vm.cancelSub = nil + } + vm.lock.Unlock() +} + func (vm *VMServer) CreateHandlers(ctx context.Context, _ *emptypb.Empty) (*vmpb.CreateHandlersResponse, error) { handlers, err := vm.vm.CreateHandlers(ctx) if err != nil { diff --git a/vms/rpcchainvm/with_context_vm_test.go b/vms/rpcchainvm/with_context_vm_test.go index e96cbf346304..fd30acdb0079 100644 --- a/vms/rpcchainvm/with_context_vm_test.go +++ b/vms/rpcchainvm/with_context_vm_test.go @@ -66,7 +66,6 @@ func contextEnabledTestPlugin(t *testing.T, loadExpectations bool) block.ChainVM ctxVM.ChainVM.EXPECT().Initialize( gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), ).Return(nil).Times(1), ctxVM.ChainVM.EXPECT().LastAccepted(gomock.Any()).Return(preSummaryBlk.ID(), nil).Times(1), ctxVM.ChainVM.EXPECT().GetBlock(gomock.Any(), gomock.Any()).Return(preSummaryBlk, nil).Times(1), @@ -100,7 +99,7 @@ func TestContextVMSummary(t *testing.T) { ctx := snowtest.Context(t, snowtest.CChainID) - require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil, nil)) + require.NoError(vm.Initialize(context.Background(), ctx, memdb.New(), nil, nil, nil, nil, nil)) blkIntf, err := vm.BuildBlockWithContext(context.Background(), blockContext) require.NoError(err) diff --git a/vms/tracedvm/block_vm.go b/vms/tracedvm/block_vm.go index 13bb1a5d7b7c..9446f936b9e1 100644 --- a/vms/tracedvm/block_vm.go +++ b/vms/tracedvm/block_vm.go @@ -101,7 +101,6 @@ func (vm *blockVM) Initialize( genesisBytes, upgradeBytes, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -115,7 +114,6 @@ func (vm *blockVM) Initialize( genesisBytes, upgradeBytes, configBytes, - toEngine, fxs, appSender, ) diff --git a/vms/tracedvm/vertex_vm.go b/vms/tracedvm/vertex_vm.go index c4cf1998bb63..173e19ae67fe 100644 --- a/vms/tracedvm/vertex_vm.go +++ b/vms/tracedvm/vertex_vm.go @@ -39,7 +39,6 @@ func (vm *vertexVM) Initialize( genesisBytes, upgradeBytes, configBytes []byte, - toEngine chan<- common.Message, fxs []*common.Fx, appSender common.AppSender, ) error { @@ -53,7 +52,6 @@ func (vm *vertexVM) Initialize( genesisBytes, upgradeBytes, configBytes, - toEngine, fxs, appSender, ) diff --git a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go index 8e5427b28a1f..cfaf1d159e64 100644 --- a/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go +++ b/wallet/subnet/primary/examples/add-permissioned-subnet-validator/main.go @@ -5,10 +5,10 @@ package main import ( "context" + "github.com/ava-labs/avalanchego/utils/formatting" "log" "time" - "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/units" @@ -21,7 +21,7 @@ func main() { key := genesis.EWOQKey uri := primary.LocalAPIURI kc := secp256k1fx.NewKeychain(key) - subnetIDStr := "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" + subnetIDStr := "BKBZ6xXTnT86B4L5fp8rvtcmNSpvtNz8En9jG61ywV2uWyeHy" startTime := time.Now().Add(time.Minute) duration := 2 * 7 * 24 * time.Hour // 2 weeks weight := units.Schmeckle @@ -32,43 +32,64 @@ func main() { } ctx := context.Background() - infoClient := info.NewClient(uri) + /* + infoClient := info.NewClient(uri) - nodeInfoStartTime := time.Now() - nodeID, _, err := infoClient.GetNodeID(ctx) - if err != nil { - log.Fatalf("failed to fetch node IDs: %s\n", err) - } - log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime)) + nodeInfoStartTime := time.Now() + nodeID, _, err := infoClient.GetNodeID(ctx) + if err != nil { + log.Fatalf("failed to fetch node IDs: %s\n", err) + } + log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime))*/ - // MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that - // [uri] is hosting and registers [subnetID]. - walletSyncStartTime := time.Now() - wallet, err := primary.MakePWallet( - ctx, - uri, - kc, - primary.WalletConfig{ - SubnetIDs: []ids.ID{subnetID}, - }, - ) - if err != nil { - log.Fatalf("failed to initialize wallet: %s\n", err) - } - log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + for _, nodeIDHex := range []string{ + "0x479f66c8be895830547e70b4b298cafd433dba6e1ebdfb85", + "0xde31b4d8b22991d51aa6aa1fc733f23a851a8c9427f780c8", + "0xe9094f73698002fd52c90819b457b9fbc866ab80727952c7", + "0xaa18d3991cf637aa6c162f5e95cf163f69cd82913f89fa2e", + "0xf29bce5f34a74301eb0de716d5194e4a4aea5d7ae0cb875e", + } { + //formatting.Encode(formatting.Hex, tx.Bytes()) + + nodeIDBytes, err := formatting.Decode(formatting.Hex, nodeIDHex) + if err != nil { + log.Fatalf("failed to decode node ID %q: %s\n", nodeIDHex, err) + } + + var nodeID ids.NodeID + copy(nodeID[:], nodeIDBytes) + + // MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that + // [uri] is hosting and registers [subnetID]. + walletSyncStartTime := time.Now() + wallet, err := primary.MakePWallet( + ctx, + uri, + kc, + primary.WalletConfig{ + SubnetIDs: []ids.ID{subnetID}, + }, + ) + if err != nil { + log.Fatalf("failed to initialize wallet: %s\n", err) + } + log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime)) + + addValidatorStartTime := time.Now() + addValidatorTx, err := wallet.IssueAddSubnetValidatorTx(&txs.SubnetValidator{ + Validator: txs.Validator{ + NodeID: nodeID, + Start: uint64(startTime.Unix()), + End: uint64(startTime.Add(duration).Unix()), + Wght: weight, + }, + Subnet: subnetID, + }) + if err != nil { + log.Fatalf("failed to issue add subnet validator transaction: %s\n", err) + } + log.Printf("added new subnet validator %s to %s with %s in %s\n", nodeID, subnetID, addValidatorTx.ID(), time.Since(addValidatorStartTime)) - addValidatorStartTime := time.Now() - addValidatorTx, err := wallet.IssueAddSubnetValidatorTx(&txs.SubnetValidator{ - Validator: txs.Validator{ - NodeID: nodeID, - Start: uint64(startTime.Unix()), - End: uint64(startTime.Add(duration).Unix()), - Wght: weight, - }, - Subnet: subnetID, - }) - if err != nil { - log.Fatalf("failed to issue add subnet validator transaction: %s\n", err) } - log.Printf("added new subnet validator %s to %s with %s in %s\n", nodeID, subnetID, addValidatorTx.ID(), time.Since(addValidatorStartTime)) + } diff --git a/wallet/subnet/primary/examples/create-chain/main.go b/wallet/subnet/primary/examples/create-chain/main.go index db83f2051a5e..f59cc3612cac 100644 --- a/wallet/subnet/primary/examples/create-chain/main.go +++ b/wallet/subnet/primary/examples/create-chain/main.go @@ -6,7 +6,7 @@ package main import ( "context" "log" - "math" + "os" "time" "github.com/ava-labs/avalanchego/genesis" @@ -14,35 +14,25 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary" - - xsgenesis "github.com/ava-labs/avalanchego/vms/example/xsvm/genesis" ) func main() { key := genesis.EWOQKey uri := primary.LocalAPIURI kc := secp256k1fx.NewKeychain(key) - subnetIDStr := "29uVeLPJB1eQJkzRemU8g8wZDw5uJRqpab5U2mX9euieVwiEbL" - genesis := &xsgenesis.Genesis{ - Timestamp: time.Now().Unix(), - Allocations: []xsgenesis.Allocation{ - { - Address: genesis.EWOQKey.Address(), - Balance: math.MaxUint64, - }, - }, - } - vmID := constants.XSVMID - name := "let there" + subnetIDStr := "BKBZ6xXTnT86B4L5fp8rvtcmNSpvtNz8En9jG61ywV2uWyeHy" - subnetID, err := ids.FromString(subnetIDStr) + vmID := constants.SubnetEVMID + name := "simplexvm" + + genesisBytes, err := os.ReadFile("/Users/yacov.manevich/.avalanche-cli/subnets/yak/genesis.json") if err != nil { - log.Fatalf("failed to parse subnet ID: %s\n", err) + log.Fatalf("failed to read genesis file: %s\n", err) } - genesisBytes, err := xsgenesis.Codec.Marshal(xsgenesis.CodecVersion, genesis) + subnetID, err := ids.FromString(subnetIDStr) if err != nil { - log.Fatalf("failed to create genesis bytes: %s\n", err) + log.Fatalf("failed to parse subnet ID: %s\n", err) } ctx := context.Background()