Skip to content

feat: Ignore P2P messages previously seen#14665

Merged
alexghr merged 8 commits intomasterfrom
pw/use-msg-time-cache
Jun 2, 2025
Merged

feat: Ignore P2P messages previously seen#14665
alexghr merged 8 commits intomasterfrom
pw/use-msg-time-cache

Conversation

@PhilWindle
Copy link
Collaborator

Please read contributing guidelines and remove this line.

@PhilWindle PhilWindle added the ci-full Run all master checks. label Jun 1, 2025
@mralj
Copy link
Contributor

mralj commented Jun 2, 2025

Hey! I'm probably missing something, but this solution feels too complicated.
IMO, a much easier solution would be poor man's LRU.

  1. We cap cache by TX count, not time. I don't see a massive benefit in defining this by time instead of count. Is it UX? Because it's easier to reason about the 24hrs or 12hrs, or should I configure the cache to hold 100k transactions or 1M?
  2. We have a Set and a Queue
  3. If tx already exists in the Set, do nothing, else
  4. If set.length >= N, pop from Queue and remove from Set
  5. Add to Set and push to Queue

This seems much less complicated and will guarantee removing the oldest transactions first. And uses half of the memory of the current solution

The downsides I see:

  1. As mentioned, maybe a bit worse UX
  2. JS doesn't have Queues, so the perf will suffer when we hit the cache size limit and constantly call shift(). To combat this, I see 2 options
    2.1. Proper off-shelf queue implementation, but if you don't like this:
    2.2. We could set the cache size to 2N (memory-wise, it will be similar to the current solution), and when we hit limit of 2N cached txs, we prune half - effectively amortizing the cost of the queue.shift()]
    2.3. Implement queue ourselves - but then this gets more complicated than the current solution 😅

P.S.

We could still have the Set/Queue solution without a sliding window if we store, e.g., [hash, timestamp] in the queue and check if the first element of the queue is old enough to execute prune when inserting. IMO it will still be simpler and use less memory :)

@PhilWindle
Copy link
Collaborator Author

Hey! I'm probably missing something, but this solution feels too complicated. IMO, a much easier solution would be poor man's LRU.

  1. We cap cache by TX count, not time. I don't see a massive benefit in defining this by time instead of count. Is it UX? Because it's easier to reason about the 24hrs or 12hrs, or should I configure the cache to hold 100k transactions or 1M?
  2. We have a Set and a Queue
  3. If tx already exists in the Set, do nothing, else
  4. If set.length >= N, pop from Queue and remove from Set
  5. Add to Set and push to Queue

This seems much less complicated and will guarantee removing the oldest transactions first. And uses half of the memory of the current solution

The downsides I see:

  1. As mentioned, maybe a bit worse UX
  2. JS doesn't have Queues, so the perf will suffer when we hit the cache size limit and constantly call shift(). To combat this, I see 2 options
    2.1. Proper off-shelf queue implementation, but if you don't like this:
    2.2. We could set the cache size to 2N (memory-wise, it will be similar to the current solution), and when we hit limit of 2N cached txs, we prune half - effectively amortizing the cost of the queue.shift()]
    2.3. Implement queue ourselves - but then this gets more complicated than the current solution 😅

P.S.

We could still have the Set/Queue solution without a sliding window if we store, e.g., [hash, timestamp] in the queue and check if the first element of the queue is old enough to execute prune when inserting. IMO it will still be simpler and use less memory :)

I agree with this. I went for a time-based approach as it intuitive to say 'store N minutes of messages'. But I don't think there is inherently any reason to view the store in this way and a simpler 'store N messages' will suffice. I will also create a cache per topic too.

I think we can get rid of the shifting all together by using a circular array?

@mralj
Copy link
Contributor

mralj commented Jun 2, 2025

I think we can get rid of the shifting all together by using a circular array?

Ring buffer FTW 😄

Copy link
Contributor

@alexghr alexghr left a comment

Choose a reason for hiding this comment

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

I like the new approach

Copy link
Contributor

@mralj mralj left a comment

Choose a reason for hiding this comment

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

LGTM.
I have left 2 nitpicks 😅


