mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
Add AcceptedTransactionIDs to ChainChanged notification and VirtualSelectedParentChain RPC (#2036)
* Add acceptedTransactionIds to GetVirtualSelectedParentChainFromBlockResponseMessage and VirtualSelectedParentChainChangedNotificationMessage * Modify appmessage structs to include new fields * Implement the functionality for acceptedTransactionID notifications * Add missing field for IncludeAcceptedTransactionIds * Notify of block added before notifying that chain changed * Use consensushashing instead of Transaction.ID * Don't notify of empty virtual changes * Don't generate virtualChainChanged notification if there's nobody subscribed * Fix test to not expect empty notifications * Don't generate acceptedTransactionIDs if they were not requested by anyone Co-authored-by: Ori Newman <orinewman1@gmail.com>
This commit is contained in:
parent
1660cf0cf1
commit
52fbeedf20
@ -4,7 +4,8 @@ package appmessage
|
||||
// its respective RPC message
|
||||
type GetVirtualSelectedParentChainFromBlockRequestMessage struct {
|
||||
baseMessage
|
||||
StartHash string
|
||||
StartHash string
|
||||
IncludeAcceptedTransactionIDs bool
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
@ -13,18 +14,29 @@ func (msg *GetVirtualSelectedParentChainFromBlockRequestMessage) Command() Messa
|
||||
}
|
||||
|
||||
// NewGetVirtualSelectedParentChainFromBlockRequestMessage returns a instance of the message
|
||||
func NewGetVirtualSelectedParentChainFromBlockRequestMessage(startHash string) *GetVirtualSelectedParentChainFromBlockRequestMessage {
|
||||
func NewGetVirtualSelectedParentChainFromBlockRequestMessage(
|
||||
startHash string, includeAcceptedTransactionIDs bool) *GetVirtualSelectedParentChainFromBlockRequestMessage {
|
||||
|
||||
return &GetVirtualSelectedParentChainFromBlockRequestMessage{
|
||||
StartHash: startHash,
|
||||
StartHash: startHash,
|
||||
IncludeAcceptedTransactionIDs: includeAcceptedTransactionIDs,
|
||||
}
|
||||
}
|
||||
|
||||
// AcceptedTransactionIDs is a part of the GetVirtualSelectedParentChainFromBlockResponseMessage and
|
||||
// VirtualSelectedParentChainChangedNotificationMessage appmessages
|
||||
type AcceptedTransactionIDs struct {
|
||||
AcceptingBlockHash string
|
||||
AcceptedTransactionIDs []string
|
||||
}
|
||||
|
||||
// GetVirtualSelectedParentChainFromBlockResponseMessage is an appmessage corresponding to
|
||||
// its respective RPC message
|
||||
type GetVirtualSelectedParentChainFromBlockResponseMessage struct {
|
||||
baseMessage
|
||||
RemovedChainBlockHashes []string
|
||||
AddedChainBlockHashes []string
|
||||
AcceptedTransactionIDs []*AcceptedTransactionIDs
|
||||
|
||||
Error *RPCError
|
||||
}
|
||||
@ -36,10 +48,11 @@ func (msg *GetVirtualSelectedParentChainFromBlockResponseMessage) Command() Mess
|
||||
|
||||
// NewGetVirtualSelectedParentChainFromBlockResponseMessage returns a instance of the message
|
||||
func NewGetVirtualSelectedParentChainFromBlockResponseMessage(removedChainBlockHashes,
|
||||
addedChainBlockHashes []string) *GetVirtualSelectedParentChainFromBlockResponseMessage {
|
||||
addedChainBlockHashes []string, acceptedTransactionIDs []*AcceptedTransactionIDs) *GetVirtualSelectedParentChainFromBlockResponseMessage {
|
||||
|
||||
return &GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
RemovedChainBlockHashes: removedChainBlockHashes,
|
||||
AddedChainBlockHashes: addedChainBlockHashes,
|
||||
AcceptedTransactionIDs: acceptedTransactionIDs,
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package appmessage
|
||||
// its respective RPC message
|
||||
type NotifyVirtualSelectedParentChainChangedRequestMessage struct {
|
||||
baseMessage
|
||||
IncludeAcceptedTransactionIDs bool
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
@ -11,9 +12,13 @@ func (msg *NotifyVirtualSelectedParentChainChangedRequestMessage) Command() Mess
|
||||
return CmdNotifyVirtualSelectedParentChainChangedRequestMessage
|
||||
}
|
||||
|
||||
// NewNotifyVirtualSelectedParentChainChangedRequestMessage returns a instance of the message
|
||||
func NewNotifyVirtualSelectedParentChainChangedRequestMessage() *NotifyVirtualSelectedParentChainChangedRequestMessage {
|
||||
return &NotifyVirtualSelectedParentChainChangedRequestMessage{}
|
||||
// NewNotifyVirtualSelectedParentChainChangedRequestMessage returns an instance of the message
|
||||
func NewNotifyVirtualSelectedParentChainChangedRequestMessage(
|
||||
includeAcceptedTransactionIDs bool) *NotifyVirtualSelectedParentChainChangedRequestMessage {
|
||||
|
||||
return &NotifyVirtualSelectedParentChainChangedRequestMessage{
|
||||
IncludeAcceptedTransactionIDs: includeAcceptedTransactionIDs,
|
||||
}
|
||||
}
|
||||
|
||||
// NotifyVirtualSelectedParentChainChangedResponseMessage is an appmessage corresponding to
|
||||
@ -39,6 +44,7 @@ type VirtualSelectedParentChainChangedNotificationMessage struct {
|
||||
baseMessage
|
||||
RemovedChainBlockHashes []string
|
||||
AddedChainBlockHashes []string
|
||||
AcceptedTransactionIDs []*AcceptedTransactionIDs
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message
|
||||
@ -48,10 +54,11 @@ func (msg *VirtualSelectedParentChainChangedNotificationMessage) Command() Messa
|
||||
|
||||
// NewVirtualSelectedParentChainChangedNotificationMessage returns a instance of the message
|
||||
func NewVirtualSelectedParentChainChangedNotificationMessage(removedChainBlockHashes,
|
||||
addedChainBlocks []string) *VirtualSelectedParentChainChangedNotificationMessage {
|
||||
addedChainBlocks []string, acceptedTransactionIDs []*AcceptedTransactionIDs) *VirtualSelectedParentChainChangedNotificationMessage {
|
||||
|
||||
return &VirtualSelectedParentChainChangedNotificationMessage{
|
||||
RemovedChainBlockHashes: removedChainBlockHashes,
|
||||
AddedChainBlockHashes: addedChainBlocks,
|
||||
AcceptedTransactionIDs: acceptedTransactionIDs,
|
||||
}
|
||||
}
|
||||
|
@ -52,18 +52,25 @@ func (m *Manager) NotifyBlockAddedToDAG(block *externalapi.DomainBlock, virtualC
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyBlockAddedToDAG")
|
||||
defer onEnd()
|
||||
|
||||
err := m.NotifyVirtualChange(virtualChangeSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rpcBlock := appmessage.DomainBlockToRPCBlock(block)
|
||||
err = m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, false)
|
||||
err := m.context.PopulateBlockWithVerboseData(rpcBlock, block.Header, block, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockAddedNotification := appmessage.NewBlockAddedNotificationMessage(rpcBlock)
|
||||
return m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
|
||||
err = m.context.NotificationManager.NotifyBlockAdded(blockAddedNotification)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// When block was added during IBD - it doesn't incur any Virtual change,
|
||||
// thus no notification is needed.
|
||||
if len(virtualChangeSet.VirtualSelectedParentChainChanges.Added) == 0 &&
|
||||
len(virtualChangeSet.VirtualSelectedParentChainChanges.Removed) == 0 {
|
||||
|
||||
return nil
|
||||
}
|
||||
return m.NotifyVirtualChange(virtualChangeSet)
|
||||
}
|
||||
|
||||
// NotifyVirtualChange notifies the manager that the virtual block has been changed.
|
||||
@ -195,10 +202,25 @@ func (m *Manager) notifyVirtualSelectedParentChainChanged(virtualChangeSet *exte
|
||||
onEnd := logger.LogAndMeasureExecutionTime(log, "RPCManager.NotifyVirtualSelectedParentChainChanged")
|
||||
defer onEnd()
|
||||
|
||||
notification, err := m.context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
|
||||
virtualChangeSet.VirtualSelectedParentChainChanges)
|
||||
if err != nil {
|
||||
return err
|
||||
listenersThatPropagateSelectedParentChanged :=
|
||||
m.context.NotificationManager.AllListenersThatPropagateVirtualSelectedParentChainChanged()
|
||||
if len(listenersThatPropagateSelectedParentChanged) > 0 {
|
||||
// Generating acceptedTransactionIDs is a heavy operation, so we check if it's needed by any listener.
|
||||
includeAcceptedTransactionIDs := false
|
||||
for _, listener := range listenersThatPropagateSelectedParentChanged {
|
||||
if listener.IncludeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications() {
|
||||
includeAcceptedTransactionIDs = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
notification, err := m.context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
|
||||
virtualChangeSet.VirtualSelectedParentChainChanges, includeAcceptedTransactionIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.context.NotificationManager.NotifyVirtualSelectedParentChainChanged(notification)
|
||||
}
|
||||
return m.context.NotificationManager.NotifyVirtualSelectedParentChainChanged(notification)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -3,12 +3,14 @@ package rpccontext
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
)
|
||||
|
||||
// ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage converts
|
||||
// VirtualSelectedParentChainChanges to VirtualSelectedParentChainChangedNotificationMessage
|
||||
func (ctx *Context) ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
|
||||
selectedParentChainChanges *externalapi.SelectedChainPath) (*appmessage.VirtualSelectedParentChainChangedNotificationMessage, error) {
|
||||
selectedParentChainChanges *externalapi.SelectedChainPath, includeAcceptedTransactionIDs bool) (
|
||||
*appmessage.VirtualSelectedParentChainChangedNotificationMessage, error) {
|
||||
|
||||
removedChainBlockHashes := make([]string, len(selectedParentChainChanges.Removed))
|
||||
for i, removed := range selectedParentChainChanges.Removed {
|
||||
@ -20,5 +22,43 @@ func (ctx *Context) ConvertVirtualSelectedParentChainChangesToChainChangedNotifi
|
||||
addedChainBlocks[i] = added.String()
|
||||
}
|
||||
|
||||
return appmessage.NewVirtualSelectedParentChainChangedNotificationMessage(removedChainBlockHashes, addedChainBlocks), nil
|
||||
var acceptedTransactionIDs []*appmessage.AcceptedTransactionIDs
|
||||
if includeAcceptedTransactionIDs {
|
||||
var err error
|
||||
acceptedTransactionIDs, err = ctx.getAndConvertAcceptedTransactionIDs(selectedParentChainChanges)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return appmessage.NewVirtualSelectedParentChainChangedNotificationMessage(
|
||||
removedChainBlockHashes, addedChainBlocks, acceptedTransactionIDs), nil
|
||||
}
|
||||
|
||||
func (ctx *Context) getAndConvertAcceptedTransactionIDs(selectedParentChainChanges *externalapi.SelectedChainPath) (
|
||||
[]*appmessage.AcceptedTransactionIDs, error) {
|
||||
|
||||
acceptedTransactionIDs := make([]*appmessage.AcceptedTransactionIDs, len(selectedParentChainChanges.Added))
|
||||
|
||||
for i, addedChainBlock := range selectedParentChainChanges.Added {
|
||||
blockAcceptanceData, err := ctx.Domain.Consensus().GetBlockAcceptanceData(addedChainBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
acceptedTransactionIDs[i] = &appmessage.AcceptedTransactionIDs{
|
||||
AcceptingBlockHash: addedChainBlock.String(),
|
||||
AcceptedTransactionIDs: nil,
|
||||
}
|
||||
for _, blockAcceptanceData := range blockAcceptanceData {
|
||||
for _, transactionAcceptanceData := range blockAcceptanceData.TransactionAcceptanceData {
|
||||
if transactionAcceptanceData.IsAccepted {
|
||||
acceptedTransactionIDs[i].AcceptedTransactionIDs =
|
||||
append(acceptedTransactionIDs[i].AcceptedTransactionIDs,
|
||||
consensushashing.TransactionID(transactionAcceptanceData.Transaction).String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return acceptedTransactionIDs, nil
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ type NotificationListener struct {
|
||||
propagatePruningPointUTXOSetOverrideNotifications bool
|
||||
propagateNewBlockTemplateNotifications bool
|
||||
|
||||
propagateUTXOsChangedNotificationAddresses map[utxoindex.ScriptPublicKeyString]*UTXOsChangedNotificationAddress
|
||||
propagateUTXOsChangedNotificationAddresses map[utxoindex.ScriptPublicKeyString]*UTXOsChangedNotificationAddress
|
||||
includeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications bool
|
||||
}
|
||||
|
||||
// NewNotificationManager creates a new NotificationManager
|
||||
@ -92,13 +93,27 @@ func (nm *NotificationManager) NotifyBlockAdded(notification *appmessage.BlockAd
|
||||
}
|
||||
|
||||
// NotifyVirtualSelectedParentChainChanged notifies the notification manager that the DAG's selected parent chain has changed
|
||||
func (nm *NotificationManager) NotifyVirtualSelectedParentChainChanged(notification *appmessage.VirtualSelectedParentChainChangedNotificationMessage) error {
|
||||
func (nm *NotificationManager) NotifyVirtualSelectedParentChainChanged(
|
||||
notification *appmessage.VirtualSelectedParentChainChangedNotificationMessage) error {
|
||||
|
||||
nm.RLock()
|
||||
defer nm.RUnlock()
|
||||
|
||||
notificationWithoutAcceptedTransactionIDs := &appmessage.VirtualSelectedParentChainChangedNotificationMessage{
|
||||
RemovedChainBlockHashes: notification.RemovedChainBlockHashes,
|
||||
AddedChainBlockHashes: notification.AddedChainBlockHashes,
|
||||
}
|
||||
|
||||
for router, listener := range nm.listeners {
|
||||
if listener.propagateVirtualSelectedParentChainChangedNotifications {
|
||||
err := router.OutgoingRoute().Enqueue(notification)
|
||||
var err error
|
||||
|
||||
if listener.includeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications {
|
||||
err = router.OutgoingRoute().Enqueue(notification)
|
||||
} else {
|
||||
err = router.OutgoingRoute().Enqueue(notificationWithoutAcceptedTransactionIDs)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -107,6 +122,18 @@ func (nm *NotificationManager) NotifyVirtualSelectedParentChainChanged(notificat
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllListenersThatPropagateVirtualSelectedParentChainChanged returns true if there's any listener that is
|
||||
// subscribed to VirtualSelectedParentChainChanged notifications.
|
||||
func (nm *NotificationManager) AllListenersThatPropagateVirtualSelectedParentChainChanged() []*NotificationListener {
|
||||
var listenersThatPropagate []*NotificationListener
|
||||
for _, listener := range nm.listeners {
|
||||
if listener.propagateVirtualSelectedParentChainChangedNotifications {
|
||||
listenersThatPropagate = append(listenersThatPropagate, listener)
|
||||
}
|
||||
}
|
||||
return listenersThatPropagate
|
||||
}
|
||||
|
||||
// NotifyFinalityConflict notifies the notification manager that there's a finality conflict in the DAG
|
||||
func (nm *NotificationManager) NotifyFinalityConflict(notification *appmessage.FinalityConflictNotificationMessage) error {
|
||||
nm.RLock()
|
||||
@ -251,6 +278,12 @@ func newNotificationListener() *NotificationListener {
|
||||
}
|
||||
}
|
||||
|
||||
// IncludeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications returns true if this listener
|
||||
// includes accepted transaction IDs in it's virtual-selected-parent-chain-changed notifications
|
||||
func (nl *NotificationListener) IncludeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications() bool {
|
||||
return nl.includeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications
|
||||
}
|
||||
|
||||
// PropagateBlockAddedNotifications instructs the listener to send block added notifications
|
||||
// to the remote listener
|
||||
func (nl *NotificationListener) PropagateBlockAddedNotifications() {
|
||||
@ -259,8 +292,9 @@ func (nl *NotificationListener) PropagateBlockAddedNotifications() {
|
||||
|
||||
// PropagateVirtualSelectedParentChainChangedNotifications instructs the listener to send chain changed notifications
|
||||
// to the remote listener
|
||||
func (nl *NotificationListener) PropagateVirtualSelectedParentChainChangedNotifications() {
|
||||
func (nl *NotificationListener) PropagateVirtualSelectedParentChainChangedNotifications(includeAcceptedTransactionIDs bool) {
|
||||
nl.propagateVirtualSelectedParentChainChangedNotifications = true
|
||||
nl.includeAcceptedTransactionIDsInVirtualSelectedParentChainChangedNotifications = includeAcceptedTransactionIDs
|
||||
}
|
||||
|
||||
// PropagateFinalityConflictNotifications instructs the listener to send finality conflict notifications
|
||||
|
@ -26,12 +26,14 @@ func HandleGetVirtualSelectedParentChainFromBlock(context *rpccontext.Context, _
|
||||
return response, nil
|
||||
}
|
||||
|
||||
chainChangedNotification, err := context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(virtualSelectedParentChain)
|
||||
chainChangedNotification, err := context.ConvertVirtualSelectedParentChainChangesToChainChangedNotificationMessage(
|
||||
virtualSelectedParentChain, getVirtualSelectedParentChainFromBlockRequest.IncludeAcceptedTransactionIDs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response := appmessage.NewGetVirtualSelectedParentChainFromBlockResponseMessage(
|
||||
chainChangedNotification.RemovedChainBlockHashes, chainChangedNotification.AddedChainBlockHashes)
|
||||
chainChangedNotification.RemovedChainBlockHashes, chainChangedNotification.AddedChainBlockHashes,
|
||||
chainChangedNotification.AcceptedTransactionIDs)
|
||||
return response, nil
|
||||
}
|
||||
|
@ -7,12 +7,17 @@ import (
|
||||
)
|
||||
|
||||
// HandleNotifyVirtualSelectedParentChainChanged handles the respectively named RPC command
|
||||
func HandleNotifyVirtualSelectedParentChainChanged(context *rpccontext.Context, router *router.Router, _ appmessage.Message) (appmessage.Message, error) {
|
||||
func HandleNotifyVirtualSelectedParentChainChanged(context *rpccontext.Context, router *router.Router,
|
||||
request appmessage.Message) (appmessage.Message, error) {
|
||||
|
||||
notifyVirtualSelectedParentChainChangedRequest := request.(*appmessage.NotifyVirtualSelectedParentChainChangedRequestMessage)
|
||||
|
||||
listener, err := context.NotificationManager.Listener(router)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listener.PropagateVirtualSelectedParentChainChangedNotifications()
|
||||
listener.PropagateVirtualSelectedParentChainChangedNotifications(
|
||||
notifyVirtualSelectedParentChainChangedRequest.IncludeAcceptedTransactionIDs)
|
||||
|
||||
response := appmessage.NewNotifyVirtualSelectedParentChainChangedResponseMessage()
|
||||
return response, nil
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.2
|
||||
// protoc v3.12.3
|
||||
// source: messages.proto
|
||||
|
||||
package protowire
|
||||
|
@ -1,8 +1,4 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.17.2
|
||||
// source: messages.proto
|
||||
|
||||
package protowire
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc v3.17.2
|
||||
// protoc v3.12.3
|
||||
// source: p2p.proto
|
||||
|
||||
package protowire
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -301,6 +301,7 @@ message SubmitTransactionResponseMessage{
|
||||
//
|
||||
// See: VirtualSelectedParentChainChangedNotificationMessage
|
||||
message NotifyVirtualSelectedParentChainChangedRequestMessage{
|
||||
bool includeAcceptedTransactionIds = 1;
|
||||
}
|
||||
|
||||
message NotifyVirtualSelectedParentChainChangedResponseMessage{
|
||||
@ -317,6 +318,9 @@ message VirtualSelectedParentChainChangedNotificationMessage{
|
||||
|
||||
// The chain blocks that were added, in low-to-high order
|
||||
repeated string addedChainBlockHashes = 3;
|
||||
|
||||
// Will be filled only if `includeAcceptedTransactionIds = true` in the notify request.
|
||||
repeated AcceptedTransactionIds acceptedTransactionIds = 2;
|
||||
}
|
||||
|
||||
// GetBlockRequestMessage requests information about a specific block
|
||||
@ -349,6 +353,12 @@ message GetSubnetworkResponseMessage{
|
||||
// parent chain from some startHash to this kaspad's current virtual
|
||||
message GetVirtualSelectedParentChainFromBlockRequestMessage{
|
||||
string startHash = 1;
|
||||
bool includeAcceptedTransactionIds = 2;
|
||||
}
|
||||
|
||||
message AcceptedTransactionIds{
|
||||
string acceptingBlockHash = 1;
|
||||
repeated string acceptedTransactionIds = 2;
|
||||
}
|
||||
|
||||
message GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
@ -358,6 +368,10 @@ message GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
// The chain blocks that were added, in low-to-high order
|
||||
repeated string addedChainBlockHashes = 3;
|
||||
|
||||
// The transactions accepted by each block in addedChainBlockHashes.
|
||||
// Will be filled only if `includeAcceptedTransactionIds = true` in the request.
|
||||
repeated AcceptedTransactionIds acceptedTransactionIds = 2;
|
||||
|
||||
RPCError error = 1000;
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,13 @@ func (x *KaspadMessage_GetVirtualSelectedParentChainFromBlockResponse) fromAppMe
|
||||
x.GetVirtualSelectedParentChainFromBlockResponse = &GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
RemovedChainBlockHashes: message.RemovedChainBlockHashes,
|
||||
AddedChainBlockHashes: message.AddedChainBlockHashes,
|
||||
AcceptedTransactionIds: make([]*AcceptedTransactionIds, len(message.AcceptedTransactionIDs)),
|
||||
Error: err,
|
||||
}
|
||||
for i, acceptedTransactionIDs := range message.AcceptedTransactionIDs {
|
||||
x.GetVirtualSelectedParentChainFromBlockResponse.AcceptedTransactionIds[i] = &AcceptedTransactionIds{}
|
||||
x.GetVirtualSelectedParentChainFromBlockResponse.AcceptedTransactionIds[i].fromAppMessage(acceptedTransactionIDs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -62,9 +67,28 @@ func (x *GetVirtualSelectedParentChainFromBlockResponseMessage) toAppMessage() (
|
||||
return nil, errors.New("GetVirtualSelectedParentChainFromBlockResponseMessage contains both an error and a response")
|
||||
}
|
||||
|
||||
return &appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
message := &appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage{
|
||||
RemovedChainBlockHashes: x.RemovedChainBlockHashes,
|
||||
AddedChainBlockHashes: x.AddedChainBlockHashes,
|
||||
AcceptedTransactionIDs: make([]*appmessage.AcceptedTransactionIDs, len(x.AcceptedTransactionIds)),
|
||||
Error: rpcErr,
|
||||
}, nil
|
||||
}
|
||||
|
||||
for i, acceptedTransactionIds := range x.AcceptedTransactionIds {
|
||||
message.AcceptedTransactionIDs[i] = acceptedTransactionIds.toAppMessage()
|
||||
}
|
||||
|
||||
return message, nil
|
||||
}
|
||||
|
||||
func (x *AcceptedTransactionIds) fromAppMessage(acceptedTransactionIDs *appmessage.AcceptedTransactionIDs) {
|
||||
x.AcceptingBlockHash = acceptedTransactionIDs.AcceptingBlockHash
|
||||
x.AcceptedTransactionIds = acceptedTransactionIDs.AcceptedTransactionIDs
|
||||
}
|
||||
|
||||
func (x *AcceptedTransactionIds) toAppMessage() *appmessage.AcceptedTransactionIDs {
|
||||
return &appmessage.AcceptedTransactionIDs{
|
||||
AcceptingBlockHash: x.AcceptingBlockHash,
|
||||
AcceptedTransactionIDs: x.AcceptedTransactionIds,
|
||||
}
|
||||
}
|
||||
|
@ -9,11 +9,15 @@ func (x *KaspadMessage_NotifyVirtualSelectedParentChainChangedRequest) toAppMess
|
||||
if x == nil {
|
||||
return nil, errors.Wrapf(errorNil, "KaspadMessage_NotifyVirtualSelectedParentChainChangedRequest is nil")
|
||||
}
|
||||
return &appmessage.NotifyVirtualSelectedParentChainChangedRequestMessage{}, nil
|
||||
return &appmessage.NotifyVirtualSelectedParentChainChangedRequestMessage{
|
||||
IncludeAcceptedTransactionIDs: x.NotifyVirtualSelectedParentChainChangedRequest.IncludeAcceptedTransactionIds,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (x *KaspadMessage_NotifyVirtualSelectedParentChainChangedRequest) fromAppMessage(_ *appmessage.NotifyVirtualSelectedParentChainChangedRequestMessage) error {
|
||||
x.NotifyVirtualSelectedParentChainChangedRequest = &NotifyVirtualSelectedParentChainChangedRequestMessage{}
|
||||
func (x *KaspadMessage_NotifyVirtualSelectedParentChainChangedRequest) fromAppMessage(appmessage *appmessage.NotifyVirtualSelectedParentChainChangedRequestMessage) error {
|
||||
x.NotifyVirtualSelectedParentChainChangedRequest = &NotifyVirtualSelectedParentChainChangedRequestMessage{
|
||||
IncludeAcceptedTransactionIds: appmessage.IncludeAcceptedTransactionIDs,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -60,6 +64,12 @@ func (x *KaspadMessage_VirtualSelectedParentChainChangedNotification) fromAppMes
|
||||
x.VirtualSelectedParentChainChangedNotification = &VirtualSelectedParentChainChangedNotificationMessage{
|
||||
RemovedChainBlockHashes: message.RemovedChainBlockHashes,
|
||||
AddedChainBlockHashes: message.AddedChainBlockHashes,
|
||||
AcceptedTransactionIds: make([]*AcceptedTransactionIds, len(message.AcceptedTransactionIDs)),
|
||||
}
|
||||
|
||||
for i, acceptedTransactionIDs := range message.AcceptedTransactionIDs {
|
||||
x.VirtualSelectedParentChainChangedNotification.AcceptedTransactionIds[i] = &AcceptedTransactionIds{}
|
||||
x.VirtualSelectedParentChainChangedNotification.AcceptedTransactionIds[i].fromAppMessage(acceptedTransactionIDs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -68,8 +78,14 @@ func (x *VirtualSelectedParentChainChangedNotificationMessage) toAppMessage() (a
|
||||
if x == nil {
|
||||
return nil, errors.Wrapf(errorNil, "VirtualSelectedParentChainChangedNotificationMessage is nil")
|
||||
}
|
||||
return &appmessage.VirtualSelectedParentChainChangedNotificationMessage{
|
||||
message := &appmessage.VirtualSelectedParentChainChangedNotificationMessage{
|
||||
RemovedChainBlockHashes: x.RemovedChainBlockHashes,
|
||||
AddedChainBlockHashes: x.AddedChainBlockHashes,
|
||||
}, nil
|
||||
AcceptedTransactionIDs: make([]*appmessage.AcceptedTransactionIDs, len(x.AcceptedTransactionIds)),
|
||||
}
|
||||
|
||||
for i, acceptedTransactionIds := range x.AcceptedTransactionIds {
|
||||
message.AcceptedTransactionIDs[i] = acceptedTransactionIds.toAppMessage()
|
||||
}
|
||||
return message, nil
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package rpcclient
|
||||
import "github.com/kaspanet/kaspad/app/appmessage"
|
||||
|
||||
// GetVirtualSelectedParentChainFromBlock sends an RPC request respective to the function's name and returns the RPC server's response
|
||||
func (c *RPCClient) GetVirtualSelectedParentChainFromBlock(startHash string) (*appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage, error) {
|
||||
err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewGetVirtualSelectedParentChainFromBlockRequestMessage(startHash))
|
||||
func (c *RPCClient) GetVirtualSelectedParentChainFromBlock(startHash string, includeAcceptedTransactionIDs bool) (
|
||||
*appmessage.GetVirtualSelectedParentChainFromBlockResponseMessage, error) {
|
||||
err := c.rpcRouter.outgoingRoute().Enqueue(
|
||||
appmessage.NewGetVirtualSelectedParentChainFromBlockRequestMessage(startHash, includeAcceptedTransactionIDs))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -8,8 +8,11 @@ import (
|
||||
|
||||
// RegisterForVirtualSelectedParentChainChangedNotifications 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) RegisterForVirtualSelectedParentChainChangedNotifications(onChainChanged func(notification *appmessage.VirtualSelectedParentChainChangedNotificationMessage)) error {
|
||||
err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewNotifyVirtualSelectedParentChainChangedRequestMessage())
|
||||
func (c *RPCClient) RegisterForVirtualSelectedParentChainChangedNotifications(includeAcceptedTransactionIDs bool,
|
||||
onChainChanged func(notification *appmessage.VirtualSelectedParentChainChangedNotificationMessage)) error {
|
||||
|
||||
err := c.rpcRouter.outgoingRoute().Enqueue(
|
||||
appmessage.NewNotifyVirtualSelectedParentChainChangedRequestMessage(includeAcceptedTransactionIDs))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
)
|
||||
@ -15,7 +16,7 @@ func TestVirtualSelectedParentChain(t *testing.T) {
|
||||
|
||||
// Register to virtual selected parent chain changes
|
||||
onVirtualSelectedParentChainChangedChan := make(chan *appmessage.VirtualSelectedParentChainChangedNotificationMessage)
|
||||
err := kaspad1.rpcClient.RegisterForVirtualSelectedParentChainChangedNotifications(
|
||||
err := kaspad1.rpcClient.RegisterForVirtualSelectedParentChainChangedNotifications(true,
|
||||
func(notification *appmessage.VirtualSelectedParentChainChangedNotificationMessage) {
|
||||
onVirtualSelectedParentChainChangedChan <- notification
|
||||
})
|
||||
@ -64,36 +65,10 @@ func TestVirtualSelectedParentChain(t *testing.T) {
|
||||
chain2TipHashString := chain2TipHash.String()
|
||||
|
||||
// For the first `blockAmountToMine - 1` blocks we don't expect
|
||||
// the chain to change at all
|
||||
for i := 0; i < blockAmountToMine-1; i++ {
|
||||
notification := <-onVirtualSelectedParentChainChangedChan
|
||||
if len(notification.RemovedChainBlockHashes) > 0 {
|
||||
t.Fatalf("RemovedChainBlockHashes is unexpectedly not empty")
|
||||
}
|
||||
if len(notification.AddedChainBlockHashes) > 0 {
|
||||
t.Fatalf("AddedChainBlockHashes is unexpectedly not empty")
|
||||
}
|
||||
}
|
||||
// the chain to change at all, thus there will be no notifications
|
||||
|
||||
// Either the next block could cause a reorg or the one
|
||||
// after it
|
||||
potentialReorgNotification1 := <-onVirtualSelectedParentChainChangedChan
|
||||
potentialReorgNotification2 := <-onVirtualSelectedParentChainChangedChan
|
||||
var reorgNotification *appmessage.VirtualSelectedParentChainChangedNotificationMessage
|
||||
var nonReorgNotification *appmessage.VirtualSelectedParentChainChangedNotificationMessage
|
||||
if len(potentialReorgNotification1.RemovedChainBlockHashes) > 0 {
|
||||
reorgNotification = potentialReorgNotification1
|
||||
nonReorgNotification = potentialReorgNotification2
|
||||
} else {
|
||||
reorgNotification = potentialReorgNotification2
|
||||
nonReorgNotification = potentialReorgNotification1
|
||||
}
|
||||
|
||||
// Make sure that the non-reorg notification has nothing
|
||||
// in `removed`
|
||||
if len(nonReorgNotification.RemovedChainBlockHashes) > 0 {
|
||||
t.Fatalf("nonReorgNotification.RemovedChainBlockHashes is unexpectedly not empty")
|
||||
}
|
||||
// Either the next block or the one after it will cause a reorg
|
||||
reorgNotification := <-onVirtualSelectedParentChainChangedChan
|
||||
|
||||
// Make sure that the reorg notification contains exactly
|
||||
// `blockAmountToMine` blocks in its `removed`
|
||||
@ -104,7 +79,8 @@ func TestVirtualSelectedParentChain(t *testing.T) {
|
||||
|
||||
// Get the virtual selected parent chain from the tip of
|
||||
// the first chain
|
||||
virtualSelectedParentChainFromChain1Tip, err := kaspad1.rpcClient.GetVirtualSelectedParentChainFromBlock(chain1TipHashString)
|
||||
virtualSelectedParentChainFromChain1Tip, err := kaspad1.rpcClient.GetVirtualSelectedParentChainFromBlock(
|
||||
chain1TipHashString, true)
|
||||
if err != nil {
|
||||
t.Fatalf("GetVirtualSelectedParentChainFromBlock failed: %s", err)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user