Hello,
I want to ask some questions and touch base a bit about what the cranking process is and what are the best practices by which it should be done.
What I know from examining the code:
- Cranking is done through the
consume_events instruction
- Each invocation of the
consume_events instruction needs to know how many items in the queue it should read and process (through the max_iterations parameters)
- Each invocation of the
consume_events instruction needs to provide the DEX program with the open_orders_accounts of all the users that are referenced by the events which are about to be processed. This can be done by loading the event_queue and extracting their open_orders_account from the Event by the following rule: in case it's an EventFill then it's taken from the event_fill.makerCallbackInfo.slice(0, 32); in case it's an EventOut then it's taken from the event_out.callbackInfo.slice(0, 32)
- A
taker doesn't need to have his events consumed because the new_order instruction already takes care of updating the open_orders_account in case there was at least a partial fill for his order
- A
maker has to have his events consumed by a crank in order to get his open_orders_account updated after orders of his have been matched
accumulated_royalties and accumulated_fees belonging to the market are updated by consuming events
What I am not sure about and would like to figure out:
- I thought about ways of embedding the
consume_events instruction in different transactions. For example:
- Transaction(
new_order, consume_events) so that after a taker will get his order matched, he will also consume the events that would update the open_orders_account of the maker, making the latter able to settle his funds.
- Transaction(
consume_events, settle) so that before a maker tries to settle his funds, he makes sure he consumed the events that will update his open_orders_account in order to actually have something to settle
However, I don't think these solutions are good. For example:
- For the first bullet above,: it seems that the events pushed to the queue in the case of a match are not "seen" in the
consume_events instruction that belongs to the same transaction. But if I create a second transaction with just the consume_events instruction and execute it after the new_order this will work
- For the second bullet above: this is too sketchy because there could be multiple events waiting in the queue that don't belong to the maker trying to get his
open_orders_account updated. Given the fact that he needs to specify a max_iterations, he could consume the next X events that belong to other users and were not consumed yet, so he would end up cranking the market for others and not consume enough events to reach his own events.
All in all, I think trying to embed the consume_events instruction in users' trading transaction is a dead-end. This leads to the point 2) below.
- There is a
cranker folder in the repo. The code looks like something that needs to be run in a background job by the market admin at a particular frequency. The frequency can be set according to the liquidity in the market I guess.
Here are the questions:
- Is the background job the way to go regarding
cranking/consuming events of a market?
- If it is, any suggestions about the number of iterations it should consume at each run? Is there a limit for how many events can be consumed?
Hello,
I want to ask some questions and touch base a bit about what the cranking process is and what are the best practices by which it should be done.
What I know from examining the code:
consume_eventsinstructionconsume_eventsinstruction needs to know how many items in the queue it should read and process (through themax_iterationsparameters)consume_eventsinstruction needs to provide the DEX program with theopen_orders_accountsof all the users that are referenced by the events which are about to be processed. This can be done by loading theevent_queueand extracting theiropen_orders_accountfrom theEventby the following rule: in case it's anEventFillthen it's taken from theevent_fill.makerCallbackInfo.slice(0, 32); in case it's anEventOutthen it's taken from theevent_out.callbackInfo.slice(0, 32)takerdoesn't need to have his events consumed because thenew_orderinstruction already takes care of updating theopen_orders_accountin case there was at least a partial fill for his ordermakerhas to have his events consumed by a crank in order to get hisopen_orders_accountupdated after orders of his have been matchedaccumulated_royaltiesandaccumulated_feesbelonging to the market are updated byconsuming eventsWhat I am not sure about and would like to figure out:
consume_eventsinstruction in different transactions. For example:new_order,consume_events) so that after a taker will get his order matched, he will also consume the events that would update theopen_orders_accountof the maker, making the latter able to settle his funds.consume_events,settle) so that before a maker tries to settle his funds, he makes sure he consumed the events that will update hisopen_orders_accountin order to actually have something to settleHowever, I don't think these solutions are good. For example:
consume_eventsinstruction that belongs to the same transaction. But if I create a second transaction with just theconsume_eventsinstruction and execute it after thenew_orderthis will workopen_orders_accountupdated. Given the fact that he needs to specify amax_iterations, he could consume the next X events that belong to other users and were not consumed yet, so he would end up cranking the market for others and not consume enough events to reach his own events.All in all, I think trying to embed the
consume_eventsinstruction in users' trading transaction is a dead-end. This leads to the point 2) below.crankerfolder in the repo. The code looks like something that needs to be run in a background job by the market admin at a particular frequency. The frequency can be set according to the liquidity in the market I guess.Here are the questions:
cranking/consuming eventsof a market?