Contractless/src/rpc/client/block_hash_vote.rs

43 lines
1.4 KiB
Rust

use crate::encode;
use crate::records::memory::response_channels::{reserve_entry, Command};
use crate::rpc::command_maps::RPC_BLOCK_HASH_AT_HEIGHT;
use crate::rpc::responses::RpcResponse;
use crate::{timeout, Arc, Duration, Mutex, TcpStream};
pub async fn request_block_hash_at_height(
stream: Arc<Mutex<TcpStream>>,
map: Arc<Mutex<Command>>,
connections_key: String,
height: u32,
) -> Result<String, String> {
let (hashmap_key, _tx, rx) = reserve_entry(map).await;
let mut message = vec![RPC_BLOCK_HASH_AT_HEIGHT];
message.extend_from_slice(&hashmap_key);
message.extend_from_slice(&height.to_le_bytes());
RpcResponse::send_raw(&stream, Some(&connections_key), &message).await;
let mut rx = rx.lock().await;
let buffer = timeout(Duration::from_secs(5), rx.recv())
.await
.map_err(|_| format!("Timed out waiting for block hash vote at height {height}"))?
.ok_or_else(|| "No block hash vote response received".to_string())?;
if let Ok(response_text) = String::from_utf8(buffer.clone()) {
let trimmed = response_text.trim();
if trimmed.starts_with("error:") {
return Err(trimmed.to_string());
}
}
if buffer.len() != 32 {
return Err(format!(
"Invalid block hash vote length: expected 32, got {}",
buffer.len()
));
}
Ok(encode(buffer))
}