I have found a case where Query Server traffic can cause Node failure. The query server uses a Object which has a ARC RWLock reference to the current nodes chainstate and a cloned copy. ``` /// data container for API pub struct QueryServer { pub(crate) ledger: Arc<RwLock<LedgerState>>, pub(crate) ledger_cloned: LedgerState, } ``` After every end of block a clone of the current chainstate is taken from a proper read lock. ``` /// update after a new block is created #[inline(always)] pub fn update(&mut self) { if let Some(l) = self.ledger.try_read() { self.ledger_cloned = l.clone(); } } ``` But the underlying data structure has a LedgerStatus object which has a bunch of Mapx, Vecx, Mapxnk, etc. Cloning these creates references pointing to the same disk based file, written and read by potentially multiple threads. One example I found of concern was `get_claim_txns` API in the Query Server which calls the `get_transaction_light` on the `ledger_cloned` field. ``` /// Query the transaction by a TxnSID without its proof data to reduce latency pub fn get_transaction_light(&self, id: TxnSID) -> Result<FinalizedTransaction> { self.tx_to_block_location .get(&id) .c(d!()) .and_then(|[block_idx, tx_idx]| { self.blocks .get(block_idx) .c(d!()) .and_then(|b| b.txns.get(tx_idx).cloned().c(d!())) }) } ``` `get_transaction_light` as you can see calls `tx_to_block_location` and `blocks` field of the cloned `LedgerState` which are of the type `Mapxnk` and `Vecx` respectively. Also there are other API routes accessing the X fields `utxos`, `owned_utxos`, `issuance_num`