[NOD-1405] Add getMempoolEntries RPC command (#937)

* [NOD-1405] Add getMempoolEntries RPC command

* [NOD-1405] Remove redundant fields from GetMempoolEntryResponseMessage
This commit is contained in:
Ori Newman 2020-09-23 15:51:02 +03:00 committed by GitHub
parent fed34273a1
commit f8d0f7f67a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1442 additions and 991 deletions

View File

@ -97,6 +97,8 @@ const (
CmdNotifyFinalityConflictsResponseMessage
CmdFinalityConflictNotificationMessage
CmdFinalityConflictResolvedNotificationMessage
CmdGetMempoolEntriesRequestMessage
CmdGetMempoolEntriesResponseMessage
)
// ProtocolMessageCommandToString maps all MessageCommands to their string representation
@ -170,6 +172,8 @@ var RPCMessageCommandToString = map[MessageCommand]string{
CmdNotifyFinalityConflictsResponseMessage: "NotifyFinalityConflictsResponse",
CmdFinalityConflictNotificationMessage: "FinalityConflictNotification",
CmdFinalityConflictResolvedNotificationMessage: "FinalityConflictResolvedNotification",
CmdGetMempoolEntriesRequestMessage: "GetMempoolEntriesRequestMessage",
CmdGetMempoolEntriesResponseMessage: "GetMempoolEntriesResponseMessage",
}
// Message is an interface that describes a kaspa message. A type that

View File

@ -0,0 +1,38 @@
package appmessage
// GetMempoolEntriesRequestMessage is an appmessage corresponding to
// its respective RPC message
type GetMempoolEntriesRequestMessage struct {
baseMessage
}
// Command returns the protocol command string for the message
func (msg *GetMempoolEntriesRequestMessage) Command() MessageCommand {
return CmdGetMempoolEntriesRequestMessage
}
// NewGetMempoolEntriesRequestMessage returns a instance of the message
func NewGetMempoolEntriesRequestMessage() *GetMempoolEntriesRequestMessage {
return &GetMempoolEntriesRequestMessage{}
}
// GetMempoolEntriesResponseMessage is an appmessage corresponding to
// its respective RPC message
type GetMempoolEntriesResponseMessage struct {
baseMessage
Entries []*MempoolEntry
Error *RPCError
}
// Command returns the protocol command string for the message
func (msg *GetMempoolEntriesResponseMessage) Command() MessageCommand {
return CmdGetMempoolEntriesResponseMessage
}
// NewGetMempoolEntriesResponseMessage returns a instance of the message
func NewGetMempoolEntriesResponseMessage(entries []*MempoolEntry) *GetMempoolEntriesResponseMessage {
return &GetMempoolEntriesResponseMessage{
Entries: entries,
}
}

View File

@ -21,12 +21,17 @@ func NewGetMempoolEntryRequestMessage(txID string) *GetMempoolEntryRequestMessag
// its respective RPC message
type GetMempoolEntryResponseMessage struct {
baseMessage
Fee uint64
TransactionVerboseData *TransactionVerboseData
Entry *MempoolEntry
Error *RPCError
}
// MempoolEntry represents a transaction in the mempool.
type MempoolEntry struct {
Fee uint64
TransactionVerboseData *TransactionVerboseData
}
// Command returns the protocol command string for the message
func (msg *GetMempoolEntryResponseMessage) Command() MessageCommand {
return CmdGetMempoolEntryResponseMessage
@ -35,7 +40,9 @@ func (msg *GetMempoolEntryResponseMessage) Command() MessageCommand {
// NewGetMempoolEntryResponseMessage returns a instance of the message
func NewGetMempoolEntryResponseMessage(fee uint64, transactionVerboseData *TransactionVerboseData) *GetMempoolEntryResponseMessage {
return &GetMempoolEntryResponseMessage{
Fee: fee,
TransactionVerboseData: transactionVerboseData,
Entry: &MempoolEntry{
Fee: fee,
TransactionVerboseData: transactionVerboseData,
},
}
}

View File

@ -31,6 +31,7 @@ var handlers = map[appmessage.MessageCommand]handler{
appmessage.CmdGetBlockDAGInfoRequestMessage: rpchandlers.HandleGetBlockDAGInfo,
appmessage.CmdResolveFinalityConflictRequestMessage: rpchandlers.HandleResolveFinalityConflict,
appmessage.CmdNotifyFinalityConflictsRequestMessage: rpchandlers.HandleNotifyFinalityConflicts,
appmessage.CmdGetMempoolEntriesRequestMessage: rpchandlers.HandleGetMempoolEntries,
}
func (m *Manager) routerInitializer(router *router.Router, netConnection *netadapter.NetConnection) {

View File

@ -0,0 +1,25 @@
package rpchandlers
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
)
// HandleGetMempoolEntries handles the respectively named RPC command
func HandleGetMempoolEntries(context *rpccontext.Context, _ *router.Router, _ appmessage.Message) (appmessage.Message, error) {
txDescs := context.Mempool.TxDescs()
entries := make([]*appmessage.MempoolEntry, len(txDescs))
for i, txDesc := range txDescs {
transactionVerboseData, err := context.BuildTransactionVerboseData(txDesc.Tx.MsgTx(), txDesc.Tx.ID().String(),
nil, "", nil, true)
if err != nil {
return nil, err
}
entries[i] = &appmessage.MempoolEntry{
Fee: txDesc.Fee,
TransactionVerboseData: transactionVerboseData,
}
}
return appmessage.NewGetMempoolEntriesResponseMessage(entries), nil
}

View File

@ -70,6 +70,8 @@ message KaspadMessage {
NotifyFinalityConflictsResponseMessage notifyFinalityConflictsResponse = 1040;
FinalityConflictNotificationMessage finalityConflictNotification = 1041;
FinalityConflictResolvedNotificationMessage finalityConflictResolvedNotification = 1042;
GetMempoolEntriesRequestMessage getMempoolEntriesRequest = 1043;
GetMempoolEntriesResponseMessage getMempoolEntriesResponse = 1044;
}
}
@ -361,17 +363,32 @@ message GetSelectedTipHashResponseMessage{
RPCError error = 1000;
}
// mempool entries start
message MempoolEntry{
uint64 fee = 1;
TransactionVerboseData transactionVerboseData = 2;
}
message GetMempoolEntryRequestMessage{
string txId = 1;
}
message GetMempoolEntryResponseMessage{
uint64 fee = 1;
TransactionVerboseData transactionVerboseData = 2;
MempoolEntry entry = 1;
RPCError error = 1000;
}
message GetMempoolEntriesRequestMessage{
}
message GetMempoolEntriesResponseMessage{
repeated MempoolEntry entries = 1;
RPCError error = 1000;
}
// mempool entries end
message GetConnectedPeerInfoRequestMessage{
}

View File

@ -0,0 +1,51 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
func (x *KaspadMessage_GetMempoolEntriesRequest) toAppMessage() (appmessage.Message, error) {
return &appmessage.GetMempoolEntriesRequestMessage{}, nil
}
func (x *KaspadMessage_GetMempoolEntriesRequest) fromAppMessage(_ *appmessage.GetMempoolEntriesRequestMessage) error {
x.GetMempoolEntriesRequest = &GetMempoolEntriesRequestMessage{}
return nil
}
func (x *KaspadMessage_GetMempoolEntriesResponse) toAppMessage() (appmessage.Message, error) {
var rpcErr *appmessage.RPCError
if x.GetMempoolEntriesResponse.Error != nil {
rpcErr = &appmessage.RPCError{Message: x.GetMempoolEntriesResponse.Error.Message}
}
entries := make([]*appmessage.MempoolEntry, len(x.GetMempoolEntriesResponse.Entries))
for i, entry := range x.GetMempoolEntriesResponse.Entries {
var err error
entries[i], err = entry.toAppMessage()
if err != nil {
return nil, err
}
}
return &appmessage.GetMempoolEntriesResponseMessage{
Entries: entries,
Error: rpcErr,
}, nil
}
func (x *KaspadMessage_GetMempoolEntriesResponse) fromAppMessage(message *appmessage.GetMempoolEntriesResponseMessage) error {
var rpcErr *RPCError
if message.Error != nil {
rpcErr = &RPCError{Message: message.Error.Message}
}
entries := make([]*MempoolEntry, len(message.Entries))
for i, entry := range message.Entries {
entries[i] = new(MempoolEntry)
err := entries[i].fromAppMessage(entry)
if err != nil {
return err
}
}
x.GetMempoolEntriesResponse = &GetMempoolEntriesResponseMessage{
Entries: entries,
Error: rpcErr,
}
return nil
}

View File

@ -1,6 +1,8 @@
package protowire
import "github.com/kaspanet/kaspad/app/appmessage"
import (
"github.com/kaspanet/kaspad/app/appmessage"
)
func (x *KaspadMessage_GetMempoolEntryRequest) toAppMessage() (appmessage.Message, error) {
return &appmessage.GetMempoolEntryRequestMessage{
@ -20,18 +22,17 @@ func (x *KaspadMessage_GetMempoolEntryResponse) toAppMessage() (appmessage.Messa
if x.GetMempoolEntryResponse.Error != nil {
rpcErr = &appmessage.RPCError{Message: x.GetMempoolEntryResponse.Error.Message}
}
var transactionVerboseData *appmessage.TransactionVerboseData
if x.GetMempoolEntryResponse.TransactionVerboseData != nil {
var entry *appmessage.MempoolEntry
if x.GetMempoolEntryResponse.Entry != nil {
var err error
transactionVerboseData, err = x.GetMempoolEntryResponse.TransactionVerboseData.toAppMessage()
entry, err = x.GetMempoolEntryResponse.Entry.toAppMessage()
if err != nil {
return nil, err
}
}
return &appmessage.GetMempoolEntryResponseMessage{
Fee: x.GetMempoolEntryResponse.Fee,
TransactionVerboseData: transactionVerboseData,
Error: rpcErr,
Entry: entry,
Error: rpcErr,
}, nil
}
@ -40,17 +41,47 @@ func (x *KaspadMessage_GetMempoolEntryResponse) fromAppMessage(message *appmessa
if message.Error != nil {
rpcErr = &RPCError{Message: message.Error.Message}
}
transactionVerboseData := &TransactionVerboseData{}
if message.TransactionVerboseData != nil {
err := transactionVerboseData.fromAppMessage(message.TransactionVerboseData)
entry := new(MempoolEntry)
if message.Entry != nil {
err := entry.fromAppMessage(message.Entry)
if err != nil {
return err
}
}
x.GetMempoolEntryResponse = &GetMempoolEntryResponseMessage{
Fee: message.Fee,
TransactionVerboseData: transactionVerboseData,
Error: rpcErr,
Entry: entry,
Error: rpcErr,
}
return nil
}
func (x *MempoolEntry) toAppMessage() (*appmessage.MempoolEntry, error) {
var txVerboseData *appmessage.TransactionVerboseData
if x.TransactionVerboseData != nil {
var err error
txVerboseData, err = x.TransactionVerboseData.toAppMessage()
if err != nil {
return nil, err
}
}
return &appmessage.MempoolEntry{
Fee: x.Fee,
TransactionVerboseData: txVerboseData,
}, nil
}
func (x *MempoolEntry) fromAppMessage(message *appmessage.MempoolEntry) error {
var txVerboseData *TransactionVerboseData
if message.TransactionVerboseData != nil {
txVerboseData = new(TransactionVerboseData)
err := txVerboseData.fromAppMessage(message.TransactionVerboseData)
if err != nil {
return err
}
}
*x = MempoolEntry{
Fee: message.Fee,
TransactionVerboseData: txVerboseData,
}
return nil
}

View File

@ -506,6 +506,20 @@ func toRPCPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntriesRequestMessage:
payload := new(KaspadMessage_GetMempoolEntriesRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntriesResponseMessage:
payload := new(KaspadMessage_GetMempoolEntriesResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
default:
return nil, nil
}

View File

@ -0,0 +1,20 @@
package rpcclient
import "github.com/kaspanet/kaspad/app/appmessage"
// GetMempoolEntries sends an RPC request respective to the function's name and returns the RPC server's response
func (c *RPCClient) GetMempoolEntries() (*appmessage.GetMempoolEntriesResponseMessage, error) {
err := c.rpcRouter.outgoingRoute().Enqueue(appmessage.NewGetMempoolEntriesRequestMessage())
if err != nil {
return nil, err
}
response, err := c.route(appmessage.CmdGetMempoolEntriesResponseMessage).DequeueWithTimeout(c.timeout)
if err != nil {
return nil, err
}
getMempoolEntriesResponse := response.(*appmessage.GetMempoolEntriesResponseMessage)
if getMempoolEntriesResponse.Error != nil {
return nil, c.convertRPCError(getMempoolEntriesResponse.Error)
}
return getMempoolEntriesResponse, nil
}