Skip to content

Commit 4a13c94

Browse files
committed
Implement portal_*Offer json-rpc endpoint
1 parent 87e77f1 commit 4a13c94

File tree

6 files changed

+112
-0
lines changed

6 files changed

+112
-0
lines changed

newsfragments/275.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `portal_*Offer` JSON-RPC andpoint

trin-core/src/jsonrpc/endpoints.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum StateEndpoint {
1414
FindContent,
1515
FindNodes,
1616
LocalContent,
17+
Offer,
1718
Ping,
1819
}
1920

@@ -24,6 +25,7 @@ pub enum HistoryEndpoint {
2425
FindContent,
2526
FindNodes,
2627
LocalContent,
28+
Offer,
2729
Ping,
2830
RecursiveFindContent,
2931
}
@@ -77,6 +79,7 @@ impl FromStr for TrinEndpoint {
7779
"portal_historyLocalContent" => {
7880
Ok(TrinEndpoint::HistoryEndpoint(HistoryEndpoint::LocalContent))
7981
}
82+
"portal_historyOffer" => Ok(TrinEndpoint::HistoryEndpoint(HistoryEndpoint::Offer)),
8083
"portal_historyPing" => Ok(TrinEndpoint::HistoryEndpoint(HistoryEndpoint::Ping)),
8184
"portal_historyRadius" => {
8285
Ok(TrinEndpoint::HistoryEndpoint(HistoryEndpoint::DataRadius))
@@ -88,6 +91,7 @@ impl FromStr for TrinEndpoint {
8891
"portal_stateLocalContent" => {
8992
Ok(TrinEndpoint::StateEndpoint(StateEndpoint::LocalContent))
9093
}
94+
"portal_stateOffer" => Ok(TrinEndpoint::StateEndpoint(StateEndpoint::Offer)),
9195
"portal_statePing" => Ok(TrinEndpoint::StateEndpoint(StateEndpoint::Ping)),
9296
"portal_stateRadius" => Ok(TrinEndpoint::StateEndpoint(StateEndpoint::DataRadius)),
9397
_ => Err(()),

trin-core/src/jsonrpc/types.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,65 @@ impl TryFrom<[&Value; 2]> for FindContentParams {
196196
}
197197
}
198198

199+
pub struct OfferParams {
200+
pub enr: SszEnr,
201+
pub content_keys: Vec<ByteList>,
202+
}
203+
204+
impl TryFrom<Params> for OfferParams {
205+
type Error = ValidationError;
206+
207+
fn try_from(params: Params) -> Result<Self, Self::Error> {
208+
match params {
209+
Params::Array(val) => match val.len() {
210+
2 => Self::try_from([&val[0], &val[1]]),
211+
_ => Err(ValidationError::new("Expected 2 params")),
212+
},
213+
_ => Err(ValidationError::new("Expected array of params")),
214+
}
215+
}
216+
}
217+
218+
impl TryFrom<[&Value; 2]> for OfferParams {
219+
type Error = ValidationError;
220+
221+
fn try_from(params: [&Value; 2]) -> Result<Self, Self::Error> {
222+
let enr: SszEnr = params[0].try_into()?;
223+
224+
let content_keys = params[1].as_array();
225+
226+
match content_keys {
227+
Some(content_keys) => {
228+
let content_keys: Result<Vec<String>, _> = content_keys
229+
.iter()
230+
.cloned()
231+
.map(serde_json::from_value)
232+
.collect();
233+
234+
if let Ok(content_keys) = content_keys {
235+
let content_keys: Result<Vec<Vec<u8>>, _> =
236+
content_keys.iter().map(hex::decode).collect();
237+
238+
if let Ok(content_keys) = content_keys {
239+
Ok(Self {
240+
enr,
241+
content_keys: content_keys
242+
.into_iter()
243+
.map(VariableList::from)
244+
.collect(),
245+
})
246+
} else {
247+
Err(ValidationError::new("Unable to hex decode content keys"))
248+
}
249+
} else {
250+
Err(ValidationError::new("Unable to decode content keys"))
251+
}
252+
}
253+
None => Err(ValidationError::new("Required a list of content keys")),
254+
}
255+
}
256+
}
257+
199258
pub struct RecursiveFindContentParams {
200259
pub content_key: ByteList,
201260
}

trin-core/src/portalnet/types/messages.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,12 @@ pub struct Accept {
491491
pub content_keys: BitList<typenum::U8>,
492492
}
493493

494+
impl Into<Value> for Accept {
495+
fn into(self) -> Value {
496+
serde_json::json!({ "connection_id": format!("{:?}", self.connection_id.to_be()) , "content_keys": self.content_keys})
497+
}
498+
}
499+
494500
#[derive(Debug, PartialEq, Clone)]
495501
pub struct SszEnr(Enr);
496502

trin-history/src/jsonrpc.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use serde_json::{json, Value};
55
use tokio::sync::mpsc;
66

77
use crate::network::HistoryNetwork;
8+
use trin_core::jsonrpc::types::OfferParams;
89
use trin_core::jsonrpc::{
910
endpoints::HistoryEndpoint,
1011
types::{
@@ -170,6 +171,26 @@ impl HistoryRequestHandler {
170171
};
171172
let _ = request.resp.send(response);
172173
}
174+
HistoryEndpoint::Offer => {
175+
let response = match OfferParams::try_from(request.params) {
176+
Ok(val) => {
177+
let content_keys =
178+
val.content_keys.iter().map(|key| key.to_vec()).collect();
179+
180+
match self
181+
.network
182+
.overlay
183+
.send_offer(content_keys, val.enr.into())
184+
.await
185+
{
186+
Ok(accept) => Ok(accept.into()),
187+
Err(msg) => Err(format!("Offer request timeout: {:?}", msg)),
188+
}
189+
}
190+
Err(msg) => Err(format!("Invalid Offer params: {:?}", msg)),
191+
};
192+
let _ = request.resp.send(response);
193+
}
173194
HistoryEndpoint::Ping => {
174195
let response = match PingParams::try_from(request.params) {
175196
Ok(val) => match self.network.overlay.send_ping(val.enr.into()).await {

trin-state/src/jsonrpc.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use serde_json::Value;
44
use tokio::sync::mpsc;
55

66
use crate::network::StateNetwork;
7+
use trin_core::jsonrpc::types::OfferParams;
78
use trin_core::jsonrpc::{
89
endpoints::StateEndpoint,
910
types::{
@@ -81,6 +82,26 @@ impl StateRequestHandler {
8182
};
8283
let _ = request.resp.send(response);
8384
}
85+
StateEndpoint::Offer => {
86+
let response = match OfferParams::try_from(request.params) {
87+
Ok(val) => {
88+
let content_keys =
89+
val.content_keys.iter().map(|key| key.to_vec()).collect();
90+
91+
match self
92+
.network
93+
.overlay
94+
.send_offer(content_keys, val.enr.into())
95+
.await
96+
{
97+
Ok(accept) => Ok(accept.into()),
98+
Err(msg) => Err(format!("Offer request timeout: {:?}", msg)),
99+
}
100+
}
101+
Err(msg) => Err(format!("Invalid Offer params: {:?}", msg)),
102+
};
103+
let _ = request.resp.send(response);
104+
}
84105
StateEndpoint::Ping => {
85106
let response = match PingParams::try_from(request.params) {
86107
Ok(val) => match self.network.overlay.send_ping(val.enr.into()).await {

0 commit comments

Comments
 (0)