Luke Parker
2022-08-22 12:15:14 -04:00
parent 5a1f011db8
commit 5c106cecf6
9 changed files with 258 additions and 155 deletions

View File

@@ -138,12 +138,9 @@ impl Rpc {
Ok(self.rpc_call::<Option<()>, HeightResponse>("get_height", None).await?.height)
}
async fn get_transactions_core(
&self,
hashes: &[[u8; 32]],
) -> Result<(Vec<Result<Transaction, RpcError>>, Vec<[u8; 32]>), RpcError> {
pub async fn get_transactions(&self, hashes: &[[u8; 32]]) -> Result<Vec<Transaction>, RpcError> {
if hashes.is_empty() {
return Ok((vec![], vec![]));
return Ok(vec![]);
}
#[derive(Deserialize, Debug)]
@@ -168,50 +165,34 @@ impl Rpc {
)
.await?;
Ok((
txs
.txs
.iter()
.map(|res| {
let tx = Transaction::deserialize(&mut std::io::Cursor::new(
rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex }).unwrap(),
))
.map_err(|_| {
RpcError::InvalidTransaction(hex::decode(&res.tx_hash).unwrap().try_into().unwrap())
})?;
// https://github.com/monero-project/monero/issues/8311
if res.as_hex.is_empty() {
match tx.prefix.inputs.get(0) {
Some(Input::Gen { .. }) => (),
_ => Err(RpcError::PrunedTransaction)?,
}
}
Ok(tx)
})
.collect(),
txs.missed_tx.iter().map(|hash| hex::decode(&hash).unwrap().try_into().unwrap()).collect(),
))
}
pub async fn get_transactions(&self, hashes: &[[u8; 32]]) -> Result<Vec<Transaction>, RpcError> {
let (txs, missed) = self.get_transactions_core(hashes).await?;
if !missed.is_empty() {
Err(RpcError::TransactionsNotFound(missed))?;
if txs.missed_tx.len() != 0 {
Err(RpcError::TransactionsNotFound(
txs.missed_tx.iter().map(|hash| hex::decode(&hash).unwrap().try_into().unwrap()).collect(),
))?;
}
// This will clone several KB and is accordingly inefficient
// TODO: Optimize
txs.iter().cloned().collect::<Result<_, _>>()
}
// TODO: Remove with https://github.com/serai-dex/serai/issues/25
pub async fn get_transactions_possible(
&self,
hashes: &[[u8; 32]],
) -> Result<Vec<Transaction>, RpcError> {
let (txs, _) = self.get_transactions_core(hashes).await?;
Ok(txs.iter().cloned().filter_map(|tx| tx.ok()).collect())
txs
.txs
.iter()
.map(|res| {
let tx = Transaction::deserialize(&mut std::io::Cursor::new(
rpc_hex(if !res.as_hex.is_empty() { &res.as_hex } else { &res.pruned_as_hex }).unwrap(),
))
.map_err(|_| {
RpcError::InvalidTransaction(hex::decode(&res.tx_hash).unwrap().try_into().unwrap())
})?;
// https://github.com/monero-project/monero/issues/8311
if res.as_hex.is_empty() {
match tx.prefix.inputs.get(0) {
Some(Input::Gen { .. }) => (),
_ => Err(RpcError::PrunedTransaction)?,
}
}
Ok(tx)
})
.collect()
}
pub async fn get_block(&self, height: usize) -> Result<Block, RpcError> {
@@ -238,32 +219,13 @@ impl Rpc {
)
}
async fn get_block_transactions_core(
&self,
height: usize,
possible: bool,
) -> Result<Vec<Transaction>, RpcError> {
pub async fn get_block_transactions(&self, height: usize) -> Result<Vec<Transaction>, RpcError> {
let block = self.get_block(height).await?;
let mut res = vec![block.miner_tx];
res.extend(if possible {
self.get_transactions_possible(&block.txs).await?
} else {
self.get_transactions(&block.txs).await?
});
res.extend(self.get_transactions(&block.txs).await?);
Ok(res)
}
pub async fn get_block_transactions(&self, height: usize) -> Result<Vec<Transaction>, RpcError> {
self.get_block_transactions_core(height, false).await
}
pub async fn get_block_transactions_possible(
&self,
height: usize,
) -> Result<Vec<Transaction>, RpcError> {
self.get_block_transactions_core(height, true).await
}
pub async fn get_o_indexes(&self, hash: [u8; 32]) -> Result<Vec<u64>, RpcError> {
#[derive(Serialize, Debug)]
struct Request {