// add 1000 messages
for (let i = 0; i < 1000; i++) {
expect(validator.addMessage(makeMsgId())).toBe(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: I'd add expect(validator.queue.length === 10) just to be sure this is not growing indefinitely.

Comment on lines +504 to +517
const getValidator = () => {
if (msg.topic === this.topicStrings[TopicType.tx]) {
return this.msgIdSeenValidators[TopicType.tx];
}
if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
return this.msgIdSeenValidators[TopicType.block_attestation];
}
if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
return this.msgIdSeenValidators[TopicType.block_proposal];
}
this.logger.error(`Received message on unknown topic: ${msg.topic}`);
};

const validator = getValidator();
Copy link
Contributor

Choose a reason for hiding this comment

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

This could be simplified to const validator = this.msgIdSeenValidators[msg.topic]; given that we check taht validator exist: if(!validator ...).

Copy link
Contributor

Choose a reason for hiding this comment

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

We tried this but TopicType.tx is just a prefix of msg.topic (the topic of the actual message contains the compressed version string as a suffix)

@alexghr alexghr added this pull request to the merge queue Jun 2, 2025
Merged via the queue into master with commit 2e50588 Jun 2, 2025
4 checks passed
@alexghr alexghr deleted the pw/use-msg-time-cache branch June 2, 2025 11:54
charlielye pushed a commit that referenced this pull request Jun 2, 2025
🤖 I have created a new Aztec Packages release
---


##
[0.87.6](v0.87.5...v0.87.6)
(2025-06-02)


### ⚠ BREAKING CHANGES

