-
Notifications
You must be signed in to change notification settings - Fork 57
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
fix: add protection in rest service to always publish with timestamp if user doesn't provide it #2261
Conversation
You can find the image built from this PR at
Built from 6b768ba |
Interesting. Can you expand a little bit more on why the |
I think we've discussed before about automatically adding in REST the current timestamp if the user does not set it in the request. |
Thanks for the comment! In this case, the very first page will be returned with the following cursor definition (notice that Line 807 in 89dbbd2
After that, a go-Store client will ask for the second page of messages from the following code. Notice that the After that, the following nwaku/waku/waku_store/rpc_codec.nim Lines 56 to 57 in c86dc44
|
Set now timestamp to the WakuMessage if the client didn't send this information in the request. This could happen in a request like: curl -X POST "http://127.0.0.1:8646/relay/v1/messages/%2Fwaku%2F2%2Fdefault-waku%2Fproto" -H "content-type: application/json" -d '{"payload":"'${payload}'","contentTopic":"my-ctopic"}'
552bc3d
to
a7213c4
Compare
Thanks for the suggestion @gabrielmer ! |
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.
Thank you!
@@ -72,7 +72,7 @@ suite "Waku Archive - message handling": | |||
|
|||
## Then | |||
check: | |||
(waitFor driver.getMessagesCount()).tryGet() == 1 | |||
(waitFor driver.getMessagesCount()).tryGet() == 0 |
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 would change the test name. also it should be deliver
not driver
🤣
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 would change the test name. also it should be
deliver
notdriver
🤣
Good point! I changed the whole tests' names, which is a little bit beyond the scope of this PR.
f541d4b
to
bc4620e
Compare
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.
Looks great! Thanks so much! 🤩
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.
Thanks for the detailed response!
After that, the following if statement will happen, considering it a wrong request, in nwaku, and therefore the rest of the Store requests won't proceed. In other words, only the very first page is delivered to the store client.
Ah, I see now why this happens. However, I think the issue here is that nwaku enforces the existence of a senderTimestamp
field in violation of the current RFC. We may indeed change to a timestamp-mandatory store implementation, but that would involve an RFC change and a more extensive data schema review (storedAt
receiverTimestamp
become obsolete), as I mention below. A good time to do that would be in the new, reviewed Store protocol that @ABresting is working on, where timestamp
is likely to be mandatory.
I do agree with the REST API adding timestamps on the user's behalf though. For now to proceed, I'd be happy to approve two different PRs:
- REST API changes to add timestamp when publishing new messages (received messages should never be modified)
- Remove strict requirement for sender timestamp in cursor in nwaku (fixing compliance with RFC).
waku/waku_api/rest/filter/types.nim
Outdated
var timestamp = msg.timestamp.get(0) | ||
|
||
if timestamp == 0: | ||
timestamp = getNanosecondTime(getTime().toUnixFloat()) |
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.
A bit confused by this. Where is this used? Afaics this is to convert received filter messages (as a client) to Waku Messages, although I can't find where this is called in the implementation. What would be the purpose of modifying timestamps in received messages on the 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.
Well, this was thought to be a change aligned to the Store change. I can remove it if that doesn't make sense to you in this PR.
waku/waku_archive/archive.nim
Outdated
if msg.timestamp == 0: | ||
return ok() | ||
return err(timestampIsZero) |
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.
Although I agree with the REST API adding timestamps on behalf of the application when publishing messages. I still don't think the Store should (for now) enforce sender timestamps. Doing so goes against the existing RFC. Furthermore, this obsoletes the entire receiverTimestamp
, storedAt
, etc. mechanism which is a larger cleanup exercise. We may indeed decide to follow this route (and perhaps should have from the beginning), but deprecating the RFC provision for optional timestamps is a bit larger, involves an RFC change and a more extensive review of the existing data scheme.
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.
Thanks for the comment!
The https://rfc.vac.dev/spec/13/ RFC enforces the existence of senderTime
in the Store request, although it is true that the RFC doesn't enforce any value. This can be seen because the senderTime
is not optional in the protobuf definition:
On the other hand, in the archive.nim
module we are enforcing the senderTime
to be within a certain time window:
nwaku/waku/waku_archive/archive.nim
Lines 51 to 60 in aebc912
let | |
now = getNanosecondTime(getTime().toUnixFloat()) | |
lowerBound = now - MaxMessageTimestampVariance | |
upperBound = now + MaxMessageTimestampVariance | |
if msg.timestamp < lowerBound: | |
return err(invalidMessageOld) | |
if upperBound < msg.timestamp: | |
return err(invalidMessageFuture) |
... but it is weird that we accept msg.timestamp == 0
, isn't it?
aebc912
to
9c37289
Compare
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.
Thanks! LGTM now.
This is needed because we have the following in waku_archive/archive.nim method validate*(validator: DefaultMessageValidator, msg: WakuMessage): ValidationResult = if msg.timestamp == 0: return ok()
4bf048a
to
499f107
Compare
After a chat with @jm-clius , we left the waku_archive/archive.nim with the following:
Therefore, messages with timestamp zero are allowed. Kindly ask Hanno for further details as to why this is interesting as he has a better understanding of the system :D |
Description
Before this PR, the
relay
REST service accepted "publish" events withouttimestamp
info.Therefore, the Postgres database ended up with the following message set:
That caused pagination issues within the Store protocol because the
sender_time
attribute (part of the Cursor object) was always set to 0.Changes
Issue
This was noticed while dogfooding
status.test
in the context of status-im/infra-status#37