mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 11:39:30 +00:00
fix get_txid
for /get_outs
miner transaction was not accounted for
This commit is contained in:
parent
cb6fdb76e4
commit
dff77e8bed
6 changed files with 49 additions and 23 deletions
|
@ -47,8 +47,11 @@ use crate::constants::{
|
||||||
/// assert_eq!(to_string(&other).unwrap(), r#""OTHER""#);
|
/// assert_eq!(to_string(&other).unwrap(), r#""OTHER""#);
|
||||||
///
|
///
|
||||||
/// assert_eq!(Status::Ok.as_ref(), CORE_RPC_STATUS_OK);
|
/// 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!(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!(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::NotMining.as_ref(), CORE_RPC_STATUS_NOT_MINING);
|
||||||
/// assert_eq!(Status::PaymentRequired.as_ref(), CORE_RPC_STATUS_PAYMENT_REQUIRED);
|
/// assert_eq!(Status::PaymentRequired.as_ref(), CORE_RPC_STATUS_PAYMENT_REQUIRED);
|
||||||
/// assert_eq!(other.as_ref(), "OTHER");
|
/// assert_eq!(other.as_ref(), "OTHER");
|
||||||
|
@ -74,16 +77,16 @@ pub enum Status {
|
||||||
// `#[serde(rename = "")]` only takes raw string literals?
|
// `#[serde(rename = "")]` only takes raw string literals?
|
||||||
// We have to re-type the constants here...
|
// We have to re-type the constants here...
|
||||||
/// Successful RPC response, everything is OK; [`CORE_RPC_STATUS_OK`].
|
/// 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]
|
#[default]
|
||||||
Ok,
|
Ok,
|
||||||
|
|
||||||
/// Generic request failure.
|
/// Generic request failure.
|
||||||
#[cfg_attr(feature = "serde", serde(rename = "Failed"))]
|
#[cfg_attr(feature = "serde", serde(alias = "FAILED"))]
|
||||||
Failed,
|
Failed,
|
||||||
|
|
||||||
/// The daemon is busy, try later; [`CORE_RPC_STATUS_BUSY`].
|
/// 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,
|
Busy,
|
||||||
|
|
||||||
/// The daemon is not mining; [`CORE_RPC_STATUS_NOT_MINING`].
|
/// The daemon is not mining; [`CORE_RPC_STATUS_NOT_MINING`].
|
||||||
|
|
|
@ -785,7 +785,7 @@ mod test {
|
||||||
SendRawTransactionResponse {
|
SendRawTransactionResponse {
|
||||||
base: AccessResponseBase {
|
base: AccessResponseBase {
|
||||||
response_base: ResponseBase {
|
response_base: ResponseBase {
|
||||||
status: Status::Other("Failed".into()),
|
status: Status::Failed,
|
||||||
untrusted: false,
|
untrusted: false,
|
||||||
},
|
},
|
||||||
credits: 0,
|
credits: 0,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use curve25519_dalek::edwards::CompressedEdwardsY;
|
use curve25519_dalek::edwards::CompressedEdwardsY;
|
||||||
use monero_serai::transaction::Timelock;
|
use monero_serai::transaction::{Timelock, Transaction};
|
||||||
|
|
||||||
use cuprate_database::{
|
use cuprate_database::{
|
||||||
DbResult, RuntimeError, {DatabaseRo, DatabaseRw},
|
DbResult, RuntimeError, {DatabaseRo, DatabaseRw},
|
||||||
|
@ -13,7 +13,9 @@ use cuprate_types::OutputOnChain;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ops::macros::{doc_add_block_inner_invariant, doc_error},
|
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},
|
types::{Amount, AmountIndex, Output, OutputFlags, PreRctOutputId, RctOutput},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,6 +156,8 @@ pub fn output_to_output_on_chain(
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
||||||
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
|
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
|
||||||
|
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
||||||
|
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
||||||
) -> DbResult<OutputOnChain> {
|
) -> DbResult<OutputOnChain> {
|
||||||
let commitment = compute_zero_commitment(amount);
|
let commitment = compute_zero_commitment(amount);
|
||||||
|
|
||||||
|
@ -173,7 +177,13 @@ pub fn output_to_output_on_chain(
|
||||||
let txid = {
|
let txid = {
|
||||||
let height = u32_to_usize(output.height);
|
let height = u32_to_usize(output.height);
|
||||||
let tx_idx = u64_to_usize(output.tx_idx);
|
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 {
|
Ok(OutputOnChain {
|
||||||
|
@ -198,6 +208,8 @@ pub fn rct_output_to_output_on_chain(
|
||||||
rct_output: &RctOutput,
|
rct_output: &RctOutput,
|
||||||
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
||||||
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
|
table_block_txs_hashes: &impl DatabaseRo<BlockTxsHashes>,
|
||||||
|
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
||||||
|
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
||||||
) -> DbResult<OutputOnChain> {
|
) -> DbResult<OutputOnChain> {
|
||||||
// INVARIANT: Commitments stored are valid when stored by the database.
|
// INVARIANT: Commitments stored are valid when stored by the database.
|
||||||
let commitment = CompressedEdwardsY::from_slice(&rct_output.commitment)
|
let commitment = CompressedEdwardsY::from_slice(&rct_output.commitment)
|
||||||
|
@ -221,7 +233,13 @@ pub fn rct_output_to_output_on_chain(
|
||||||
let txid = {
|
let txid = {
|
||||||
let height = u32_to_usize(rct_output.height);
|
let height = u32_to_usize(rct_output.height);
|
||||||
let tx_idx = u64_to_usize(rct_output.tx_idx);
|
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 {
|
Ok(OutputOnChain {
|
||||||
|
@ -245,6 +263,8 @@ pub fn id_to_output_on_chain(id: &PreRctOutputId, tables: &impl Tables) -> DbRes
|
||||||
&rct_output,
|
&rct_output,
|
||||||
tables.tx_unlock_time(),
|
tables.tx_unlock_time(),
|
||||||
tables.block_txs_hashes(),
|
tables.block_txs_hashes(),
|
||||||
|
tables.block_infos(),
|
||||||
|
tables.tx_blobs(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(output_on_chain)
|
Ok(output_on_chain)
|
||||||
|
@ -256,6 +276,8 @@ pub fn id_to_output_on_chain(id: &PreRctOutputId, tables: &impl Tables) -> DbRes
|
||||||
id.amount,
|
id.amount,
|
||||||
tables.tx_unlock_time(),
|
tables.tx_unlock_time(),
|
||||||
tables.block_txs_hashes(),
|
tables.block_txs_hashes(),
|
||||||
|
tables.block_infos(),
|
||||||
|
tables.tx_blobs(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(output_on_chain)
|
Ok(output_on_chain)
|
||||||
|
|
|
@ -1,7 +1,2 @@
|
||||||
# `cuprate-hex`
|
# `cuprate-hex`
|
||||||
Cuprate's hexadecimal data types.
|
Cuprate's hexadecimal data types.
|
||||||
|
|
||||||
# Features flags
|
|
||||||
| Feature flag | Does what |
|
|
||||||
|--------------|-----------|
|
|
||||||
| `serde` | Enables `serde` on types where applicable
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -11,18 +11,18 @@ use serde::{Deserialize, Deserializer, Serialize};
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use cuprate_hex::HexVec;
|
/// # use cuprate_hex::HexVec;
|
||||||
/// let hash = [1; 32];
|
/// let hash = [1; 32];
|
||||||
/// let hex_bytes = HexVec(hash);
|
/// let hex_vec = HexVec(hash);
|
||||||
/// let expected_json = r#""0101010101010101010101010101010101010101010101010101010101010101""#;
|
/// 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);
|
/// assert_eq!(to_string, expected_json);
|
||||||
///
|
///
|
||||||
/// let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
|
/// 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 expected_json = r#"["0101010101010101010101010101010101010101010101010101010101010101","0101010101010101010101010101010101010101010101010101010101010101"]"#;
|
||||||
///
|
///
|
||||||
/// let to_string = serde_json::to_string(&vec).unwrap();
|
/// let to_string = serde_json::to_string(&vec).unwrap();
|
||||||
|
@ -47,7 +47,14 @@ impl HexVec {
|
||||||
self.0.is_empty()
|
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 {
|
pub fn empty_if_zeroed<const N: usize>(array: [u8; N]) -> Self {
|
||||||
if array == [0; N] {
|
if array == [0; N] {
|
||||||
Self(Vec::new())
|
Self(Vec::new())
|
||||||
|
@ -112,13 +119,13 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn asdf() {
|
fn asdf() {
|
||||||
let hash = vec![0; 32];
|
let hash = vec![0; 32];
|
||||||
let hex_bytes = HexVec(hash);
|
let hex_vec = HexVec(hash);
|
||||||
let expected_json = r#""0000000000000000000000000000000000000000000000000000000000000000""#;
|
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);
|
assert_eq!(to_string, expected_json);
|
||||||
|
|
||||||
let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
|
let from_str = serde_json::from_str::<HexVec>(expected_json).unwrap();
|
||||||
assert_eq!(hex_bytes, from_str);
|
assert_eq!(hex_vec, from_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue