fix get_txid for /get_outs

miner transaction was not accounted for
This commit is contained in:
hinto.janai 2024-12-19 18:10:43 -05:00
parent cb6fdb76e4
commit dff77e8bed
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
6 changed files with 49 additions and 23 deletions

View file

@ -47,8 +47,11 @@ use crate::constants::{
/// assert_eq!(to_string(&other).unwrap(), r#""OTHER""#);
///
/// assert_eq!(Status::Ok.as_ref(), CORE_RPC_STATUS_OK);
/// assert_eq!("Ok", CORE_RPC_STATUS_OK);
/// assert_eq!(Status::Failed.as_ref(), CORE_RPC_STATUS_FAILED);
/// assert_eq!("FAILED", CORE_RPC_STATUS_FAILED);
/// assert_eq!(Status::Busy.as_ref(), CORE_RPC_STATUS_BUSY);
/// assert_eq!("Busy", CORE_RPC_STATUS_BUSY);
/// assert_eq!(Status::NotMining.as_ref(), CORE_RPC_STATUS_NOT_MINING);
/// assert_eq!(Status::PaymentRequired.as_ref(), CORE_RPC_STATUS_PAYMENT_REQUIRED);
/// assert_eq!(other.as_ref(), "OTHER");
@ -74,16 +77,16 @@ pub enum Status {
// `#[serde(rename = "")]` only takes raw string literals?
// We have to re-type the constants here...
/// Successful RPC response, everything is OK; [`CORE_RPC_STATUS_OK`].
#[cfg_attr(feature = "serde", serde(rename = "OK"))]
#[cfg_attr(feature = "serde", serde(rename = "OK", alias = "Ok"))]
#[default]
Ok,
/// Generic request failure.
#[cfg_attr(feature = "serde", serde(rename = "Failed"))]
#[cfg_attr(feature = "serde", serde(alias = "FAILED"))]
Failed,
/// The daemon is busy, try later; [`CORE_RPC_STATUS_BUSY`].
#[cfg_attr(feature = "serde", serde(rename = "BUSY"))]
#[cfg_attr(feature = "serde", serde(rename = "BUSY", alias = "Busy"))]
Busy,
/// The daemon is not mining; [`CORE_RPC_STATUS_NOT_MINING`].

View file

@ -785,7 +785,7 @@ mod test {
SendRawTransactionResponse {
base: AccessResponseBase {
response_base: ResponseBase {
status: Status::Other("Failed".into()),
status: Status::Failed,
untrusted: false,
},
credits: 0,

View file

@ -2,7 +2,7 @@
//---------------------------------------------------------------------------------------------------- Import
use curve25519_dalek::edwards::CompressedEdwardsY;
use monero_serai::transaction::Timelock;
use monero_serai::transaction::{Timelock, Transaction};
use cuprate_database::{
DbResult, RuntimeError, {DatabaseRo, DatabaseRw},
@ -13,7 +13,9 @@ use cuprate_types::OutputOnChain;
use crate::{
ops::macros::{doc_add_block_inner_invariant, doc_error},
tables::{BlockTxsHashes, Outputs, RctOutputs, Tables, TablesMut, TxUnlockTime},
tables::{
BlockInfos, BlockTxsHashes, Outputs, RctOutputs, Tables, TablesMut, TxBlobs, TxUnlockTime,
},
types::{Amount, AmountIndex, Output, OutputFlags, PreRctOutputId, RctOutput},
};
@ -154,6 +156,8 @@ pub fn output_to_output_on_chain(
amount: Amount,
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
table_block_infos: &impl DatabaseRo<BlockInfos>,
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
) -> DbResult<OutputOnChain> {
let commitment = compute_zero_commitment(amount);
@ -173,7 +177,13 @@ pub fn output_to_output_on_chain(
let txid = {
let height = u32_to_usize(output.height);
let tx_idx = u64_to_usize(output.tx_idx);
table_block_txs_hashes.get(&height)?[tx_idx]
if let Some(hash) = table_block_txs_hashes.get(&height)?.get(tx_idx) {
*hash
} else {
let miner_tx_id = table_block_infos.get(&height)?.mining_tx_index;
let tx_blob = table_tx_blobs.get(&miner_tx_id)?;
Transaction::read(&mut tx_blob.0.as_slice())?.hash()
}
};
Ok(OutputOnChain {
@ -198,6 +208,8 @@ pub fn rct_output_to_output_on_chain(
rct_output: &RctOutput,
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
table_block_infos: &impl DatabaseRo<BlockInfos>,
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
) -> DbResult<OutputOnChain> {
// INVARIANT: Commitments stored are valid when stored by the database.
let commitment = CompressedEdwardsY::from_slice(&rct_output.commitment)
@ -221,7 +233,13 @@ pub fn rct_output_to_output_on_chain(
let txid = {
let height = u32_to_usize(rct_output.height);
let tx_idx = u64_to_usize(rct_output.tx_idx);
table_block_txs_hashes.get(&height)?[tx_idx]
if let Some(hash) = table_block_txs_hashes.get(&height)?.get(tx_idx) {
*hash
} else {
let miner_tx_id = table_block_infos.get(&height)?.mining_tx_index;
let tx_blob = table_tx_blobs.get(&miner_tx_id)?;
Transaction::read(&mut tx_blob.0.as_slice())?.hash()
}
};
Ok(OutputOnChain {
@ -245,6 +263,8 @@ pub fn id_to_output_on_chain(id: &PreRctOutputId, tables: &impl Tables) -> DbRes
&rct_output,
tables.tx_unlock_time(),
tables.block_txs_hashes(),
tables.block_infos(),
tables.tx_blobs(),
)?;
Ok(output_on_chain)
@ -256,6 +276,8 @@ pub fn id_to_output_on_chain(id: &PreRctOutputId, tables: &impl Tables) -> DbRes
id.amount,
tables.tx_unlock_time(),
tables.block_txs_hashes(),
tables.block_infos(),
tables.tx_blobs(),
)?;
Ok(output_on_chain)

View file

@ -1,7 +1,2 @@
# `cuprate-hex`
Cuprate's hexadecimal data types.
# Features flags
| Feature flag | Does what |
|--------------|-----------|
| `serde` | Enables `serde` on types where applicable
Cuprate's hexadecimal data types.

View file

@ -1 +0,0 @@

View file

@ -11,18 +11,18 @@ use serde::{Deserialize, Deserializer, Serialize};
/// ```rust
/// # use cuprate_hex::HexVec;
/// let hash = [1; 32];
/// let hex_bytes = HexVec(hash);
/// let hex_vec = HexVec(hash);
/// let expected_json = r#""0101010101010101010101010101010101010101010101010101010101010101""#;
///
/// let to_string = serde_json::to_string(&hex_bytes).unwrap();
/// let to_string = serde_json::to_string(&hex_vec).unwrap();
/// assert_eq!(to_string, expected_json);
///
/// let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
/// assert_eq!(hex_bytes, from_str);
/// assert_eq!(hex_vec, from_str);
///
/// //------
///
/// let vec = vec![hex_bytes; 2];
/// let vec = vec![hex_vec; 2];
/// let expected_json = r#"["0101010101010101010101010101010101010101010101010101010101010101","0101010101010101010101010101010101010101010101010101010101010101"]"#;
///
/// let to_string = serde_json::to_string(&vec).unwrap();
@ -47,7 +47,14 @@ impl HexVec {
self.0.is_empty()
}
/// TODO
/// Returns an empty [`Self`] if `array` is all `0`s.
///
/// ```rust
/// # use cuprate_hex::HexVec;
/// assert_eq!(HexVec::empty_if_zeroed([1; 32]), [1; 32]);
/// assert_eq!(HexVec::empty_if_zeroed([0; 32]), HexVec(vec![]));
/// assert!(HexVec::empty_if_zeroed([0; 32]).is_empty());
/// ```
pub fn empty_if_zeroed<const N: usize>(array: [u8; N]) -> Self {
if array == [0; N] {
Self(Vec::new())
@ -112,13 +119,13 @@ mod test {
#[test]
fn asdf() {
let hash = vec![0; 32];
let hex_bytes = HexVec(hash);
let hex_vec = HexVec(hash);
let expected_json = r#""0000000000000000000000000000000000000000000000000000000000000000""#;
let to_string = serde_json::to_string(&hex_bytes).unwrap();
let to_string = serde_json::to_string(&hex_vec).unwrap();
assert_eq!(to_string, expected_json);
let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
assert_eq!(hex_bytes, from_str);
assert_eq!(hex_vec, from_str);
}
}