-
Notifications
You must be signed in to change notification settings - Fork 87
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
Update portal_*Offer
jsonrpc call to accept multiple key-value pairs
#342
Conversation
The goal is to have a JSON-RPC command that can create an offer with multiple content keys https://github.com/ethereum/portal-network-specs/blame/35085002701e4ffad7fb95085c1211157bd32a49/portal-wire-protocol.md#L214-L223 To test if clients can properly handle the limit of 64 given in the spec |
Seems reasonable to me, though I'd opt for a name more like |
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 think that this is how portal_historyOffer
itself ought to work, rather than a separate endpoint
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 general I have no issue with adding a call like this to Fluffy, but it's definition is currently not clear to me.
Regarding debug prefix, I am mostly in favor:
If the call is only supposed to do the offer/accept (without utp part) then I think this should get a debug_portal
prefix (we probably should revise if more should then go in the debug
prefix, but that's another issue).
If the call is supposed to do offer/accept/utp, then I'm not 100% sure, but it still feels like a debug
call because of the fact that you already need to have stored the content locally.
jsonrpc/src/methods/history.json
Outdated
@@ -115,6 +115,21 @@ | |||
"$ref": "#/components/contentDescriptors/OfferResult" | |||
} | |||
}, | |||
{ | |||
"name": "portal_historyWireOffer", | |||
"summary": "Send an OFFER request with given ContentKeys, to the designated peer and wait for a response. Requires the content keys to be stored locally. Returns the content keys bitlist upon successful content transmission or empty bitlist receive.", |
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 is not fully clear to me from the explanation whether the call should also do the uTP transfers or not (and wait for their result or not).
The result type is just OfferResult
, which is practically the bitlist, so the result of the offer (the returned accept).
But it does say Requires the content keys to be stored locally
. I assume this should be: Requires the content to be stored locally
. And that would mean that it needs the content because it also needs to send it afterwards.
So please clarify what this call is supposed to do.
Maybe we should just do scotty's suggestion and make it so portal_*offer can be used to send multiple pieces of content. I think this makes the most sense as currently portal_*offer returns a bitlist as you said so I think it would make sense for it to be able to take multiple pieces of content |
Yeah, I'm fine with that too (in fact I've needed it in the past also for local tests). But there is a difference that in that call the content gets passed within the json-rpc method parameters, and this new call expects it to be there already. |
I am fine with |
Sure, I'm fine with adjusting that existing call. It can also stay under the regular |
Sounds like a win. I will update the PR when I wake up |
+1 for modifying |
portal_*Offer
jsonrpc call to accept multiple key-value pairs
Currently, I think we want to retain both the ability to send an offer jsonrpc request with & without the accompanying value. So I'm not sure it's as simple as updating I'm not sure I'd be in favor of updating IIUC, this thread is leaning towards updating Tbh, i don't have strong feelings about which kind ends up as
I'd also suggest adding |
If we can send multiple pairs of content, we would still maintain the ability to send Sending a single pair of content is a subcase of multiple |
I think the difference here is between sending multiple content keys and multiple content key/value pairs
It seems messy to me to have a single endpoint that'll support both of these use cases. |
^ This doesn't work for the state network. It doesn't make sense for the beacon network. Personally I don't see a need for it
^ We won't be supporting both usecases. We will only be supporting |
Ok I guess I can't think of any good reason to keep that functionality around just for the history network. Maybe simply the reason that this represents the actual wire protocol message, but there's no reason we need to expose jsonrpc endpoints for the raw protocol messages. 👍 |
f8a44fd
to
2714aee
Compare
@acolytec3 @kdeme @njgheorghita @ScottyPoi ready for another look. I updated the PR to follow Scotty's suggestion |
jsonrpc/src/content/params.json
Outdated
@@ -43,6 +43,17 @@ | |||
} | |||
} | |||
}, | |||
"ContentPairs": { |
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.
ContentItems
? imo (at least from python land) this is the usual term used to identify a key/value piar
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.
Personally ambivalent about ContentPair
vs ContentItem
. For me, ContentPair
feels more descriptive (KeyValuePair
even more so), but if ContentItem
is more conventional in a way that the rest of you appreciate, then I support the choice.
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 don't really mind one or the other either. I think what @njgheorghita refers to is e.g. the items
iterator for dictionary in Python? But sure, that's rather language specific.
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 prefer ContentPair's as it is more descriptive, I updated the PR to ContentItems, because I think getting the PR in takes priority over small nits I might have
jsonrpc/src/methods/history.json
Outdated
@@ -99,16 +99,13 @@ | |||
}, | |||
{ | |||
"name": "portal_historyOffer", | |||
"summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", | |||
"summary": "Send an OFFER request with given array of Content Pairs (Keys & Values), to the designated peer and wait for a response. `portal_historyOffer` should only accept 1 to 64 content pairs else the client will throw an out of bounds error.", |
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.
nitpick ... content pairs or else the ....
jsonrpc/src/schemas/portal.json
Outdated
"contentKey": { | ||
"title": "Content key", | ||
"description": "The encoded Portal content key", | ||
"$ref": "#/components/schemas/hexString" | ||
}, | ||
"contentValue": { | ||
"title": "Content value", | ||
"description": "The encoded Portal content value", | ||
"$ref": "#/components/schemas/hexString" |
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.
ContentKey and ContentValue already exist here: https://github.com/ethereum/portal-network-specs/blob/master/jsonrpc/src/content/params.json#L2-L16
I guess they could be re-used here inside the ContentPair
(or ContentItem
).
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'm curious about the choice for ContentPair
to be an object, rather than a tuple [key, value]
.
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 didn't know tuple was a type in openapi I will updated it
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'm curious about the choice for
ContentPair
to be an object, rather than a tuple[key, value]
.
I couldn't find a tuple type so I ended up using an array to achieve a similar thing
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.
ContentKey and ContentValue already exist here: https://github.com/ethereum/portal-network-specs/blob/master/jsonrpc/src/content/params.json#L2-L16
I guess they could be re-used here inside the
ContentPair
(orContentItem
).
I am not sure how to do this, I tried a few times. Maybe someone else knows how?
jsonrpc/src/methods/beacon.json
Outdated
@@ -99,16 +99,13 @@ | |||
}, | |||
{ | |||
"name": "portal_beaconOffer", | |||
"summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", | |||
"summary": "Send an OFFER request with given array of Content Pairs (Keys & Values), to the designated peer and wait for a response. `portal_historyOffer` should only accept 1 to 64 content pairs else the client will throw an out of bounds error.", |
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.
The text is quite ambiguous right now regarding the limits/failure case:
- It might not be completely clear right now if it is allowed to fail on 2 content items (it is not, only when > 64)
should
is not sufficient, must bemust
- it must be made clear that it is the rpc client that will fail in case > 64 items, not the receiving client on the p2p network.
"summary": "Send an OFFER request with given array of Content Pairs (Keys & Values), to the designated peer and wait for a response. `portal_historyOffer` should only accept 1 to 64 content pairs else the client will throw an out of bounds error.", | |
"summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided.", |
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.
LGTM. I think this is important. it will give us a new way to stress-test uTP in the hive suites.
I left a couple comments, but generally I would be happy with merging as it is
jsonrpc/src/schemas/portal.json
Outdated
"contentKey": { | ||
"title": "Content key", | ||
"description": "The encoded Portal content key", | ||
"$ref": "#/components/schemas/hexString" | ||
}, | ||
"contentValue": { | ||
"title": "Content value", | ||
"description": "The encoded Portal content value", | ||
"$ref": "#/components/schemas/hexString" |
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'm curious about the choice for ContentPair
to be an object, rather than a tuple [key, value]
.
jsonrpc/src/content/params.json
Outdated
@@ -43,6 +43,17 @@ | |||
} | |||
} | |||
}, | |||
"ContentPairs": { |
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.
Personally ambivalent about ContentPair
vs ContentItem
. For me, ContentPair
feels more descriptive (KeyValuePair
even more so), but if ContentItem
is more conventional in a way that the rest of you appreciate, then I support the choice.
@kdeme @njgheorghita @ScottyPoi ready for another look if nobody sees an issue we can merge it |
jsonrpc/src/methods/history.json
Outdated
@@ -99,16 +99,13 @@ | |||
}, | |||
{ | |||
"name": "portal_historyOffer", | |||
"summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", | |||
"summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided or less than 1 content items are provided..", |
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.
nitpick there's 2 periods at the end of this sentence
jsonrpc/src/methods/beacon.json
Outdated
@@ -99,16 +99,13 @@ | |||
}, | |||
{ | |||
"name": "portal_beaconOffer", | |||
"summary": "Send an OFFER request with given ContentKey, to the designated peer and wait for a response.", | |||
"summary": "Send an OFFER request with given array of content items (keys & values), to the designated peer and wait for a response. The client MUST return an error if more than 64 content items are provided or less than 1 content items are provided..", |
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.
Same here
}, | ||
"ContentItem": { | ||
"title": "content_item", | ||
"type": "array", |
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.
Why is this an array
? Shouldn't it be an object
?
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.
@ScottyPoi said it should be a tupel? but that doesn't exist so I did an array.
I will let you guys discuss what we should use as I am impartial as long as I can use this RPC command to test the spec. I do think an object would be potentially cleaner though, but I haven't looked too into this yet
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'm OK with it either way
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 implemented it with tuples and it feels good so I am on the tuple side now
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 implemented it with tuples and it feels good so I am on the tuple side now
This statement is rather confusing to me. Because afaik tuples don't exist in JSON, and when they are translated from other languages I think they are typically translated to objects.
An object seems also more natural to me here, I think you don't need that "minItems": 2, "maxItems": 2,
in that case.
This will do too, but I wanted to highlight it for others adjusting this rpc, as I was implementing it in fluffy with tuple/object, and then realized its an actually array.
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.
and when they are translated from other languages I think they are typically translated to objects.
sorry for the confusion. i thought "tuple" was universally an array-like structure, but with constraints (i.e. length: 2)
I am trying to write a Hive test for ethereum/trin#1484, and I am sending offer values of 64 items. The current issue I am facing is all Portal clients don't implement a JSON-RPC command that can send more than 1 piece of content per offer.
Trin already does, though, and we call it
portal_historyWireOffer.
I believe Nick made it for internal testing, but I think it would be useful for all clients to implement it for hive.I am not adding this command to State or Beacon due to the way it works. If we want it to work for the State Network, we should include the content value in the parameters. I think Nick didn't do this because the message would could be very big, which might be a bad idea? I'm unsure if that is an issue, though, if the limit is only 64 items.
Recap
It is currently not possible to test whether Portal clients follow the spec in being able to send 64 pieces of content in one offer. I am open to discussing making this an RPC call in the
debug
namespace.Update to PR 9/26/2024
After a suggestion from Scotty the current leading solution is to make our current
portal_*Offer
accept multiple items. I updated the PR to reflect this