-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: simulator #209
base: main
Are you sure you want to change the base?
feat: simulator #209
Conversation
|
||
tx = VersionedTransaction.from_bytes(base64.b64decode(data["params"][0])) | ||
sig = tx.signatures[0] | ||
resposne = {"jsonrpc": "2.0", "result": str(sig), "id": data["id"]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo :D
svm.set_account(*key, account.clone()).unwrap(); | ||
} | ||
for (key, account) in self.programs.iter() { | ||
svm.add_program( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does this work with program upgrades? why not just set account data for the program and its executable as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tried that first, litesvm didn't support it very well. But we can create a PR for that in litesvm package
pub async fn fetch_pending_and_remove_old_txs(&self) -> Vec<VersionedTransaction> { | ||
let now = Instant::now(); | ||
let mut pending_txs = self.pending_txs.write().await; | ||
pending_txs.retain(|(_, time)| now.duration_since(*time).as_secs() < 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the 5 seconds here a proxy for whether the state change has been processed on-chain? why not just check the commitment statuses of the transactions? that may be easier and more robust via getSignatureStatuses
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, once we have a definite status we can remove it from this array. This will probably be handled by a separate thread that's either polling or subscribing
) -> solana_client::client_error::Result<Signature> { | ||
let now = Instant::now(); | ||
self.pending_txs.write().await.push((tx.clone(), now)); | ||
self.sender |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not simulate the tx here optimistically? you're anyways going to simulate it later, so why not do so here and poll regularly until the tx either hits processed
or doesn't show up on-chain after some buffer time (in which case you revert to the RPC's view of state)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't understand what you mean. We simulate it just before calling this function, why should we simulate it again?
context: accounts_config_with_context.context, | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one way i was thinking of structuring this is the following:
- you have an rpc client that informs your view of state of all accounts except for a list of accounts which txs that you have submitted have altered (i.e. writable accounts in txs submitted by searchers)
- for each of those writable accounts, you pull the state of the account when you submit the tx and log that as well as the state of the account post simulating your tx
- you regularly poll the state of the accounts in your list as well as listen for commitment updates on the transactions you submitted. as soon as you observe either a change in the RPC's view of an account state or get a commitment update on a transaction, you drop your simulated view of the account from your list
- when simulating transactions, you check if any of the transaction's accounts are in your list. if so, you don't fetch those accounts' data and instead use your stored accounts; you fetch all other accounts.
- this allows an easy fallback where if the original transaction you submitted fails or doesn't reach
processed
within enough time, then you revert to on-chain state. but for a short period of time after you submit, you will definitely retain a future view of state so you can simulate new txs more intelligently
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
of course, the key is in how you poll and balance btwn keeping ahead of future tx inclusion and fallback behavior in case a transaction doesn't reach processed
or fails on-chain. if another tx changes the state of an account that your submitted tx touches before it is processed
you should probably pessimistically drop your simulated forward state bc your tx may not succeed any longer. practically speaking, for limo orders, this shouldn't happen too often, but it's worth thinking about the tradeoffs here in case of other accounts that users may interact with outside of this context
No description provided.