Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

disable HandleTransactionAnnouncement #529

Closed
wants to merge 66 commits into from

Conversation

shotasilagadzetaal
Copy link
Collaborator

@shotasilagadzetaal shotasilagadzetaal commented Aug 1, 2024

We have memory issue caused by processing too many messages in HandleTransactionAnnouncement. On every message we create new go routine which pushes message into the channel. When checking the leak cause I see too many go rougines blocked on the channel push. Having many go rougines created caused memory issue.

We don't actually need to process every transaction with this message. We will get SEEN_ON_NETWORK status for our transactions from HandleTransaction handler instead.

boecklim

This comment was marked as outdated.

@boecklim boecklim dismissed their stale review August 9, 2024 13:29

After discussion agreed on changes

Copy link
Collaborator

@arkadiuszos4chain arkadiuszos4chain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the motivation for the change?
What would be the impact of it?
What are the benefits?

test/endpoint_test.go Outdated Show resolved Hide resolved
@shotasilagadzetaal shotasilagadzetaal force-pushed the disable-handle-transaction-announce branch from da9e1b1 to f2f11cd Compare August 13, 2024 14:12
Copy link

sonarcloud bot commented Aug 15, 2024

@@ -45,15 +45,6 @@ func (m *PeerHandler) HandleTransactionSent(msg *wire.MsgTx, peer p2p.PeerI) err

// HandleTransactionAnnouncement is a message sent to the PeerHandler when a transaction INV message is received from a peer.
func (m *PeerHandler) HandleTransactionAnnouncement(msg *wire.InvVect, peer p2p.PeerI) error {
select {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment why we do not handle INV messages

internal/metamorph/processor.go Outdated Show resolved Hide resolved
internal/metamorph/processor.go Outdated Show resolved Hide resolved
}

type AnnouncedTransaction struct {
second uint64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
second uint64
timestamp uint64

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not actually timestamp, it's simply number of seconds.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the number of seconds since the Unix epoch. It is used to determine if an object is older than a specific moment in time. Seems like a timestamp to me

internal/metamorph/processor.go Outdated Show resolved Hide resolved
case <-ticker.C:
p.announcedTransactionsLock.Lock()
for k := 0; k < len(p.announcedTransactions); k++ {
if p.announcedTransactions[k].second < uint64(time.Now().Unix())-1 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. use p.now()
  2. move calculating timestamp (uint64(time.Now().Unix())-1) above the loop
  3. remove redundant casting from p.pm.RequestTransaction((*chainhash.Hash)(p.announcedTransactions[k].hash))

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't understand second point here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for k := 0; k < len(p.announcedTransactions); k++ {
	if p.announcedTransactions[k].second < uint64(time.Now().Unix())-1{
	      (...)
	}
	(...)
}
					

To:

until :=  uint64(p.Now().Unix())-1
for k := 0; k < len(p.announcedTransactions); k++ {
	if p.announcedTransactions[k].second < until{
	    (...)
	}
	(...)
}

internal/metamorph/processor.go Outdated Show resolved Hide resolved
break
}
}
p.announcedTransactionsLock.Unlock()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reset the ticker at the end

@@ -689,6 +727,9 @@ func (p *Processor) ProcessTransaction(ctx context.Context, req *ProcessorReques
return
}

// will be requesting transaction after ~2 seconds to get SEEN_ON_NETWORK status
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation may be blocking. Can we move it to the end of the processing? Does it make sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean blocking? It's simple mutex lock nothing complicated here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we lock the same collection in StartCheckingTransactionsInNetwork

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry still confused. Yes we lock it in StartCheckingTransactionsInNetwork too but why is it a problem?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's assume we have heavy traffic and receive a lot of transactions.

  1. StartCheckingTransactionsInNetwork locks the announcedTransaction collection and starts sending messages to the node.
  2. Many transactions are sent to ARC and announced to the network.
  3. The transactions are waiting for the announcedTransaction collection to be released.

In this case, isn't it a problem that we are delaying the processing of transactions (status updates, responses to the client) until the transactions can be added to the collection?

@@ -384,6 +394,37 @@ func (p *Processor) StartSendStatusUpdate() {
}()
}

func (p *Processor) StartCheckingTransactionsInNetwork() {
p.waitGroup.Add(1)
ticker := time.NewTicker(100 * time.Millisecond)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: Is it necessary to lock the announcedTransactions collection every 100 milliseconds? A better approach might be to increase the interval to 0.5-1 second and decrease the delta between the current time and the transaction announcement time. WDYT?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly not sure what we need here exactly. Or in other words what's the best time interval to wait before requesting transaction.

@boecklim
Copy link
Collaborator

boecklim commented Sep 4, 2024

Closed because the fix for issue of too much DB load will be resolved later

@boecklim boecklim closed this Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants