From 5b2075b2ec631d8126571add525a836a6dc6d932 Mon Sep 17 00:00:00 2001 From: junderw Date: Sun, 4 Feb 2024 21:50:43 +0900 Subject: [PATCH] Fix: Output index should be u32 to prevent clobbering when over 65536 outputs. --- src/elements/asset.rs | 22 +++++++++--------- src/elements/peg.rs | 4 ++-- src/new_index/mempool.rs | 8 +++---- src/new_index/schema.rs | 50 ++++++++++++++++++++-------------------- src/util/transaction.rs | 2 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/elements/asset.rs b/src/elements/asset.rs index b6cd704f3..5b6a6bd70 100644 --- a/src/elements/asset.rs +++ b/src/elements/asset.rs @@ -71,9 +71,9 @@ pub struct IssuedAsset { #[derive(Serialize, Deserialize, Debug)] pub struct AssetRow { pub issuance_txid: FullHash, - pub issuance_vin: u16, + pub issuance_vin: u32, pub prev_txid: FullHash, - pub prev_vout: u16, + pub prev_vout: u32, pub issuance: Bytes, // bincode does not like dealing with AssetIssuance, deserialization fails with "invalid type: sequence, expected a struct" pub reissuance_token: FullHash, } @@ -105,7 +105,7 @@ impl IssuedAsset { }, issuance_prevout: OutPoint { txid: deserialize(&asset.prev_txid).unwrap(), - vout: asset.prev_vout as u32, + vout: asset.prev_vout, }, contract_hash, reissuance_token, @@ -155,7 +155,7 @@ impl LiquidAsset { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct IssuingInfo { pub txid: FullHash, - pub vin: u16, + pub vin: u32, pub is_reissuance: bool, // None for blinded issuances pub issued_amount: Option, @@ -166,7 +166,7 @@ pub struct IssuingInfo { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct BurningInfo { pub txid: FullHash, - pub vout: u16, + pub vout: u32, pub value: u64, } @@ -251,7 +251,7 @@ fn index_tx_assets( pegout.asset.explicit().unwrap(), TxHistoryInfo::Pegout(PegoutInfo { txid, - vout: txo_index as u16, + vout: txo_index as u32, value: pegout.value, }), )); @@ -262,7 +262,7 @@ fn index_tx_assets( asset_id, TxHistoryInfo::Burning(BurningInfo { txid, - vout: txo_index as u16, + vout: txo_index as u32, value, }), )); @@ -277,7 +277,7 @@ fn index_tx_assets( pegin.asset.explicit().unwrap(), TxHistoryInfo::Pegin(PeginInfo { txid, - vin: txi_index as u16, + vin: txi_index as u32, value: pegin.value, }), )); @@ -302,7 +302,7 @@ fn index_tx_assets( asset_id, TxHistoryInfo::Issuing(IssuingInfo { txid, - vin: txi_index as u16, + vin: txi_index as u32, is_reissuance, issued_amount, token_amount, @@ -319,9 +319,9 @@ fn index_tx_assets( asset_id, AssetRow { issuance_txid: txid, - issuance_vin: txi_index as u16, + issuance_vin: txi_index as u32, prev_txid: full_hash(&txi.previous_output.txid[..]), - prev_vout: txi.previous_output.vout as u16, + prev_vout: txi.previous_output.vout, issuance: serialize(&txi.asset_issuance), reissuance_token: full_hash(&reissuance_token.into_inner()[..]), }, diff --git a/src/elements/peg.rs b/src/elements/peg.rs index cd339e60d..316c5dbaf 100644 --- a/src/elements/peg.rs +++ b/src/elements/peg.rs @@ -55,7 +55,7 @@ impl PegoutValue { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct PeginInfo { pub txid: FullHash, - pub vin: u16, + pub vin: u32, pub value: u64, } @@ -64,6 +64,6 @@ pub struct PeginInfo { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct PegoutInfo { pub txid: FullHash, - pub vout: u16, + pub vout: u32, pub value: u64, } diff --git a/src/new_index/mempool.rs b/src/new_index/mempool.rs index ccd50fe18..139612d4f 100644 --- a/src/new_index/mempool.rs +++ b/src/new_index/mempool.rs @@ -210,7 +210,7 @@ impl Mempool { Some(Utxo { txid: deserialize(&info.txid).expect("invalid txid"), - vout: info.vout as u32, + vout: info.vout, value: info.value, confirmed: None, @@ -452,9 +452,9 @@ impl Mempool { compute_script_hash(&prevout.script_pubkey), TxHistoryInfo::Spending(SpendingInfo { txid: txid_bytes, - vin: input_index as u16, + vin: input_index, prev_txid: full_hash(&txi.previous_output.txid[..]), - prev_vout: txi.previous_output.vout as u16, + prev_vout: txi.previous_output.vout, value: prevout.value, }), ) @@ -473,7 +473,7 @@ impl Mempool { compute_script_hash(&txo.script_pubkey), TxHistoryInfo::Funding(FundingInfo { txid: txid_bytes, - vout: index as u16, + vout: index as u32, value: txo.value, }), ) diff --git a/src/new_index/schema.rs b/src/new_index/schema.rs index 7efc90994..a52a7671f 100644 --- a/src/new_index/schema.rs +++ b/src/new_index/schema.rs @@ -936,7 +936,7 @@ impl ChainQuery { let txid: Txid = deserialize(&edge.key.spending_txid).unwrap(); self.tx_confirming_block(&txid).map(|b| SpendingInput { txid, - vin: edge.key.spending_vin as u32, + vin: edge.key.spending_vin, confirmed: Some(b), }) }) @@ -1164,7 +1164,7 @@ fn index_transaction( confirmed_height, TxHistoryInfo::Funding(FundingInfo { txid, - vout: txo_index as u16, + vout: txo_index as u32, value: txo.value, }), ); @@ -1190,9 +1190,9 @@ fn index_transaction( confirmed_height, TxHistoryInfo::Spending(SpendingInfo { txid, - vin: txi_index as u16, + vin: txi_index as u32, prev_txid: full_hash(&txi.previous_output.txid[..]), - prev_vout: txi.previous_output.vout as u16, + prev_vout: txi.previous_output.vout, value: prev_txo.value, }), ); @@ -1200,9 +1200,9 @@ fn index_transaction( let edge = TxEdgeRow::new( full_hash(&txi.previous_output.txid[..]), - txi.previous_output.vout as u16, + txi.previous_output.vout, txid, - txi_index as u16, + txi_index as u32, ); rows.push(edge.into_row()); } @@ -1322,7 +1322,7 @@ impl TxConfRow { struct TxOutKey { code: u8, txid: FullHash, - vout: u16, + vout: u32, } struct TxOutRow { @@ -1336,7 +1336,7 @@ impl TxOutRow { key: TxOutKey { code: b'O', txid: *txid, - vout: vout as u16, + vout: vout as u32, }, value: serialize(txout), } @@ -1345,7 +1345,7 @@ impl TxOutRow { bincode_util::serialize_little(&TxOutKey { code: b'O', txid: full_hash(&outpoint.txid[..]), - vout: outpoint.vout as u16, + vout: outpoint.vout, }) .unwrap() } @@ -1436,7 +1436,7 @@ impl BlockRow { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct FundingInfo { pub txid: FullHash, - pub vout: u16, + pub vout: u32, pub value: Value, } @@ -1444,9 +1444,9 @@ pub struct FundingInfo { #[cfg_attr(test, derive(PartialEq, Eq))] pub struct SpendingInfo { pub txid: FullHash, // spending transaction - pub vin: u16, + pub vin: u32, pub prev_txid: FullHash, // funding transaction - pub prev_vout: u16, + pub prev_vout: u32, pub value: Value, } @@ -1546,11 +1546,11 @@ impl TxHistoryInfo { match self { TxHistoryInfo::Funding(ref info) => OutPoint { txid: deserialize(&info.txid).unwrap(), - vout: info.vout as u32, + vout: info.vout, }, TxHistoryInfo::Spending(ref info) => OutPoint { txid: deserialize(&info.prev_txid).unwrap(), - vout: info.prev_vout as u32, + vout: info.prev_vout, }, #[cfg(feature = "liquid")] TxHistoryInfo::Issuing(_) @@ -1565,9 +1565,9 @@ impl TxHistoryInfo { struct TxEdgeKey { code: u8, funding_txid: FullHash, - funding_vout: u16, + funding_vout: u32, spending_txid: FullHash, - spending_vin: u16, + spending_vin: u32, } struct TxEdgeRow { @@ -1577,9 +1577,9 @@ struct TxEdgeRow { impl TxEdgeRow { fn new( funding_txid: FullHash, - funding_vout: u16, + funding_vout: u32, spending_txid: FullHash, - spending_vin: u16, + spending_vin: u32, ) -> Self { let key = TxEdgeKey { code: b'S', @@ -1593,7 +1593,7 @@ impl TxEdgeRow { fn filter(outpoint: &OutPoint) -> Bytes { // TODO build key without using bincode? [ b"S", &outpoint.txid[..], outpoint.vout?? ].concat() - bincode_util::serialize_little(&(b'S', full_hash(&outpoint.txid[..]), outpoint.vout as u16)) + bincode_util::serialize_little(&(b'S', full_hash(&outpoint.txid[..]), outpoint.vout)) .unwrap() } @@ -1730,7 +1730,7 @@ mod tests { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // vout - 0, 3, + 0, 0, 0, 3, // Value variant (Explicit) 0, 0, 0, 0, 0, 0, 0, 2, // number of tuple elements @@ -1746,7 +1746,7 @@ mod tests { 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 3, + 0, 0, 0, 3, // Value variant (Null) 0, 0, 0, 0, 0, 0, 0, 1, // number of tuple elements @@ -1760,10 +1760,10 @@ mod tests { 0, 0, 0, 1, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 0, 12, + 0, 0, 0, 12, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, - 0, 9, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 2, 1, 14, 0, 0, 0, 0, 0, 0, 0, @@ -1776,10 +1776,10 @@ mod tests { 0, 0, 0, 1, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 0, 12, + 0, 0, 0, 12, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, 98, 101, 101, 102, - 0, 9, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 1, 0, ], diff --git a/src/util/transaction.rs b/src/util/transaction.rs index c9ff29ae6..be801c738 100644 --- a/src/util/transaction.rs +++ b/src/util/transaction.rs @@ -48,7 +48,7 @@ impl From> for TransactionStatus { #[derive(Serialize, Deserialize)] pub struct TxInput { pub txid: Txid, - pub vin: u16, + pub vin: u32, } pub fn is_coinbase(txin: &TxIn) -> bool {