-
Notifications
You must be signed in to change notification settings - Fork 18
(Bug) Postcard limit can be exceeded in some cases #169 #179
Conversation
Pull Request Test Coverage Report for Build 579
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to work. I made this test:
- Comment the lines in
RegisterAddressPage
that post to/api/notifyRegTx
- Limit the number of postcards per day to 3
- Send the form 5 times. Use the resulting txIds and session keys and send 5 multiple concurrent posts to
/api/notifyRegTx
.
The five postcards are being sent, while only three of theme should be sent.
web-dapp/app.js
Outdated
@@ -24,5 +24,6 @@ app.use(bodyParser.json({ limit: config.bodySizeLimit })); | |||
const routes = require('./routes')({}); | |||
app.use('/api', routes); | |||
app.use('/confirm/api', routes); | |||
app.use('/register/api', routes); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
frontend was throwing a 404 error at that url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything worked for me when I uncommented it. Besides, did something change for this to be needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends on which url you opened first. It serves as a root url, when you go to a different urls, they are not actually served by server, but intercepted by react and served on client-side. So if you open /register page in new incognito window, api requests would go to /register/api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the problem is the
window.$.ajax({
type: 'post',
url: './api/prepareRegTx',
in RegisterAddressPage
. The .
seems problematic. Adding this endpoint to fix the issue seems extremely hacky to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed a commit fixing this and removing the unnecessary extra routes. Tested both the registration and confirmation using new pages in incognito mode. Please check.
For reference, this is the curl that I used, replacing
(Of course, the wallet may be different, but that's the first one in the |
I think there's one more important point - if there are multiple processes of the web-server behind a load balancer, they won't be sharing this semaphore - I wonder if we can use |
Probably this module https://www.npmjs.com/package/petty-cache#semaphore can help. But for a local testing it should be configurable to run web-server without it. |
@matiasgaratortiz I moved pettyCache to session-store and added methods @fvictorio it seems to be working, could you please test again? You'll need redis locally, because pettyCache only works with redis. For |
Added mutexes for |
@fvictorio I also changed |
I tested again with multiple concurrent requests and all postcards were sent, even when the limit was exceeded. I also started two instances of the app with redis as db, and the postcard limit was enforced even when alternating between the two instances, so that worked. |
@fvictorio it must be fixed now, sorry. |
Thanks @phahulin. Tested it with both memory and redis stores. Looks good. |
@fvictorio thank you! |
What is it? (leave one option)
(Fix)
What was the root cause of the problem originally / what feature was missing?
There can be a race condition here if multiple requests are sent in short time period. Each requests will result in calling postcardLimiter.canSend which leads to calling postcardLimiter.get. If there are too many requests, they all get the same value from .get() and thus .canSend() is true for all of them, so they can exceed the limit.
How does this pull request solve it (in broad terms)?
Limit the request before calling the canSend method.
Does it close any open issues?
Closes (Bug) Postcard limit can be exceeded in some cases #169
Quick checklist
npm run lint
shows no errorsAdditional information