fix(FLOW-10): Enforce fair FIFO queue ordering on-chain#46
fix(FLOW-10): Enforce fair FIFO queue ordering on-chain#46
Conversation
ebe63d0 to
8ad764e
Compare
9a20c8f to
5717ad2
Compare
74c948d to
371f132
Compare
PR Review: fix(FLOW-10) — Enforce Fair FIFO Queue Ordering On-ChainOverall this is a solid improvement. The mapping-based queue eliminates the costly O(n) array shift for normal processing, and the Bug / Correctness
|
| Severity | Issue | Location |
|---|---|---|
| Style | requestsQueue missing _ prefix |
FlowYieldVaultsRequests.sol:~170 |
| Docs | _requestsQueueTail comment says "last to be processed" but is exclusive upper bound |
FlowYieldVaultsRequests.sol:~176 |
| Docs | _dropQueuedRequest O(n) complexity not documented |
FlowYieldVaultsRequests.sol:~1768 |
| Test | Missing coverage for duplicate IDs in successful+rejected arrays | FlowYieldVaultsRequests.t.sol |
The core logic is correct and the implementation achieves its stated goal. The style and documentation issues are minor; the O(n) complexity of _dropQueuedRequest is worth calling out explicitly so it doesn't surprise future maintainers.
71b9aeb to
9d7d107
Compare
1760973 to
95d1302
Compare
95d1302 to
0da95a3
Compare
Closes #25
FLOW-10: FIFO Queue Is Not Enforced on-Chain yet Costs O(n) to Maintain
Introduce an optimized queue data structure (mapping-based with head & tail pointers), to avoid the high gas costs of maintaining the FIFO order on-chain. Both
enqueue&dequeueoperations are now O(1).The previous queue data structure required an array and a mapping, and had O(n) performance when removing a request from the pending queue:
In additionn
_startProcessingInternalnow has a check which verifies that the request being processed is the head of therequestsQueueFIFO queue:If that is not the case, the function call reverts with
RequestProcessOutOfOrder.The Cadence
Schedulerthat schedules & processes the requests, is fetching the request IDs with:which returns a given count of pending EVM requests from the queue, in FIFO order.
These are fed to
preprocessRequests(), and after the validation checks, they are classified as successful/rejected, and they are then passed in tostartProcessingBatch(), which drops the rejected request IDs, and calls_startProcessingInternal()for each individual successful request ID.