Correct get_o_indexes to work for 0-output TXs

This commit is contained in:
Luke Parker
2023-07-17 12:57:17 -04:00
parent a0f8214d48
commit 56f7037084

View File

@@ -369,11 +369,14 @@ impl<R: RpcConnection> Rpc<R> {
let mut indexes: &[u8] = indexes_buf.as_ref(); let mut indexes: &[u8] = indexes_buf.as_ref();
(|| { (|| {
let mut res = None;
let mut is_okay = false;
if read_bytes::<_, { EPEE_HEADER.len() }>(&mut indexes)? != EPEE_HEADER { if read_bytes::<_, { EPEE_HEADER.len() }>(&mut indexes)? != EPEE_HEADER {
Err(io::Error::new(io::ErrorKind::Other, "invalid header"))?; Err(io::Error::new(io::ErrorKind::Other, "invalid header"))?;
} }
let read_object = |reader: &mut &[u8]| { let read_object = |reader: &mut &[u8]| -> io::Result<Vec<u64>> {
let fields = read_byte(reader)? >> 2; let fields = read_byte(reader)? >> 2;
for _ in 0 .. fields { for _ in 0 .. fields {
@@ -437,25 +440,50 @@ impl<R: RpcConnection> Rpc<R> {
} }
}; };
let mut res = vec![]; let mut bytes_res = vec![];
for _ in 0 .. iters { for _ in 0 .. iters {
res.push(f(reader)?); bytes_res.push(f(reader)?);
} }
let mut actual_res = Vec::with_capacity(res.len()); let mut actual_res = Vec::with_capacity(bytes_res.len());
if &name == b"o_indexes" { match name.as_slice() {
for o_index in res { b"o_indexes" => {
actual_res.push(u64::from_le_bytes(o_index.try_into().map_err(|_| { for o_index in bytes_res {
io::Error::new(io::ErrorKind::Other, "node didn't provide 8 bytes for a u64") actual_res.push(u64::from_le_bytes(o_index.try_into().map_err(|_| {
})?)); io::Error::new(io::ErrorKind::Other, "node didn't provide 8 bytes for a u64")
})?));
}
res = Some(actual_res);
} }
return Ok(actual_res); b"status" => {
if bytes_res
.get(0)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "status wasn't a string"))?
.as_slice() !=
b"OK"
{
// TODO: Better handle non-OK responses
Err(io::Error::new(io::ErrorKind::Other, "response wasn't OK"))?;
}
is_okay = true;
}
_ => continue,
}
if is_okay && res.is_some() {
break;
} }
} }
// Didn't return a response with o_indexes // Didn't return a response with a status
// TODO: Check if this didn't have o_indexes because it's an error response // (if the status wasn't okay, we would've already errored)
Err(io::Error::new(io::ErrorKind::Other, "response didn't contain o_indexes")) if !is_okay {
Err(io::Error::new(io::ErrorKind::Other, "response didn't contain a status"))?;
}
// If the Vec was empty, it would've been omitted, hence the unwrap_or
// TODO: Test against a 0-output TX, such as the ones found in block 202612
Ok(res.unwrap_or(vec![]))
}; };
read_object(&mut indexes) read_object(&mut indexes)