HotShot icon indicating copy to clipboard operation
HotShot copied to clipboard

Nodes subscribe to `transactions` topic only when they need transactions

Open lukaszrzasik opened this issue 1 year ago • 6 comments

Closes #1992

This PR:

  • Creates three new methods in the ConnectedNetwork trait:
  • subscribe_transactions which subscribes to the new Transactions topic
  • unsubscribe_transactions which unsubscribes from the Transactions topic
  • publish_transaction which publishes a message to the Transactions topic
  • implements these three methods for networks: Libp2pNetwork, PushCdnNetwork and CombinedNetworks
  • subscribes the node to the topic when it is to become the leader in the next view
  • unsubscribes the node from the topic when the view has been updated and the node is not the leader in the next view

This PR does not:

Key places to review:

lukaszrzasik avatar Apr 22 '24 13:04 lukaszrzasik

I think that currently this change has no real impact because the soon-to-be-leader fetches the transactions from the builder and the nodes do not gossip the transactions between themselves.

The logic when to subscribe and unsubscribe from the Transactions topic is somewhat arbitrary at the moment. I need to test the change without the builder if that's possible.

lukaszrzasik avatar Apr 23 '24 13:04 lukaszrzasik

I've come up with the following approach to check if all the transactions are received:

  1. I've commented out the part of the code that sends the transactions to the builder using EventType::Transactions in SystemContext::publish_transaction_async. This way the nodes receive transactions only through DataMessage::SubmitTransaction via the Transactions topic and sent from the same method SystemContext::publish_transaction_async.
  2. I've modifed TestValidatedState::create_random_transaction so that each transaction includes a predetermined number incremented with the next transaction. This way it can be checked if all transactions are handled.
  3. Print the transactions included in the DA proposal. All the transactions should be present.

lukaszrzasik avatar Apr 25 '24 13:04 lukaszrzasik

Checking with the above method I can't see all the transactions. If I comment out the part where HotShotEvent::UnsubscribeTransactions is sent then all the transactions are visible.

lukaszrzasik avatar Apr 25 '24 14:04 lukaszrzasik

From my understanding this PR allows us to subscribe to transactions for views which we are going to be leader, just before being leader. I think this made sense for previous versions of the code where we were building blocks ourselves. Now hotshots job as it relates to transactions is to gossip/share them with any node who cares to create a public mempool. The builder also listens to this topic (right now via a hotshot node) to get transactions to build blocks. In other words any node that can receive transactions from a user needs to be able to send it to all HotShot nodes that care (query server nodes). For libp2p if a node is not in the topic, it can't necessarily gossip to that topic and joing/leaving a topic sporadically is not something you want to do either.

The code changes for subscribing/unsubscribing looks good, we probably want a different way to decide if a node cares about the transaction topic.

Just to check if I correctly understand the current main branch implementation:

  1. When a node receives DataMessage::SubmitTransaction, it bundles the received transactions and internally sends HotShotEvent::TransactionsRecv. This in turn is handled in TransactionTaskState by sending EventType::Transactions to the builder.
  2. DataMessage::SubmitTransaction is sent only by the publish_transaction_async method which is used by an application (e.g. the sequencer). The same method sends the same transaction to the builder via EventType::Transactions.
  3. HotShotEvent::TransactionSend is not used at all at the moment.
  4. The soon-to-be-leader node receives the block with the transactions in TransactionTaskState::wait_for_block from the builder.

I don't understand how the nodes gossip the transactions between themselves. If I didn't miss anything, the nodes (only DA nodes) receive the transactions from the application and send them to the builder. The application also sends the transactions directly to the builder (I assume this is a redundant mechanism just to be sure).

Did I miss something?

lukaszrzasik avatar Apr 29 '24 16:04 lukaszrzasik

2. publish_transaction_async

publish_transaction_async is the function that is doing the gossiping (it's handled at the networking layer). So basically a node gets a transaction, then it broadcast that transaction to all the other nodes, and finally each node upon receiving the broadcast transaction sends the transaction to the builder.

bfish713 avatar Apr 29 '24 17:04 bfish713

The CDN changes look good 👍

rob-maron avatar Apr 29 '24 19:04 rob-maron

Should we close this (and revive the branch if we really need this)? I think we aren't going to work on this anytime soon

bfish713 avatar Jun 05 '24 19:06 bfish713

Should we close this (and revive the branch if we really need this)? I think we aren't going to work on this anytime soon

Yes, I agree. I'll close it.

lukaszrzasik avatar Jun 06 '24 07:06 lukaszrzasik