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`