* app benches and unified PXE creation
([#14504](#14504))
* Removes normalize() calls on pairing points
([#14285](#14285))

### Features

* Adds StarknetZK WASM bindings to bb.js
([#14372](#14372))
([224b219](224b219))
* allow mempool to overflow before evicting
([#14641](#14641))
([f81425d](f81425d))
* app benches and unified PXE creation
([#14504](#14504))
([aae5ab0](aae5ab0))
* **bb:** memory tracking for microbenchmarks
([#14445](#14445))
([fae2961](fae2961))
* enable provers to run in node chart
([#14405](#14405))
([94edd35](94edd35))
* Ignore P2P messages previously seen
([#14665](#14665))
([2e50588](2e50588))
* measure oracles
([#14552](#14552))
([9cc6b54](9cc6b54))
* Removes normalize() calls on pairing points
([#14285](#14285))
([942b948](942b948))
* Request missing txs from block proposal sender
([#14341](#14341))
([3f97e8b](3f97e8b))
* unbundled bb.js
([#14401](#14401))
([e0d9662](e0d9662))
* validate notes in a single node roundtrip
([#14650](#14650))
([d467955](d467955))
* validating partial note sender
([#14379](#14379))
([de9880c](de9880c)),
closes
[#14363](#14363)


### Bug Fixes

* allow returning of tuples from contract funcs
([#14553](#14553))
([1c0955c](1c0955c))
* asan-fast caching
([#14468](#14468))
([fbd9ed6](fbd9ed6))
* attempt fix concurrency
([f31e706](f31e706))
* attempt to fix merge group base config
([6aa342b](6aa342b))
* bug in `TxProvingResult` schema
([#14498](#14498))
([#14530](#14530))
([0ac26fa](0ac26fa))
* bump defaults
([#14474](#14474))
([ade9a56](ade9a56))
* do not run concurrent idb transactions
([#14609](#14609))
([5a6f36a](5a6f36a))
* **docs:** Update create pxe interface
([#14587](#14587))
([b3b9c05](b3b9c05))
* **docs:** Update getting started with testnet page
([#14536](#14536))
([66fc3eb](66fc3eb))
* don't create ./out when verifying
([#14556](#14556))
([ccb9981](ccb9981))
* Don't manually close stream on p2p/reqresp/goodbye
([#14531](#14531))
([38cec7d](38cec7d))
* eccvm_circuit_builder overrun
([#14484](#14484))
([5e01c07](5e01c07))
* enable bundling txs with block proposals
([#14649](#14649))
([39b8c4e](39b8c4e))
* error on goodbye
([#14679](#14679))
([5112f5f](5112f5f))
* issues with syncNotes --&gt; syncPrivateState renaming
([#14442](#14442))
([78de410](78de410))
* Merge queue instances have pr name for uniquness in e.g. reorgs.
([#14562](#14562))
([1f012a9](1f012a9))
* nope
([470882a](470882a))
* parse LOG_LEVELS in bb
([#14674](#14674))
([88203d6](88203d6))
* **playground:** fix sfpc version when creating account
([#14481](#14481))
([5486a22](5486a22))
* prevent world-state from spamming the logs
([#14594](#14594))
([8c725de](8c725de))
* processing events in contracts with no notes
([#14528](#14528))
([1bab9b4](1bab9b4)),
closes
[#14499](#14499)
* retrieve L1 to L2 messages in batches
([#14586](#14586))
([2be7f1b](2be7f1b))
* slack for flakes
([61829bc](61829bc))
* target branch
([e463723](e463723))
* test tracking
([#14513](#14513))
([2d6fc3a](2d6fc3a))
* try to fix release please
([f31c07e](f31c07e))
* try to fix release please
([d402c27](d402c27))
* try to fix release please
([cb959b8](cb959b8))
* try to fix release please
([227dbd2](227dbd2))
* update sponsored fpc address in playground
([#14472](#14472))
([4c14bc9](4c14bc9))
* wip merge master to next
([249ab4c](249ab4c))
* wip merge master to next
([b7850c9](b7850c9))


### Miscellaneous

* add testnet compat test
([#14601](#14601))
([1fbb350](1fbb350))
* Aztec simulator into PXE
([#14598](#14598))
([a999c8c](a999c8c))
* **bb:** avoid compile-time hash-to-curve
([#14177](#14177))
([d3863ff](d3863ff))
* capture RPC calls + correct timings
([#14633](#14633))
([5ee54ff](5ee54ff))
* Disable flood publish by default
([#14635](#14635))
([af8d879](af8d879))
* **docs:** Add scheduled typesense index job
([#14615](#14615))
([5f42e1b](5f42e1b))
* **docs:** Update alpha-testnet docs to use version 0.87.2
([#14501](#14501))
([c86d3b0](c86d3b0))
* drop txs per block to 8
([#14627](#14627))
([369f210](369f210))
* master-to-next
([#14454](#14454))
([06ac335](06ac335))
* **master:** release 0.87.3
([#14440](#14440))
([3ca26cd](3ca26cd))
* **master:** release 0.87.3
([#14582](#14582))
([8cea842](8cea842))
* **master:** release 0.87.4
([#14583](#14583))
([8077f63](8077f63))
* New prover chart for alpha-testnet
([#14514](#14514))
([031d7cb](031d7cb))
* partial notes optimization with nullifier
([#14432](#14432))
([cc90823](cc90823))
* playground should release also at refname. attempt to make RP do
prerelease version.
([3c4fba5](3c4fba5))
* Protocol breaking changes must now go to next branch.
([#14423](#14423))
([44304b6](44304b6))
* release 0.87.3
([8340415](8340415))
* release please v4
([bf97805](bf97805))
* remove some expected failures
([#13843](#13843))
([2593e28](2593e28))
* Revert "fix: processing events in contracts with no notes
([#14528](#14528))"
([#14596](#14596))
([3278e61](3278e61))
* select random rollup versions from distinct sets
([#14568](#14568))
([fe787cd](fe787cd))
* stdlib field pre-audit pt.0
([#14413](#14413))
([52458c2](52458c2))
* trick release-please
([cbcad3d](cbcad3d))
* trick release-please
([a0c3a21](a0c3a21))


### Documentation

* comment on partial note reuse
([#14383](#14383))
([42200c8](42200c8))
* create v0.87.4 as latest
([#14607](#14607))
([78c2469](78c2469))
* fix image
([#14537](#14537))
([388e79b](388e79b)),
closes
[#14163](#14163)
* update cli ref in node doc
([#14574](#14574))
([d54a8af](d54a8af))
* update node version instructions
([#14412](#14412))
([a2b1b9d](a2b1b9d))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-full Run all master checks.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants