---
# System prepended metadata

title: Untitled

---

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`
