mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Properly include the non-JSON HTTP result in Monero's RpcError
The CI for 695d1f0ecf actually errored with a
non-JSON response, hence the value in this.
This commit is contained in:
@@ -42,12 +42,10 @@ impl HttpRpc {
|
|||||||
) -> Result<Option<(WwwAuthenticateHeader, u64)>, RpcError> {
|
) -> Result<Option<(WwwAuthenticateHeader, u64)>, RpcError> {
|
||||||
Ok(if let Some(header) = response.headers().get("www-authenticate") {
|
Ok(if let Some(header) = response.headers().get("www-authenticate") {
|
||||||
Some((
|
Some((
|
||||||
digest_auth::parse(
|
digest_auth::parse(header.to_str().map_err(|_| {
|
||||||
header
|
RpcError::InvalidNode("www-authenticate header wasn't a string".to_string())
|
||||||
.to_str()
|
})?)
|
||||||
.map_err(|_| RpcError::InvalidNode("www-authenticate header wasn't a string"))?,
|
.map_err(|_| RpcError::InvalidNode("invalid digest-auth response".to_string()))?,
|
||||||
)
|
|
||||||
.map_err(|_| RpcError::InvalidNode("invalid digest-auth response"))?,
|
|
||||||
0,
|
0,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -161,7 +159,9 @@ impl HttpRpc {
|
|||||||
HeaderValue::from_str(
|
HeaderValue::from_str(
|
||||||
&challenge
|
&challenge
|
||||||
.respond(&context)
|
.respond(&context)
|
||||||
.map_err(|_| RpcError::InvalidNode("couldn't respond to digest-auth challenge"))?
|
.map_err(|_| {
|
||||||
|
RpcError::InvalidNode("couldn't respond to digest-auth challenge".to_string())
|
||||||
|
})?
|
||||||
.to_header_string(),
|
.to_header_string(),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@@ -192,7 +192,9 @@ impl HttpRpc {
|
|||||||
if let Some(header) = response.headers().get("www-authenticate") {
|
if let Some(header) = response.headers().get("www-authenticate") {
|
||||||
header
|
header
|
||||||
.to_str()
|
.to_str()
|
||||||
.map_err(|_| RpcError::InvalidNode("www-authenticate header wasn't a string"))?
|
.map_err(|_| {
|
||||||
|
RpcError::InvalidNode("www-authenticate header wasn't a string".to_string())
|
||||||
|
})?
|
||||||
.contains("stale")
|
.contains("stale")
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ pub enum RpcError {
|
|||||||
#[cfg_attr(feature = "std", error("connection error ({0})"))]
|
#[cfg_attr(feature = "std", error("connection error ({0})"))]
|
||||||
ConnectionError(String),
|
ConnectionError(String),
|
||||||
#[cfg_attr(feature = "std", error("invalid node ({0})"))]
|
#[cfg_attr(feature = "std", error("invalid node ({0})"))]
|
||||||
InvalidNode(&'static str),
|
InvalidNode(String),
|
||||||
#[cfg_attr(feature = "std", error("unsupported protocol version ({0})"))]
|
#[cfg_attr(feature = "std", error("unsupported protocol version ({0})"))]
|
||||||
UnsupportedProtocol(usize),
|
UnsupportedProtocol(usize),
|
||||||
#[cfg_attr(feature = "std", error("transactions not found"))]
|
#[cfg_attr(feature = "std", error("transactions not found"))]
|
||||||
@@ -78,11 +78,11 @@ pub enum RpcError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
|
fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
|
||||||
hex::decode(value).map_err(|_| RpcError::InvalidNode("expected hex wasn't hex"))
|
hex::decode(value).map_err(|_| RpcError::InvalidNode("expected hex wasn't hex".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_hex(hash: &str) -> Result<[u8; 32], RpcError> {
|
fn hash_hex(hash: &str) -> Result<[u8; 32], RpcError> {
|
||||||
rpc_hex(hash)?.try_into().map_err(|_| RpcError::InvalidNode("hash wasn't 32-bytes"))
|
rpc_hex(hash)?.try_into().map_err(|_| RpcError::InvalidNode("hash wasn't 32-bytes".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rpc_point(point: &str) -> Result<EdwardsPoint, RpcError> {
|
fn rpc_point(point: &str) -> Result<EdwardsPoint, RpcError> {
|
||||||
@@ -143,9 +143,9 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let res_str = std_shims::str::from_utf8(&res)
|
let res_str = std_shims::str::from_utf8(&res)
|
||||||
.map_err(|_| RpcError::InvalidNode("response wasn't utf-8"))?;
|
.map_err(|_| RpcError::InvalidNode("response wasn't utf-8".to_string()))?;
|
||||||
serde_json::from_str(res_str)
|
serde_json::from_str(res_str)
|
||||||
.map_err(|_| RpcError::InvalidNode("response wasn't json: {res_str}"))
|
.map_err(|_| RpcError::InvalidNode(format!("response wasn't json: {res_str}")))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a JSON-RPC call with the specified method with the provided parameters
|
/// Perform a JSON-RPC call with the specified method with the provided parameters
|
||||||
@@ -254,7 +254,9 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
// This does run a few keccak256 hashes, which is pointless if the node is trusted
|
// This does run a few keccak256 hashes, which is pointless if the node is trusted
|
||||||
// In exchange, this provides resilience against invalid/malicious nodes
|
// In exchange, this provides resilience against invalid/malicious nodes
|
||||||
if tx.hash() != hashes[i] {
|
if tx.hash() != hashes[i] {
|
||||||
Err(RpcError::InvalidNode("replied with transaction wasn't the requested transaction"))?;
|
Err(RpcError::InvalidNode(
|
||||||
|
"replied with transaction wasn't the requested transaction".to_string(),
|
||||||
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(tx)
|
Ok(tx)
|
||||||
@@ -295,9 +297,9 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
self.json_rpc_call("get_block", Some(json!({ "hash": hex::encode(hash) }))).await?;
|
self.json_rpc_call("get_block", Some(json!({ "hash": hex::encode(hash) }))).await?;
|
||||||
|
|
||||||
let block = Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref())
|
let block = Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref())
|
||||||
.map_err(|_| RpcError::InvalidNode("invalid block"))?;
|
.map_err(|_| RpcError::InvalidNode("invalid block".to_string()))?;
|
||||||
if block.hash() != hash {
|
if block.hash() != hash {
|
||||||
Err(RpcError::InvalidNode("different block than requested (hash)"))?;
|
Err(RpcError::InvalidNode("different block than requested (hash)".to_string()))?;
|
||||||
}
|
}
|
||||||
Ok(block)
|
Ok(block)
|
||||||
}
|
}
|
||||||
@@ -312,7 +314,7 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
self.json_rpc_call("get_block", Some(json!({ "height": number }))).await?;
|
self.json_rpc_call("get_block", Some(json!({ "height": number }))).await?;
|
||||||
|
|
||||||
let block = Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref())
|
let block = Block::read::<&[u8]>(&mut rpc_hex(&res.blob)?.as_ref())
|
||||||
.map_err(|_| RpcError::InvalidNode("invalid block"))?;
|
.map_err(|_| RpcError::InvalidNode("invalid block".to_string()))?;
|
||||||
|
|
||||||
// Make sure this is actually the block for this number
|
// Make sure this is actually the block for this number
|
||||||
match block.miner_tx.prefix.inputs.first() {
|
match block.miner_tx.prefix.inputs.first() {
|
||||||
@@ -320,10 +322,12 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
if usize::try_from(*actual).unwrap() == number {
|
if usize::try_from(*actual).unwrap() == number {
|
||||||
Ok(block)
|
Ok(block)
|
||||||
} else {
|
} else {
|
||||||
Err(RpcError::InvalidNode("different block than requested (number)"))
|
Err(RpcError::InvalidNode("different block than requested (number)".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(RpcError::InvalidNode("block's miner_tx didn't have an input of kind Input::Gen")),
|
_ => Err(RpcError::InvalidNode(
|
||||||
|
"block's miner_tx didn't have an input of kind Input::Gen".to_string(),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +497,7 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
|
|
||||||
read_object(&mut indexes)
|
read_object(&mut indexes)
|
||||||
})()
|
})()
|
||||||
.map_err(|_| RpcError::InvalidNode("invalid binary response"))
|
.map_err(|_| RpcError::InvalidNode("invalid binary response".to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the output distribution, from the specified height to the specified height (both
|
/// Get the output distribution, from the specified height to the specified height (both
|
||||||
@@ -582,7 +586,9 @@ impl<R: RpcConnection> Rpc<R> {
|
|||||||
// invalid keys may honestly exist on the blockchain
|
// invalid keys may honestly exist on the blockchain
|
||||||
// Only a recent hard fork checked output keys were valid points
|
// Only a recent hard fork checked output keys were valid points
|
||||||
let Some(key) = CompressedEdwardsY(
|
let Some(key) = CompressedEdwardsY(
|
||||||
rpc_hex(&out.key)?.try_into().map_err(|_| RpcError::InvalidNode("non-32-byte point"))?,
|
rpc_hex(&out.key)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| RpcError::InvalidNode("non-32-byte point".to_string()))?,
|
||||||
)
|
)
|
||||||
.decompress() else {
|
.decompress() else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ impl SpendableOutput {
|
|||||||
.await?
|
.await?
|
||||||
.get(usize::from(self.output.absolute.o))
|
.get(usize::from(self.output.absolute.o))
|
||||||
.ok_or(RpcError::InvalidNode(
|
.ok_or(RpcError::InvalidNode(
|
||||||
"node returned output indexes didn't include an index for this output",
|
"node returned output indexes didn't include an index for this output".to_string(),
|
||||||
))?;
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user