From c4a034eb43b1520299568dc2105ff34f46a565c2 Mon Sep 17 00:00:00 2001 From: Michael Sutton Date: Mon, 28 Mar 2022 23:41:59 +0300 Subject: [PATCH] Optimize the miner-kaspad flow and latency (#1988) * protobuf for new block template notification structs * appmessage and wire for new block template notification structs * Set up the entire handler/call-chain for managing the new-block-template event --- app/appmessage/message.go | 6 + .../rpc_notify_new_block_template.go | 50 +++++ app/component_manager.go | 1 + app/protocol/flowcontext/blocks.go | 13 ++ app/protocol/flowcontext/flow_context.go | 9 + .../flows/v4/blockrelay/handle_relay_invs.go | 12 +- app/protocol/flows/v4/blockrelay/ibd.go | 5 + .../flows/v5/blockrelay/handle_relay_invs.go | 12 +- app/protocol/flows/v5/blockrelay/ibd.go | 5 + app/protocol/manager.go | 5 + app/rpc/manager.go | 7 + app/rpc/rpc.go | 1 + app/rpc/rpccontext/notificationmanager.go | 27 +++ .../rpchandlers/notify_new_block_template.go | 19 ++ cmd/kaspaminer/client.go | 14 +- cmd/kaspaminer/mineloop.go | 2 +- .../grpcserver/protowire/messages.pb.go | 116 ++++++++-- .../grpcserver/protowire/messages.proto | 3 + .../server/grpcserver/protowire/rpc.md | 44 ++++ .../server/grpcserver/protowire/rpc.pb.go | 204 +++++++++++++++++- .../server/grpcserver/protowire/rpc.proto | 18 ++ .../rpc_notify_new_block_template.go | 66 ++++++ .../server/grpcserver/protowire/wire.go | 21 ++ .../rpcclient/rpc_on_new_block_template.go | 38 ++++ 24 files changed, 656 insertions(+), 42 deletions(-) create mode 100644 app/appmessage/rpc_notify_new_block_template.go create mode 100644 app/rpc/rpchandlers/notify_new_block_template.go create mode 100644 infrastructure/network/netadapter/server/grpcserver/protowire/rpc_notify_new_block_template.go create mode 100644 infrastructure/network/rpcclient/rpc_on_new_block_template.go diff --git a/app/appmessage/message.go b/app/appmessage/message.go index b0a0b2f6b..6296c9328 100644 --- a/app/appmessage/message.go +++ b/app/appmessage/message.go @@ -156,6 +156,9 @@ const ( CmdVirtualDaaScoreChangedNotificationMessage CmdGetBalancesByAddressesRequestMessage CmdGetBalancesByAddressesResponseMessage + CmdNotifyNewBlockTemplateRequestMessage + CmdNotifyNewBlockTemplateResponseMessage + CmdNewBlockTemplateNotificationMessage ) // ProtocolMessageCommandToString maps all MessageCommands to their string representation @@ -286,6 +289,9 @@ var RPCMessageCommandToString = map[MessageCommand]string{ CmdVirtualDaaScoreChangedNotificationMessage: "VirtualDaaScoreChangedNotification", CmdGetBalancesByAddressesRequestMessage: "GetBalancesByAddressesRequest", CmdGetBalancesByAddressesResponseMessage: "GetBalancesByAddressesResponse", + CmdNotifyNewBlockTemplateRequestMessage: "NotifyNewBlockTemplateRequest", + CmdNotifyNewBlockTemplateResponseMessage: "NotifyNewBlockTemplateResponse", + CmdNewBlockTemplateNotificationMessage: "NewBlockTemplateNotification", } // Message is an interface that describes a kaspa message. A type that diff --git a/app/appmessage/rpc_notify_new_block_template.go b/app/appmessage/rpc_notify_new_block_template.go new file mode 100644 index 000000000..185fef5b6 --- /dev/null +++ b/app/appmessage/rpc_notify_new_block_template.go @@ -0,0 +1,50 @@ +package appmessage + +// NotifyNewBlockTemplateRequestMessage is an appmessage corresponding to +// its respective RPC message +type NotifyNewBlockTemplateRequestMessage struct { + baseMessage +} + +// Command returns the protocol command string for the message +func (msg *NotifyNewBlockTemplateRequestMessage) Command() MessageCommand { + return CmdNotifyNewBlockTemplateRequestMessage +} + +// NewNotifyNewBlockTemplateRequestMessage returns an instance of the message +func NewNotifyNewBlockTemplateRequestMessage() *NotifyNewBlockTemplateRequestMessage { + return &NotifyNewBlockTemplateRequestMessage{} +} + +// NotifyNewBlockTemplateResponseMessage is an appmessage corresponding to +// its respective RPC message +type NotifyNewBlockTemplateResponseMessage struct { + baseMessage + Error *RPCError +} + +// Command returns the protocol command string for the message +func (msg *NotifyNewBlockTemplateResponseMessage) Command() MessageCommand { + return CmdNotifyNewBlockTemplateResponseMessage +} + +// NewNotifyNewBlockTemplateResponseMessage returns an instance of the message +func NewNotifyNewBlockTemplateResponseMessage() *NotifyNewBlockTemplateResponseMessage { + return &NotifyNewBlockTemplateResponseMessage{} +} + +// NewBlockTemplateNotificationMessage is an appmessage corresponding to +// its respective RPC message +type NewBlockTemplateNotificationMessage struct { + baseMessage +} + +// Command returns the protocol command string for the message +func (msg *NewBlockTemplateNotificationMessage) Command() MessageCommand { + return CmdNewBlockTemplateNotificationMessage +} + +// NewNewBlockTemplateNotificationMessage returns an instance of the message +func NewNewBlockTemplateNotificationMessage() *NewBlockTemplateNotificationMessage { + return &NewBlockTemplateNotificationMessage{} +} diff --git a/app/component_manager.go b/app/component_manager.go index b288bd487..88eff5031 100644 --- a/app/component_manager.go +++ b/app/component_manager.go @@ -153,6 +153,7 @@ func setupRPC( shutDownChan, ) protocolManager.SetOnVirtualChange(rpcManager.NotifyVirtualChange) + protocolManager.SetOnNewBlockTemplateHandler(rpcManager.NotifyNewBlockTemplate) protocolManager.SetOnBlockAddedToDAGHandler(rpcManager.NotifyBlockAddedToDAG) protocolManager.SetOnPruningPointUTXOSetOverrideHandler(rpcManager.NotifyPruningPointUTXOSetOverride) diff --git a/app/protocol/flowcontext/blocks.go b/app/protocol/flowcontext/blocks.go index 65eefcc9c..47f4d1d76 100644 --- a/app/protocol/flowcontext/blocks.go +++ b/app/protocol/flowcontext/blocks.go @@ -68,6 +68,15 @@ func (f *FlowContext) OnVirtualChange(virtualChangeSet *externalapi.VirtualChang return nil } +// OnNewBlockTemplate calls the handler function whenever a new block template is available for miners. +func (f *FlowContext) OnNewBlockTemplate() error { + if f.onNewBlockTemplateHandler != nil { + return f.onNewBlockTemplateHandler() + } + + return nil +} + // OnPruningPointUTXOSetOverride calls the handler function whenever the UTXO set // resets due to pruning point change via IBD. func (f *FlowContext) OnPruningPointUTXOSetOverride() error { @@ -125,6 +134,10 @@ func (f *FlowContext) AddBlock(block *externalapi.DomainBlock) error { } return err } + err = f.OnNewBlockTemplate() + if err != nil { + return err + } err = f.OnNewBlock(block, virtualChangeSet) if err != nil { return err diff --git a/app/protocol/flowcontext/flow_context.go b/app/protocol/flowcontext/flow_context.go index 8c9d2e5fe..d99903af4 100644 --- a/app/protocol/flowcontext/flow_context.go +++ b/app/protocol/flowcontext/flow_context.go @@ -25,6 +25,9 @@ type OnBlockAddedToDAGHandler func(block *externalapi.DomainBlock, virtualChange // OnVirtualChangeHandler is a handler function that's triggered when the virtual changes type OnVirtualChangeHandler func(virtualChangeSet *externalapi.VirtualChangeSet) error +// OnNewBlockTemplateHandler is a handler function that's triggered when a new block template is available +type OnNewBlockTemplateHandler func() error + // OnPruningPointUTXOSetOverrideHandler is a handle function that's triggered whenever the UTXO set // resets due to pruning point change via IBD. type OnPruningPointUTXOSetOverrideHandler func() error @@ -46,6 +49,7 @@ type FlowContext struct { onVirtualChangeHandler OnVirtualChangeHandler onBlockAddedToDAGHandler OnBlockAddedToDAGHandler + onNewBlockTemplateHandler OnNewBlockTemplateHandler onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler onTransactionAddedToMempoolHandler OnTransactionAddedToMempoolHandler @@ -112,6 +116,11 @@ func (f *FlowContext) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler OnBlo f.onBlockAddedToDAGHandler = onBlockAddedToDAGHandler } +// SetOnNewBlockTemplateHandler sets the onNewBlockTemplateHandler handler +func (f *FlowContext) SetOnNewBlockTemplateHandler(onNewBlockTemplateHandler OnNewBlockTemplateHandler) { + f.onNewBlockTemplateHandler = onNewBlockTemplateHandler +} + // SetOnPruningPointUTXOSetOverrideHandler sets the onPruningPointUTXOSetOverrideHandler handler func (f *FlowContext) SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler OnPruningPointUTXOSetOverrideHandler) { f.onPruningPointUTXOSetOverrideHandler = onPruningPointUTXOSetOverrideHandler diff --git a/app/protocol/flows/v4/blockrelay/handle_relay_invs.go b/app/protocol/flows/v4/blockrelay/handle_relay_invs.go index 140a9abfd..9abf3d706 100644 --- a/app/protocol/flows/v4/blockrelay/handle_relay_invs.go +++ b/app/protocol/flows/v4/blockrelay/handle_relay_invs.go @@ -27,6 +27,7 @@ type RelayInvsContext interface { Config() *config.Config OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error + OnNewBlockTemplate() error OnPruningPointUTXOSetOverride() error SharedRequestedBlocks() *flowcontext.SharedRequestedBlocks Broadcast(message appmessage.Message) error @@ -168,11 +169,12 @@ func (flow *handleRelayInvsFlow) start() error { return err } + virtualHasNewParents := false for _, parent := range newVirtualInfo.ParentHashes { if oldVirtualParents.Contains(parent) { continue } - + virtualHasNewParents = true block, err := flow.Domain().Consensus().GetBlock(parent) if err != nil { return err @@ -185,6 +187,14 @@ func (flow *handleRelayInvsFlow) start() error { } } + if virtualHasNewParents { + log.Debugf("Virtual %d has new parents, raising new block template event", newVirtualInfo.DAAScore) + err = flow.OnNewBlockTemplate() + if err != nil { + return err + } + } + log.Infof("Accepted block %s via relay", inv.Hash) err = flow.OnNewBlock(block, virtualChangeSet) if err != nil { diff --git a/app/protocol/flows/v4/blockrelay/ibd.go b/app/protocol/flows/v4/blockrelay/ibd.go index a81561198..72c2b6e76 100644 --- a/app/protocol/flows/v4/blockrelay/ibd.go +++ b/app/protocol/flows/v4/blockrelay/ibd.go @@ -25,6 +25,7 @@ type IBDContext interface { Config() *config.Config OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error + OnNewBlockTemplate() error OnPruningPointUTXOSetOverride() error IsIBDRunning() bool TrySetIBDRunning(ibdPeer *peerpkg.Peer) bool @@ -639,6 +640,10 @@ func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64) if isCompletelyResolved { log.Infof("Resolved virtual") + err = flow.OnNewBlockTemplate() + if err != nil { + return err + } return nil } } diff --git a/app/protocol/flows/v5/blockrelay/handle_relay_invs.go b/app/protocol/flows/v5/blockrelay/handle_relay_invs.go index 140a9abfd..9abf3d706 100644 --- a/app/protocol/flows/v5/blockrelay/handle_relay_invs.go +++ b/app/protocol/flows/v5/blockrelay/handle_relay_invs.go @@ -27,6 +27,7 @@ type RelayInvsContext interface { Config() *config.Config OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error + OnNewBlockTemplate() error OnPruningPointUTXOSetOverride() error SharedRequestedBlocks() *flowcontext.SharedRequestedBlocks Broadcast(message appmessage.Message) error @@ -168,11 +169,12 @@ func (flow *handleRelayInvsFlow) start() error { return err } + virtualHasNewParents := false for _, parent := range newVirtualInfo.ParentHashes { if oldVirtualParents.Contains(parent) { continue } - + virtualHasNewParents = true block, err := flow.Domain().Consensus().GetBlock(parent) if err != nil { return err @@ -185,6 +187,14 @@ func (flow *handleRelayInvsFlow) start() error { } } + if virtualHasNewParents { + log.Debugf("Virtual %d has new parents, raising new block template event", newVirtualInfo.DAAScore) + err = flow.OnNewBlockTemplate() + if err != nil { + return err + } + } + log.Infof("Accepted block %s via relay", inv.Hash) err = flow.OnNewBlock(block, virtualChangeSet) if err != nil { diff --git a/app/protocol/flows/v5/blockrelay/ibd.go b/app/protocol/flows/v5/blockrelay/ibd.go index 2b40e724e..582a6a475 100644 --- a/app/protocol/flows/v5/blockrelay/ibd.go +++ b/app/protocol/flows/v5/blockrelay/ibd.go @@ -22,6 +22,7 @@ type IBDContext interface { Config() *config.Config OnNewBlock(block *externalapi.DomainBlock, virtualChangeSet *externalapi.VirtualChangeSet) error OnVirtualChange(virtualChangeSet *externalapi.VirtualChangeSet) error + OnNewBlockTemplate() error OnPruningPointUTXOSetOverride() error IsIBDRunning() bool TrySetIBDRunning(ibdPeer *peerpkg.Peer) bool @@ -717,6 +718,10 @@ func (flow *handleIBDFlow) resolveVirtual(estimatedVirtualDAAScoreTarget uint64) if isCompletelyResolved { log.Infof("Resolved virtual") + err = flow.OnNewBlockTemplate() + if err != nil { + return err + } return nil } } diff --git a/app/protocol/manager.go b/app/protocol/manager.go index b953f63cb..0bdea77a2 100644 --- a/app/protocol/manager.go +++ b/app/protocol/manager.go @@ -100,6 +100,11 @@ func (m *Manager) SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler flowconte m.context.SetOnBlockAddedToDAGHandler(onBlockAddedToDAGHandler) } +// SetOnNewBlockTemplateHandler sets the onNewBlockTemplate handler +func (m *Manager) SetOnNewBlockTemplateHandler(onNewBlockTemplateHandler flowcontext.OnNewBlockTemplateHandler) { + m.context.SetOnNewBlockTemplateHandler(onNewBlockTemplateHandler) +} + // SetOnPruningPointUTXOSetOverrideHandler sets the OnPruningPointUTXOSetOverride handler func (m *Manager) SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler flowcontext.OnPruningPointUTXOSetOverrideHandler) { m.context.SetOnPruningPointUTXOSetOverrideHandler(onPruningPointUTXOSetOverrideHandler) diff --git a/app/rpc/manager.go b/app/rpc/manager.go index ff77665a6..8189b33c0 100644 --- a/app/rpc/manager.go +++ b/app/rpc/manager.go @@ -96,6 +96,13 @@ func (m *Manager) NotifyVirtualChange(virtualChangeSet *externalapi.VirtualChang return nil } +// NotifyNewBlockTemplate notifies the manager that a new +// block template is available for miners +func (m *Manager) NotifyNewBlockTemplate() error { + notification := appmessage.NewNewBlockTemplateNotificationMessage() + return m.context.NotificationManager.NotifyNewBlockTemplate(notification) +} + // NotifyPruningPointUTXOSetOverride notifies the manager whenever the UTXO index // resets due to pruning point change via IBD. func (m *Manager) NotifyPruningPointUTXOSetOverride() error { diff --git a/app/rpc/rpc.go b/app/rpc/rpc.go index f4f7da3bd..4aba79816 100644 --- a/app/rpc/rpc.go +++ b/app/rpc/rpc.go @@ -48,6 +48,7 @@ var handlers = map[appmessage.MessageCommand]handler{ appmessage.CmdStopNotifyingPruningPointUTXOSetOverrideRequestMessage: rpchandlers.HandleStopNotifyingPruningPointUTXOSetOverrideRequest, appmessage.CmdEstimateNetworkHashesPerSecondRequestMessage: rpchandlers.HandleEstimateNetworkHashesPerSecond, appmessage.CmdNotifyVirtualDaaScoreChangedRequestMessage: rpchandlers.HandleNotifyVirtualDaaScoreChanged, + appmessage.CmdNotifyNewBlockTemplateRequestMessage: rpchandlers.HandleNotifyNewBlockTemplate, } func (m *Manager) routerInitializer(router *router.Router, netConnection *netadapter.NetConnection) { diff --git a/app/rpc/rpccontext/notificationmanager.go b/app/rpc/rpccontext/notificationmanager.go index c75e79195..77e8386d3 100644 --- a/app/rpc/rpccontext/notificationmanager.go +++ b/app/rpc/rpccontext/notificationmanager.go @@ -32,6 +32,7 @@ type NotificationListener struct { propagateVirtualSelectedParentBlueScoreChangedNotifications bool propagateVirtualDaaScoreChangedNotifications bool propagatePruningPointUTXOSetOverrideNotifications bool + propagateNewBlockTemplateNotifications bool propagateUTXOsChangedNotificationAddresses map[utxoindex.ScriptPublicKeyString]*UTXOsChangedNotificationAddress } @@ -201,6 +202,25 @@ func (nm *NotificationManager) NotifyVirtualDaaScoreChanged( return nil } +// NotifyNewBlockTemplate notifies the notification manager that a new +// block template is available for miners +func (nm *NotificationManager) NotifyNewBlockTemplate( + notification *appmessage.NewBlockTemplateNotificationMessage) error { + + nm.RLock() + defer nm.RUnlock() + + for router, listener := range nm.listeners { + if listener.propagateNewBlockTemplateNotifications { + err := router.OutgoingRoute().Enqueue(notification) + if err != nil { + return err + } + } + } + return nil +} + // NotifyPruningPointUTXOSetOverride notifies the notification manager that the UTXO index // reset due to pruning point change via IBD. func (nm *NotificationManager) NotifyPruningPointUTXOSetOverride() error { @@ -226,6 +246,7 @@ func newNotificationListener() *NotificationListener { propagateFinalityConflictResolvedNotifications: false, propagateUTXOsChangedNotifications: false, propagateVirtualSelectedParentBlueScoreChangedNotifications: false, + propagateNewBlockTemplateNotifications: false, propagatePruningPointUTXOSetOverrideNotifications: false, } } @@ -334,6 +355,12 @@ func (nl *NotificationListener) PropagateVirtualDaaScoreChangedNotifications() { nl.propagateVirtualDaaScoreChangedNotifications = true } +// PropagateNewBlockTemplateNotifications instructs the listener to send +// new block template notifications to the remote listener +func (nl *NotificationListener) PropagateNewBlockTemplateNotifications() { + nl.propagateNewBlockTemplateNotifications = true +} + // PropagatePruningPointUTXOSetOverrideNotifications instructs the listener to send pruning point UTXO set override notifications // to the remote listener. func (nl *NotificationListener) PropagatePruningPointUTXOSetOverrideNotifications() { diff --git a/app/rpc/rpchandlers/notify_new_block_template.go b/app/rpc/rpchandlers/notify_new_block_template.go new file mode 100644 index 000000000..fc1dcedcd --- /dev/null +++ b/app/rpc/rpchandlers/notify_new_block_template.go @@ -0,0 +1,19 @@ +package rpchandlers + +import ( + "github.com/kaspanet/kaspad/app/appmessage" + "github.com/kaspanet/kaspad/app/rpc/rpccontext" + "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" +) + +// HandleNotifyNewBlockTemplate handles the respectively named RPC command +func HandleNotifyNewBlockTemplate(context *rpccontext.Context, router *router.Router, _ appmessage.Message) (appmessage.Message, error) { + listener, err := context.NotificationManager.Listener(router) + if err != nil { + return nil, err + } + listener.PropagateNewBlockTemplateNotifications() + + response := appmessage.NewNotifyNewBlockTemplateResponseMessage() + return response, nil +} diff --git a/cmd/kaspaminer/client.go b/cmd/kaspaminer/client.go index 370518886..2602eee19 100644 --- a/cmd/kaspaminer/client.go +++ b/cmd/kaspaminer/client.go @@ -13,8 +13,8 @@ const minerTimeout = 10 * time.Second type minerClient struct { *rpcclient.RPCClient - cfg *configFlags - blockAddedNotificationChan chan struct{} + cfg *configFlags + newBlockTemplateNotificationChan chan struct{} } func (mc *minerClient) connect() error { @@ -30,14 +30,14 @@ func (mc *minerClient) connect() error { mc.SetTimeout(minerTimeout) mc.SetLogger(backendLog, logger.LevelTrace) - err = mc.RegisterForBlockAddedNotifications(func(_ *appmessage.BlockAddedNotificationMessage) { + err = mc.RegisterForNewBlockTemplateNotifications(func(_ *appmessage.NewBlockTemplateNotificationMessage) { select { - case mc.blockAddedNotificationChan <- struct{}{}: + case mc.newBlockTemplateNotificationChan <- struct{}{}: default: } }) if err != nil { - return errors.Wrapf(err, "error requesting block-added notifications") + return errors.Wrapf(err, "error requesting new-block-template notifications") } log.Infof("Connected to %s", rpcAddress) @@ -47,8 +47,8 @@ func (mc *minerClient) connect() error { func newMinerClient(cfg *configFlags) (*minerClient, error) { minerClient := &minerClient{ - cfg: cfg, - blockAddedNotificationChan: make(chan struct{}), + cfg: cfg, + newBlockTemplateNotificationChan: make(chan struct{}), } err := minerClient.connect() diff --git a/cmd/kaspaminer/mineloop.go b/cmd/kaspaminer/mineloop.go index 0ecf3cf94..9caf104d6 100644 --- a/cmd/kaspaminer/mineloop.go +++ b/cmd/kaspaminer/mineloop.go @@ -217,7 +217,7 @@ func templatesLoop(client *minerClient, miningAddr util.Address, errChan chan er ticker := time.NewTicker(tickerTime) for { select { - case <-client.blockAddedNotificationChan: + case <-client.newBlockTemplateNotificationChan: getBlockTemplate() ticker.Reset(tickerTime) case <-ticker.C: diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/messages.pb.go b/infrastructure/network/netadapter/server/grpcserver/protowire/messages.pb.go index 8c08053e3..fca251121 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/messages.pb.go +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/messages.pb.go @@ -149,6 +149,9 @@ type KaspadMessage struct { // *KaspadMessage_GetBalanceByAddressResponse // *KaspadMessage_GetBalancesByAddressesRequest // *KaspadMessage_GetBalancesByAddressesResponse + // *KaspadMessage_NotifyNewBlockTemplateRequest + // *KaspadMessage_NotifyNewBlockTemplateResponse + // *KaspadMessage_NewBlockTemplateNotification Payload isKaspadMessage_Payload `protobuf_oneof:"payload"` } @@ -1052,6 +1055,27 @@ func (x *KaspadMessage) GetGetBalancesByAddressesResponse() *GetBalancesByAddres return nil } +func (x *KaspadMessage) GetNotifyNewBlockTemplateRequest() *NotifyNewBlockTemplateRequestMessage { + if x, ok := x.GetPayload().(*KaspadMessage_NotifyNewBlockTemplateRequest); ok { + return x.NotifyNewBlockTemplateRequest + } + return nil +} + +func (x *KaspadMessage) GetNotifyNewBlockTemplateResponse() *NotifyNewBlockTemplateResponseMessage { + if x, ok := x.GetPayload().(*KaspadMessage_NotifyNewBlockTemplateResponse); ok { + return x.NotifyNewBlockTemplateResponse + } + return nil +} + +func (x *KaspadMessage) GetNewBlockTemplateNotification() *NewBlockTemplateNotificationMessage { + if x, ok := x.GetPayload().(*KaspadMessage_NewBlockTemplateNotification); ok { + return x.NewBlockTemplateNotification + } + return nil +} + type isKaspadMessage_Payload interface { isKaspadMessage_Payload() } @@ -1548,6 +1572,18 @@ type KaspadMessage_GetBalancesByAddressesResponse struct { GetBalancesByAddressesResponse *GetBalancesByAddressesResponseMessage `protobuf:"bytes,1080,opt,name=getBalancesByAddressesResponse,proto3,oneof"` } +type KaspadMessage_NotifyNewBlockTemplateRequest struct { + NotifyNewBlockTemplateRequest *NotifyNewBlockTemplateRequestMessage `protobuf:"bytes,1081,opt,name=notifyNewBlockTemplateRequest,proto3,oneof"` +} + +type KaspadMessage_NotifyNewBlockTemplateResponse struct { + NotifyNewBlockTemplateResponse *NotifyNewBlockTemplateResponseMessage `protobuf:"bytes,1082,opt,name=notifyNewBlockTemplateResponse,proto3,oneof"` +} + +type KaspadMessage_NewBlockTemplateNotification struct { + NewBlockTemplateNotification *NewBlockTemplateNotificationMessage `protobuf:"bytes,1083,opt,name=newBlockTemplateNotification,proto3,oneof"` +} + func (*KaspadMessage_Addresses) isKaspadMessage_Payload() {} func (*KaspadMessage_Block) isKaspadMessage_Payload() {} @@ -1794,13 +1830,19 @@ func (*KaspadMessage_GetBalancesByAddressesRequest) isKaspadMessage_Payload() {} func (*KaspadMessage_GetBalancesByAddressesResponse) isKaspadMessage_Payload() {} +func (*KaspadMessage_NotifyNewBlockTemplateRequest) isKaspadMessage_Payload() {} + +func (*KaspadMessage_NotifyNewBlockTemplateResponse) isKaspadMessage_Payload() {} + +func (*KaspadMessage_NewBlockTemplateNotification) isKaspadMessage_Payload() {} + var File_messages_proto protoreflect.FileDescriptor var file_messages_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x1a, 0x09, 0x70, 0x32, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x09, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0xf3, 0x66, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, + 0x6f, 0x22, 0xe1, 0x69, 0x0a, 0x0d, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x4d, 0x65, 0x73, 0x73, @@ -2622,21 +2664,44 @@ var file_messages_proto_rawDesc = []byte{ 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x1e, 0x67, 0x65, 0x74, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x42, 0x79, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x09, 0x0a, 0x07, - 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12, 0x49, + 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x1d, + 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0xb9, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, + 0x2e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x1d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, + 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7b, 0x0a, 0x1e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0xba, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x48, 0x00, 0x52, 0x1e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x1c, 0x6e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0xbb, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x1c, 0x6e, 0x65, + 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x70, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x32, 0x50, 0x0a, 0x03, 0x50, 0x32, 0x50, 0x12, 0x49, 0x0a, 0x0d, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, + 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50, 0x43, 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x32, 0x50, 0x0a, 0x03, 0x52, 0x50, 0x43, - 0x12, 0x49, 0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, - 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x18, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x4b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x26, 0x5a, 0x24, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, - 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, - 0x69, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x67, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, + 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2776,6 +2841,9 @@ var file_messages_proto_goTypes = []interface{}{ (*GetBalanceByAddressResponseMessage)(nil), // 120: protowire.GetBalanceByAddressResponseMessage (*GetBalancesByAddressesRequestMessage)(nil), // 121: protowire.GetBalancesByAddressesRequestMessage (*GetBalancesByAddressesResponseMessage)(nil), // 122: protowire.GetBalancesByAddressesResponseMessage + (*NotifyNewBlockTemplateRequestMessage)(nil), // 123: protowire.NotifyNewBlockTemplateRequestMessage + (*NotifyNewBlockTemplateResponseMessage)(nil), // 124: protowire.NotifyNewBlockTemplateResponseMessage + (*NewBlockTemplateNotificationMessage)(nil), // 125: protowire.NewBlockTemplateNotificationMessage } var file_messages_proto_depIdxs = []int32{ 1, // 0: protowire.KaspadMessage.addresses:type_name -> protowire.AddressesMessage @@ -2901,15 +2969,18 @@ var file_messages_proto_depIdxs = []int32{ 120, // 120: protowire.KaspadMessage.getBalanceByAddressResponse:type_name -> protowire.GetBalanceByAddressResponseMessage 121, // 121: protowire.KaspadMessage.getBalancesByAddressesRequest:type_name -> protowire.GetBalancesByAddressesRequestMessage 122, // 122: protowire.KaspadMessage.getBalancesByAddressesResponse:type_name -> protowire.GetBalancesByAddressesResponseMessage - 0, // 123: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage - 0, // 124: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage - 0, // 125: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage - 0, // 126: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage - 125, // [125:127] is the sub-list for method output_type - 123, // [123:125] is the sub-list for method input_type - 123, // [123:123] is the sub-list for extension type_name - 123, // [123:123] is the sub-list for extension extendee - 0, // [0:123] is the sub-list for field type_name + 123, // 123: protowire.KaspadMessage.notifyNewBlockTemplateRequest:type_name -> protowire.NotifyNewBlockTemplateRequestMessage + 124, // 124: protowire.KaspadMessage.notifyNewBlockTemplateResponse:type_name -> protowire.NotifyNewBlockTemplateResponseMessage + 125, // 125: protowire.KaspadMessage.newBlockTemplateNotification:type_name -> protowire.NewBlockTemplateNotificationMessage + 0, // 126: protowire.P2P.MessageStream:input_type -> protowire.KaspadMessage + 0, // 127: protowire.RPC.MessageStream:input_type -> protowire.KaspadMessage + 0, // 128: protowire.P2P.MessageStream:output_type -> protowire.KaspadMessage + 0, // 129: protowire.RPC.MessageStream:output_type -> protowire.KaspadMessage + 128, // [128:130] is the sub-list for method output_type + 126, // [126:128] is the sub-list for method input_type + 126, // [126:126] is the sub-list for extension type_name + 126, // [126:126] is the sub-list for extension extendee + 0, // [0:126] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -3057,6 +3128,9 @@ func file_messages_proto_init() { (*KaspadMessage_GetBalanceByAddressResponse)(nil), (*KaspadMessage_GetBalancesByAddressesRequest)(nil), (*KaspadMessage_GetBalancesByAddressesResponse)(nil), + (*KaspadMessage_NotifyNewBlockTemplateRequest)(nil), + (*KaspadMessage_NotifyNewBlockTemplateResponse)(nil), + (*KaspadMessage_NewBlockTemplateNotification)(nil), } type x struct{} out := protoimpl.TypeBuilder{ diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/messages.proto b/infrastructure/network/netadapter/server/grpcserver/protowire/messages.proto index 30d471704..8d62e83a4 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/messages.proto +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/messages.proto @@ -132,6 +132,9 @@ message KaspadMessage { GetBalanceByAddressResponseMessage getBalanceByAddressResponse = 1078; GetBalancesByAddressesRequestMessage getBalancesByAddressesRequest = 1079; GetBalancesByAddressesResponseMessage getBalancesByAddressesResponse = 1080; + NotifyNewBlockTemplateRequestMessage notifyNewBlockTemplateRequest = 1081; + NotifyNewBlockTemplateResponseMessage notifyNewBlockTemplateResponse = 1082; + NewBlockTemplateNotificationMessage newBlockTemplateNotification = 1083; } } diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.md b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.md index e38f3f65f..0b674d3da 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.md +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.md @@ -103,6 +103,9 @@ - [GetInfoResponseMessage](#protowire.GetInfoResponseMessage) - [EstimateNetworkHashesPerSecondRequestMessage](#protowire.EstimateNetworkHashesPerSecondRequestMessage) - [EstimateNetworkHashesPerSecondResponseMessage](#protowire.EstimateNetworkHashesPerSecondResponseMessage) + - [NotifyNewBlockTemplateRequestMessage](#protowire.NotifyNewBlockTemplateRequestMessage) + - [NotifyNewBlockTemplateResponseMessage](#protowire.NotifyNewBlockTemplateResponseMessage) + - [NewBlockTemplateNotificationMessage](#protowire.NewBlockTemplateNotificationMessage) - [SubmitBlockResponseMessage.RejectReason](#protowire.SubmitBlockResponseMessage.RejectReason) @@ -1694,6 +1697,47 @@ GetInfoRequestMessage returns info about the node. + + + +### NotifyNewBlockTemplateRequestMessage +NotifyNewBlockTemplateRequestMessage registers this connection for +NewBlockTemplate notifications. + +See: NewBlockTemplateNotificationMessage + + + + + + + + +### NotifyNewBlockTemplateResponseMessage + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| error | [RPCError](#protowire.RPCError) | | | + + + + + + + + +### NewBlockTemplateNotificationMessage +NewBlockTemplateNotificationMessage is sent whenever a new updated block template is +available for miners. + +See NotifyNewBlockTemplateRequestMessage + + + + + diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.pb.go b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.pb.go index b9437f0a6..79a66a4cb 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.pb.go +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.pb.go @@ -5542,6 +5542,137 @@ func (x *EstimateNetworkHashesPerSecondResponseMessage) GetError() *RPCError { return nil } +// NotifyNewBlockTemplateRequestMessage registers this connection for +// NewBlockTemplate notifications. +// +// See: NewBlockTemplateNotificationMessage +type NotifyNewBlockTemplateRequestMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NotifyNewBlockTemplateRequestMessage) Reset() { + *x = NotifyNewBlockTemplateRequestMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyNewBlockTemplateRequestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyNewBlockTemplateRequestMessage) ProtoMessage() {} + +func (x *NotifyNewBlockTemplateRequestMessage) ProtoReflect() protoreflect.Message { + mi := &file_rpc_proto_msgTypes[99] + 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 NotifyNewBlockTemplateRequestMessage.ProtoReflect.Descriptor instead. +func (*NotifyNewBlockTemplateRequestMessage) Descriptor() ([]byte, []int) { + return file_rpc_proto_rawDescGZIP(), []int{99} +} + +type NotifyNewBlockTemplateResponseMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Error *RPCError `protobuf:"bytes,1000,opt,name=error,proto3" json:"error,omitempty"` +} + +func (x *NotifyNewBlockTemplateResponseMessage) Reset() { + *x = NotifyNewBlockTemplateResponseMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotifyNewBlockTemplateResponseMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotifyNewBlockTemplateResponseMessage) ProtoMessage() {} + +func (x *NotifyNewBlockTemplateResponseMessage) ProtoReflect() protoreflect.Message { + mi := &file_rpc_proto_msgTypes[100] + 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 NotifyNewBlockTemplateResponseMessage.ProtoReflect.Descriptor instead. +func (*NotifyNewBlockTemplateResponseMessage) Descriptor() ([]byte, []int) { + return file_rpc_proto_rawDescGZIP(), []int{100} +} + +func (x *NotifyNewBlockTemplateResponseMessage) GetError() *RPCError { + if x != nil { + return x.Error + } + return nil +} + +// NewBlockTemplateNotificationMessage is sent whenever a new updated block template is +// available for miners. +// +// See NotifyNewBlockTemplateRequestMessage +type NewBlockTemplateNotificationMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NewBlockTemplateNotificationMessage) Reset() { + *x = NewBlockTemplateNotificationMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_rpc_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NewBlockTemplateNotificationMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NewBlockTemplateNotificationMessage) ProtoMessage() {} + +func (x *NewBlockTemplateNotificationMessage) ProtoReflect() protoreflect.Message { + mi := &file_rpc_proto_msgTypes[101] + 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 NewBlockTemplateNotificationMessage.ProtoReflect.Descriptor instead. +func (*NewBlockTemplateNotificationMessage) Descriptor() ([]byte, []int) { + return file_rpc_proto_rawDescGZIP(), []int{101} +} + var File_rpc_proto protoreflect.FileDescriptor var file_rpc_proto_rawDesc = []byte{ @@ -6244,10 +6375,21 @@ var file_rpc_proto_rawDesc = []byte{ 0x6f, 0x72, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x52, - 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x42, 0x26, - 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x61, 0x73, - 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x43, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x26, + 0x0a, 0x24, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x53, 0x0a, 0x25, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, + 0x4e, 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x2a, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0xe8, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x2e, 0x52, 0x50, 0x43, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x25, 0x0a, 0x23, 0x4e, + 0x65, 0x77, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x6b, 0x61, 0x73, 0x70, 0x61, 0x64, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x77, 0x69, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, } var ( @@ -6263,7 +6405,7 @@ func file_rpc_proto_rawDescGZIP() []byte { } var file_rpc_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 99) +var file_rpc_proto_msgTypes = make([]protoimpl.MessageInfo, 102) var file_rpc_proto_goTypes = []interface{}{ (SubmitBlockResponseMessage_RejectReason)(0), // 0: protowire.SubmitBlockResponseMessage.RejectReason (*RPCError)(nil), // 1: protowire.RPCError @@ -6365,6 +6507,9 @@ var file_rpc_proto_goTypes = []interface{}{ (*GetInfoResponseMessage)(nil), // 97: protowire.GetInfoResponseMessage (*EstimateNetworkHashesPerSecondRequestMessage)(nil), // 98: protowire.EstimateNetworkHashesPerSecondRequestMessage (*EstimateNetworkHashesPerSecondResponseMessage)(nil), // 99: protowire.EstimateNetworkHashesPerSecondResponseMessage + (*NotifyNewBlockTemplateRequestMessage)(nil), // 100: protowire.NotifyNewBlockTemplateRequestMessage + (*NotifyNewBlockTemplateResponseMessage)(nil), // 101: protowire.NotifyNewBlockTemplateResponseMessage + (*NewBlockTemplateNotificationMessage)(nil), // 102: protowire.NewBlockTemplateNotificationMessage } var file_rpc_proto_depIdxs = []int32{ 3, // 0: protowire.RpcBlock.header:type_name -> protowire.RpcBlockHeader @@ -6435,11 +6580,12 @@ var file_rpc_proto_depIdxs = []int32{ 1, // 65: protowire.UnbanResponseMessage.error:type_name -> protowire.RPCError 1, // 66: protowire.GetInfoResponseMessage.error:type_name -> protowire.RPCError 1, // 67: protowire.EstimateNetworkHashesPerSecondResponseMessage.error:type_name -> protowire.RPCError - 68, // [68:68] is the sub-list for method output_type - 68, // [68:68] is the sub-list for method input_type - 68, // [68:68] is the sub-list for extension type_name - 68, // [68:68] is the sub-list for extension extendee - 0, // [0:68] is the sub-list for field type_name + 1, // 68: protowire.NotifyNewBlockTemplateResponseMessage.error:type_name -> protowire.RPCError + 69, // [69:69] is the sub-list for method output_type + 69, // [69:69] is the sub-list for method input_type + 69, // [69:69] is the sub-list for extension type_name + 69, // [69:69] is the sub-list for extension extendee + 0, // [0:69] is the sub-list for field type_name } func init() { file_rpc_proto_init() } @@ -7636,6 +7782,42 @@ func file_rpc_proto_init() { return nil } } + file_rpc_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifyNewBlockTemplateRequestMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotifyNewBlockTemplateResponseMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rpc_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NewBlockTemplateNotificationMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -7643,7 +7825,7 @@ func file_rpc_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rpc_proto_rawDesc, NumEnums: 1, - NumMessages: 99, + NumMessages: 102, NumExtensions: 0, NumServices: 0, }, diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.proto b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.proto index 867ebe1d9..02d6f108b 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.proto +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc.proto @@ -654,4 +654,22 @@ message EstimateNetworkHashesPerSecondResponseMessage{ RPCError error = 1000; } +// NotifyNewBlockTemplateRequestMessage registers this connection for +// NewBlockTemplate notifications. +// +// See: NewBlockTemplateNotificationMessage +message NotifyNewBlockTemplateRequestMessage { +} + +message NotifyNewBlockTemplateResponseMessage { + RPCError error = 1000; +} + +// NewBlockTemplateNotificationMessage is sent whenever a new updated block template is +// available for miners. +// +// See NotifyNewBlockTemplateRequestMessage +message NewBlockTemplateNotificationMessage { +} + diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/rpc_notify_new_block_template.go b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc_notify_new_block_template.go new file mode 100644 index 000000000..5d7fed828 --- /dev/null +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/rpc_notify_new_block_template.go @@ -0,0 +1,66 @@ +package protowire + +import ( + "github.com/kaspanet/kaspad/app/appmessage" + "github.com/pkg/errors" +) + +func (x *KaspadMessage_NotifyNewBlockTemplateRequest) toAppMessage() (appmessage.Message, error) { + return &appmessage.NotifyNewBlockTemplateRequestMessage{}, nil +} + +func (x *KaspadMessage_NotifyNewBlockTemplateRequest) fromAppMessage(_ *appmessage.NotifyNewBlockTemplateRequestMessage) error { + x.NotifyNewBlockTemplateRequest = &NotifyNewBlockTemplateRequestMessage{} + return nil +} + +func (x *KaspadMessage_NotifyNewBlockTemplateResponse) toAppMessage() (appmessage.Message, error) { + if x == nil { + return nil, errors.Wrapf(errorNil, "KaspadMessage_NotifyNewBlockTemplateResponse is nil") + } + return x.NotifyNewBlockTemplateResponse.toAppMessage() +} + +func (x *KaspadMessage_NotifyNewBlockTemplateResponse) fromAppMessage(message *appmessage.NotifyNewBlockTemplateResponseMessage) error { + var err *RPCError + if message.Error != nil { + err = &RPCError{Message: message.Error.Message} + } + x.NotifyNewBlockTemplateResponse = &NotifyNewBlockTemplateResponseMessage{ + Error: err, + } + return nil +} + +func (x *NotifyNewBlockTemplateResponseMessage) toAppMessage() (appmessage.Message, error) { + if x == nil { + return nil, errors.Wrapf(errorNil, "NotifyNewBlockTemplateResponseMessage is nil") + } + rpcErr, err := x.Error.toAppMessage() + // Error is an optional field + if err != nil && !errors.Is(err, errorNil) { + return nil, err + } + return &appmessage.NotifyNewBlockTemplateResponseMessage{ + Error: rpcErr, + }, nil +} + +func (x *KaspadMessage_NewBlockTemplateNotification) toAppMessage() (appmessage.Message, error) { + if x == nil { + return nil, errors.Wrapf(errorNil, "KaspadMessage_NewBlockTemplateNotification is nil") + } + return x.NewBlockTemplateNotification.toAppMessage() +} + +func (x *KaspadMessage_NewBlockTemplateNotification) fromAppMessage(message *appmessage.NewBlockTemplateNotificationMessage) error { + x.NewBlockTemplateNotification = &NewBlockTemplateNotificationMessage{} + return nil +} + +func (x *NewBlockTemplateNotificationMessage) toAppMessage() (appmessage.Message, error) { + if x == nil { + return nil, errors.Wrapf(errorNil, "NewBlockTemplateNotificationMessage is nil") + } + return &appmessage.NewBlockTemplateNotificationMessage{}, nil +} diff --git a/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go b/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go index a4b71609e..a3a6e1647 100644 --- a/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go +++ b/infrastructure/network/netadapter/server/grpcserver/protowire/wire.go @@ -919,6 +919,27 @@ func toRPCPayload(message appmessage.Message) (isKaspadMessage_Payload, error) { return nil, err } return payload, nil + case *appmessage.NotifyNewBlockTemplateRequestMessage: + payload := new(KaspadMessage_NotifyNewBlockTemplateRequest) + err := payload.fromAppMessage(message) + if err != nil { + return nil, err + } + return payload, nil + case *appmessage.NotifyNewBlockTemplateResponseMessage: + payload := new(KaspadMessage_NotifyNewBlockTemplateResponse) + err := payload.fromAppMessage(message) + if err != nil { + return nil, err + } + return payload, nil + case *appmessage.NewBlockTemplateNotificationMessage: + payload := new(KaspadMessage_NewBlockTemplateNotification) + err := payload.fromAppMessage(message) + if err != nil { + return nil, err + } + return payload, nil default: return nil, nil } diff --git a/infrastructure/network/rpcclient/rpc_on_new_block_template.go b/infrastructure/network/rpcclient/rpc_on_new_block_template.go new file mode 100644 index 000000000..88e596020 --- /dev/null +++ b/infrastructure/network/rpcclient/rpc_on_new_block_template.go @@ -0,0 +1,38 @@ +package rpcclient + +import ( + "github.com/kaspanet/kaspad/app/appmessage" + routerpkg "github.com/kaspanet/kaspad/infrastructure/network/netadapter/router" + "github.com/pkg/errors" +) + +// RegisterForNewBlockTemplateNotifications sends an RPC request respective to the function's name and returns the RPC server's response. +// Additionally, it starts listening for the appropriate notification using the given handler function +func (c *RPCClient) RegisterForNewBlockTemplateNotifications(onNewBlockTemplate func(notification *appmessage.NewBlockTemplateNotificationMessage)) error { + err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewNotifyNewBlockTemplateRequestMessage()) + if err != nil { + return err + } + response, err := c.route(appmessage.CmdNotifyNewBlockTemplateResponseMessage).DequeueWithTimeout(c.timeout) + if err != nil { + return err + } + notifyNewBlockTemplateResponse := response.(*appmessage.NotifyNewBlockTemplateResponseMessage) + if notifyNewBlockTemplateResponse.Error != nil { + return c.convertRPCError(notifyNewBlockTemplateResponse.Error) + } + spawn("RegisterForNewBlockTemplateNotifications", func() { + for { + notification, err := c.route(appmessage.CmdNewBlockTemplateNotificationMessage).Dequeue() + if err != nil { + if errors.Is(err, routerpkg.ErrRouteClosed) { + break + } + panic(err) + } + NewBlockTemplateNotification := notification.(*appmessage.NewBlockTemplateNotificationMessage) + onNewBlockTemplate(NewBlockTemplateNotification) + } + }) + return nil +}