From 598241ea7757ba5075b6d1eb3934e205cdea3a80 Mon Sep 17 00:00:00 2001 From: Kolby Moroz Liebl <31669092+KolbyML@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:44:20 -0600 Subject: [PATCH] feat: update `portal_*Offer` to handle multiple pieces of content --- ethportal-api/src/beacon.rs | 9 ++++---- ethportal-api/src/history.rs | 9 ++++---- ethportal-api/src/state.rs | 7 +++---- ethportal-api/src/types/jsonrpc/endpoints.rs | 12 +++++------ ethportal-peertest/src/scenarios/gossip.rs | 8 ++++--- .../src/scenarios/offer_accept.rs | 9 +++----- ethportal-peertest/src/scenarios/state.rs | 3 +-- portalnet/src/overlay/protocol.rs | 7 ++----- rpc/src/beacon_rpc.rs | 21 ++++++++++++------- rpc/src/history_rpc.rs | 21 ++++++++++++------- rpc/src/state_rpc.rs | 16 +++++++------- trin-beacon/src/jsonrpc.rs | 17 +++++++-------- trin-history/src/jsonrpc.rs | 17 +++++++-------- trin-state/src/jsonrpc.rs | 14 +++++++------ 14 files changed, 85 insertions(+), 85 deletions(-) diff --git a/ethportal-api/src/beacon.rs b/ethportal-api/src/beacon.rs index dd08a339f..f323069c3 100644 --- a/ethportal-api/src/beacon.rs +++ b/ethportal-api/src/beacon.rs @@ -115,7 +115,7 @@ pub trait BeaconNetworkApi { content_value: RawContentValue, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store the content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. @@ -123,11 +123,10 @@ pub trait BeaconNetworkApi { async fn offer( &self, enr: Enr, - content_key: BeaconContentKey, - content_value: RawContentValue, + content_items: Vec<(BeaconContentKey, RawContentValue)>, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns trace info for the offer. #[method(name = "beaconTraceOffer")] @@ -138,7 +137,7 @@ pub trait BeaconNetworkApi { content_value: RawContentValue, ) -> RpcResult; - /// Send an OFFER request with given ContentKeys, to the designated peer and wait for a + /// Send an OFFER request with given ContentItemss, 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. diff --git a/ethportal-api/src/history.rs b/ethportal-api/src/history.rs index e91afe782..8db299ae7 100644 --- a/ethportal-api/src/history.rs +++ b/ethportal-api/src/history.rs @@ -101,7 +101,7 @@ pub trait HistoryNetworkApi { content_value: RawContentValue, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store the content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. @@ -109,11 +109,10 @@ pub trait HistoryNetworkApi { async fn offer( &self, enr: Enr, - content_key: HistoryContentKey, - content_value: RawContentValue, + content_items: Vec<(HistoryContentKey, RawContentValue)>, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns trace info for the offer. #[method(name = "historyTraceOffer")] @@ -124,7 +123,7 @@ pub trait HistoryNetworkApi { content_value: RawContentValue, ) -> RpcResult; - /// Send an OFFER request with given ContentKeys, to the designated peer and wait for a + /// Send an OFFER request with given ContentItemss, 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. diff --git a/ethportal-api/src/state.rs b/ethportal-api/src/state.rs index 88402adc8..f54bcfc11 100644 --- a/ethportal-api/src/state.rs +++ b/ethportal-api/src/state.rs @@ -94,7 +94,7 @@ pub trait StateNetworkApi { content_value: RawContentValue, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store the content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. @@ -102,11 +102,10 @@ pub trait StateNetworkApi { async fn offer( &self, enr: Enr, - content_key: StateContentKey, - content_value: RawContentValue, + content_items: Vec<(StateContentKey, RawContentValue)>, ) -> RpcResult; - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns trace info for offer. #[method(name = "stateTraceOffer")] diff --git a/ethportal-api/src/types/jsonrpc/endpoints.rs b/ethportal-api/src/types/jsonrpc/endpoints.rs index 6426c63d1..7163fe618 100644 --- a/ethportal-api/src/types/jsonrpc/endpoints.rs +++ b/ethportal-api/src/types/jsonrpc/endpoints.rs @@ -44,8 +44,8 @@ pub enum StateEndpoint { Store(StateContentKey, StateContentValue), /// WireOffer is not supported in the state network, since locally /// stored values do not contain the proofs necessary for valid gossip. - /// params: [enr, content_key, content_value] - Offer(Enr, StateContentKey, StateContentValue), + /// params: [enr, Vec<(content_key, content_value>)] + Offer(Enr, Vec<(StateContentKey, StateContentValue)>), /// params: [enr, content_key, content_value] TraceOffer(Enr, StateContentKey, StateContentValue), /// params: [enr, content_key, content_value] @@ -79,8 +79,8 @@ pub enum HistoryEndpoint { Gossip(HistoryContentKey, HistoryContentValue), /// params: [content_key, content_value] TraceGossip(HistoryContentKey, HistoryContentValue), - /// params: [enr, content_key, content_value] - Offer(Enr, HistoryContentKey, HistoryContentValue), + /// params: [enr, Vec<(content_key, content_value)>] + Offer(Enr, Vec<(HistoryContentKey, HistoryContentValue)>), /// params: [enr, content_key, content_value] TraceOffer(Enr, HistoryContentKey, HistoryContentValue), /// params: [enr, [content_key]] @@ -133,8 +133,8 @@ pub enum BeaconEndpoint { Gossip(BeaconContentKey, BeaconContentValue), /// params: [content_key, content_value] TraceGossip(BeaconContentKey, BeaconContentValue), - /// params: [enr, content_key, content_value] - Offer(Enr, BeaconContentKey, BeaconContentValue), + /// params: [enr, Vec<(content_key, content_value>)] + Offer(Enr, Vec<(BeaconContentKey, BeaconContentValue)>), /// params: [enr, content_key, content_value] TraceOffer(Enr, BeaconContentKey, BeaconContentValue), /// params: [enr, [content_key]] diff --git a/ethportal-peertest/src/scenarios/gossip.rs b/ethportal-peertest/src/scenarios/gossip.rs index 18265f7cf..ae276d50a 100644 --- a/ethportal-peertest/src/scenarios/gossip.rs +++ b/ethportal-peertest/src/scenarios/gossip.rs @@ -181,13 +181,15 @@ pub async fn test_gossip_dropped_with_offer(peertest: &Peertest, target: &Client target .offer( fresh_enr.clone(), - header_key_2.clone(), - header_value_2.encode(), + vec![(header_key_2.clone(), header_value_2.encode())], ) .await .unwrap(); target - .offer(fresh_enr.clone(), body_key_2.clone(), body_value_2.encode()) + .offer( + fresh_enr.clone(), + vec![(body_key_2.clone(), body_value_2.encode())], + ) .await .unwrap(); diff --git a/ethportal-peertest/src/scenarios/offer_accept.rs b/ethportal-peertest/src/scenarios/offer_accept.rs index ff712ab97..34b9ac10f 100644 --- a/ethportal-peertest/src/scenarios/offer_accept.rs +++ b/ethportal-peertest/src/scenarios/offer_accept.rs @@ -81,8 +81,7 @@ pub async fn test_populated_offer(peertest: &Peertest, target: &Client) { let result = target .offer( Enr::from_str(&peertest.bootnode.enr.to_base64()).unwrap(), - content_key.clone(), - content_value.encode(), + vec![(content_key.clone(), content_value.encode())], ) .await .unwrap(); @@ -144,8 +143,7 @@ pub async fn test_offer_propagates_gossip(peertest: &Peertest, target: &Client) target .offer( peertest.bootnode.enr.clone(), - content_key.clone(), - content_value.encode(), + vec![(content_key.clone(), content_value.encode())], ) .await .unwrap(); @@ -221,8 +219,7 @@ pub async fn test_offer_propagates_gossip_multiple_content_values( target .offer( peertest.bootnode.enr.clone(), - header_key.clone(), - header_value.encode(), + vec![(header_key.clone(), header_value.encode())], ) .await .unwrap(); diff --git a/ethportal-peertest/src/scenarios/state.rs b/ethportal-peertest/src/scenarios/state.rs index 457ef3c54..2af697855 100644 --- a/ethportal-peertest/src/scenarios/state.rs +++ b/ethportal-peertest/src/scenarios/state.rs @@ -63,8 +63,7 @@ async fn test_state_offer(fixture: &StateFixture, target: &Client, peer: &Peerte StateNetworkApiClient::offer( target, peer.enr.clone(), - fixture.key.clone(), - fixture.raw_offer_value.clone(), + vec![(fixture.key.clone(), fixture.raw_offer_value.clone())], ) .await .unwrap(); diff --git a/portalnet/src/overlay/protocol.rs b/portalnet/src/overlay/protocol.rs index 92e043a8b..ff93b7b8c 100644 --- a/portalnet/src/overlay/protocol.rs +++ b/portalnet/src/overlay/protocol.rs @@ -509,13 +509,10 @@ where pub async fn send_offer( &self, enr: Enr, - content_key: RawContentKey, - content_value: Vec, + content_items: Vec<(RawContentKey, Vec)>, ) -> Result { // Construct the request. - let request = Request::PopulatedOffer(PopulatedOffer { - content_items: vec![(content_key, content_value)], - }); + let request = Request::PopulatedOffer(PopulatedOffer { content_items }); let direction = RequestDirection::Outgoing { destination: enr.clone(), diff --git a/rpc/src/beacon_rpc.rs b/rpc/src/beacon_rpc.rs index c72e6e66c..285955851 100644 --- a/rpc/src/beacon_rpc.rs +++ b/rpc/src/beacon_rpc.rs @@ -179,23 +179,28 @@ impl BeaconNetworkApiServer for BeaconNetworkApi { Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. async fn offer( &self, enr: Enr, - content_key: BeaconContentKey, - content_value: RawContentValue, + content_items: Vec<(BeaconContentKey, RawContentValue)>, ) -> RpcResult { - let content_value = BeaconContentValue::decode(&content_key, &content_value) - .map_err(RpcServeError::from)?; - let endpoint = BeaconEndpoint::Offer(enr, content_key, content_value); + let content_items = content_items + .into_iter() + .map(|(key, value)| { + BeaconContentValue::decode(&key, &value) + .map(|value| (key, value)) + .map_err(RpcServeError::from) + }) + .collect::, _>>()?; + let endpoint = BeaconEndpoint::Offer(enr, content_items); Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns trace info from the offer. async fn trace_offer( @@ -210,7 +215,7 @@ impl BeaconNetworkApiServer for BeaconNetworkApi { Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKeys, to the designated peer and wait for a + /// Send an OFFER request with given ContentItemss, 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. diff --git a/rpc/src/history_rpc.rs b/rpc/src/history_rpc.rs index c806e0af5..a0a384e38 100644 --- a/rpc/src/history_rpc.rs +++ b/rpc/src/history_rpc.rs @@ -152,23 +152,28 @@ impl HistoryNetworkApiServer for HistoryNetworkApi { Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. async fn offer( &self, enr: Enr, - content_key: HistoryContentKey, - content_value: RawContentValue, + content_items: Vec<(HistoryContentKey, RawContentValue)>, ) -> RpcResult { - let content_value = HistoryContentValue::decode(&content_key, &content_value) - .map_err(RpcServeError::from)?; - let endpoint = HistoryEndpoint::Offer(enr, content_key, content_value); + let content_items = content_items + .into_iter() + .map(|(key, value)| { + HistoryContentValue::decode(&key, &value) + .map(|value| (key, value)) + .map_err(RpcServeError::from) + }) + .collect::, _>>()?; + let endpoint = HistoryEndpoint::Offer(enr, content_items); Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns true if the content was accepted and successfully transferred, /// returns false if the content was not accepted or the transfer failed. @@ -184,7 +189,7 @@ impl HistoryNetworkApiServer for HistoryNetworkApi { Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKeys, to the designated peer and wait for a + /// Send an OFFER request with given ContentItemss, 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. diff --git a/rpc/src/state_rpc.rs b/rpc/src/state_rpc.rs index b29deaf31..198b12708 100644 --- a/rpc/src/state_rpc.rs +++ b/rpc/src/state_rpc.rs @@ -145,23 +145,25 @@ impl StateNetworkApiServer for StateNetworkApi { Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer and wait for a response. + /// Send an OFFER request with given ContentItems, to the designated peer and wait for a response. /// Does not store content locally. /// Returns the content keys bitlist upon successful content transmission or empty bitlist /// receive. async fn offer( &self, enr: Enr, - content_key: StateContentKey, - content_value: RawContentValue, + content_items: Vec<(StateContentKey, RawContentValue)>, ) -> RpcResult { - let content_value = - StateContentValue::decode(&content_key, &content_value).map_err(RpcServeError::from)?; - let endpoint = StateEndpoint::Offer(enr, content_key, content_value); + let content_items = content_items + .into_iter() + .map(|(key, value)| StateContentValue::decode(&key, &value).map(|value| (key, value))) + .collect::, _>>() + .map_err(RpcServeError::from)?; + let endpoint = StateEndpoint::Offer(enr, content_items); Ok(proxy_to_subnet(&self.network, endpoint).await?) } - /// Send an OFFER request with given ContentKey, to the designated peer. + /// Send an OFFER request with given ContentItems, to the designated peer. /// Does not store the content locally. /// Returns trace info from the offer. async fn trace_offer( diff --git a/trin-beacon/src/jsonrpc.rs b/trin-beacon/src/jsonrpc.rs index b4dbe3fd8..511c2c550 100644 --- a/trin-beacon/src/jsonrpc.rs +++ b/trin-beacon/src/jsonrpc.rs @@ -72,9 +72,7 @@ async fn complete_request(network: Arc, request: BeaconJsonRpcReq } BeaconEndpoint::LightClientStore => light_client_store(&network).await, BeaconEndpoint::LookupEnr(node_id) => lookup_enr(network, node_id).await, - BeaconEndpoint::Offer(enr, content_key, content_value) => { - offer(network, enr, content_key, content_value).await - } + BeaconEndpoint::Offer(enr, content_items) => offer(network, enr, content_items).await, BeaconEndpoint::WireOffer(enr, content_keys) => { wire_offer(network, enr, content_keys).await } @@ -363,14 +361,13 @@ async fn gossip( async fn offer( network: Arc, enr: discv5::enr::Enr, - content_key: BeaconContentKey, - content_value: BeaconContentValue, + content_items: Vec<(BeaconContentKey, BeaconContentValue)>, ) -> Result { - match network - .overlay - .send_offer(enr, content_key.to_bytes(), content_value.encode().to_vec()) - .await - { + let content_items = content_items + .into_iter() + .map(|(key, value)| (key.to_bytes(), value.encode().to_vec())) + .collect(); + match network.overlay.send_offer(enr, content_items).await { Ok(accept) => Ok(json!(AcceptInfo { content_keys: accept.content_keys, })), diff --git a/trin-history/src/jsonrpc.rs b/trin-history/src/jsonrpc.rs index 0ded5881f..ff797630d 100644 --- a/trin-history/src/jsonrpc.rs +++ b/trin-history/src/jsonrpc.rs @@ -70,9 +70,7 @@ async fn complete_request(network: Arc, request: HistoryJsonRpcR trace_gossip(network, content_key, content_value).await } HistoryEndpoint::LookupEnr(node_id) => lookup_enr(network, node_id).await, - HistoryEndpoint::Offer(enr, content_key, content_value) => { - offer(network, enr, content_key, content_value).await - } + HistoryEndpoint::Offer(enr, content_items) => offer(network, enr, content_items).await, HistoryEndpoint::TraceOffer(enr, content_key, content_value) => { trace_offer(network, enr, content_key, content_value).await } @@ -335,14 +333,13 @@ async fn trace_gossip( async fn offer( network: Arc, enr: discv5::enr::Enr, - content_key: HistoryContentKey, - content_value: HistoryContentValue, + content_items: Vec<(HistoryContentKey, HistoryContentValue)>, ) -> Result { - match network - .overlay - .send_offer(enr, content_key.to_bytes(), content_value.encode().to_vec()) - .await - { + let content_items = content_items + .into_iter() + .map(|(key, value)| (key.to_bytes(), value.encode().to_vec())) + .collect(); + match network.overlay.send_offer(enr, content_items).await { Ok(accept) => Ok(json!(AcceptInfo { content_keys: accept.content_keys, })), diff --git a/trin-state/src/jsonrpc.rs b/trin-state/src/jsonrpc.rs index cbc8682b0..657f9a61a 100644 --- a/trin-state/src/jsonrpc.rs +++ b/trin-state/src/jsonrpc.rs @@ -61,9 +61,7 @@ impl StateRequestHandler { StateEndpoint::Store(content_key, content_value) => { store(network, content_key, content_value).await } - StateEndpoint::Offer(enr, content_key, content_value) => { - offer(network, enr, content_key, content_value).await - } + StateEndpoint::Offer(enr, content_items) => offer(network, enr, content_items).await, StateEndpoint::TraceOffer(enr, content_key, content_value) => { trace_offer(network, enr, content_key, content_value).await } @@ -303,14 +301,18 @@ async fn store( async fn offer( network: Arc, enr: Enr, - content_key: StateContentKey, - content_value: StateContentValue, + content_items: Vec<(StateContentKey, StateContentValue)>, ) -> Result { + let content_items = content_items + .into_iter() + .map(|(key, value)| (key.to_bytes(), value.encode().to_vec())) + .collect(); + to_json_result( "Offer", network .overlay - .send_offer(enr, content_key.to_bytes(), content_value.encode().to_vec()) + .send_offer(enr, content_items) .await .map(|accept| AcceptInfo { content_keys: accept.content_keys,