implement mango v4 crank
This commit is contained in:
parent
e22d30b9fd
commit
0a09ad81ae
|
@ -1,6 +1,6 @@
|
|||
use log::*;
|
||||
use solana_client::nonblocking::rpc_client::RpcClient;
|
||||
use solana_sdk::{clock::DEFAULT_MS_PER_SLOT, hash::Hash};
|
||||
use solana_sdk::{clock::DEFAULT_MS_PER_SLOT, commitment_config::CommitmentConfig, hash::Hash};
|
||||
use std::{
|
||||
sync::{Arc, RwLock},
|
||||
time::Duration,
|
||||
|
@ -10,9 +10,10 @@ use tokio::{spawn, time::sleep};
|
|||
const RETRY_INTERVAL: Duration = Duration::from_millis(5 * DEFAULT_MS_PER_SLOT);
|
||||
|
||||
pub async fn poll_loop(blockhash: Arc<RwLock<Hash>>, client: Arc<RpcClient>) {
|
||||
let cfg = CommitmentConfig::processed();
|
||||
loop {
|
||||
let old_blockhash = *blockhash.read().unwrap();
|
||||
if let Ok(new_blockhash) = client.get_latest_blockhash().await {
|
||||
if let Ok((new_blockhash, _)) = client.get_latest_blockhash_with_commitment(cfg).await {
|
||||
if new_blockhash != old_blockhash {
|
||||
debug!("new blockhash ({:?})", blockhash);
|
||||
*blockhash.write().unwrap() = new_blockhash;
|
||||
|
|
|
@ -24,7 +24,7 @@ use std::{
|
|||
net::SocketAddr,
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
sync::{Mutex, atomic::AtomicBool},
|
||||
sync::{atomic::AtomicBool, Mutex},
|
||||
time::Duration,
|
||||
};
|
||||
use tokio::{
|
||||
|
@ -34,14 +34,14 @@ use tokio::{
|
|||
use tokio_tungstenite::tungstenite::{protocol::Message, Error};
|
||||
|
||||
use serde::Deserialize;
|
||||
use solana_geyser_connector_lib::{
|
||||
metrics::{MetricType, MetricU64},
|
||||
FilterConfig, StatusResponse,
|
||||
};
|
||||
use solana_geyser_connector_lib::{
|
||||
fill_event_filter::{self, FillCheckpoint},
|
||||
grpc_plugin_source, metrics, websocket_source, MetricsConfig, SourceConfig,
|
||||
};
|
||||
use solana_geyser_connector_lib::{
|
||||
metrics::{MetricType, MetricU64},
|
||||
FilterConfig, StatusResponse,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(tag = "command")]
|
||||
|
@ -109,10 +109,11 @@ async fn main() -> anyhow::Result<()> {
|
|||
&Keypair::new(),
|
||||
Some(rpc_timeout),
|
||||
);
|
||||
let group_pk = Pubkey::from_str(&config.mango_group).unwrap();
|
||||
let group_context = Arc::new(
|
||||
MangoGroupContext::new_from_rpc(
|
||||
&client.rpc_async(),
|
||||
Pubkey::from_str(&config.mango_group).unwrap(),
|
||||
group_pk
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
|
@ -157,11 +158,14 @@ async fn main() -> anyhow::Result<()> {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let (account_write_queue_sender, slot_queue_sender, instruction_receiver) = transaction_builder::init(
|
||||
perp_queue_pks.clone(),
|
||||
serum_queue_pks.clone(),
|
||||
metrics_tx.clone()
|
||||
).expect("init transaction builder");
|
||||
let (account_write_queue_sender, slot_queue_sender, instruction_receiver) =
|
||||
transaction_builder::init(
|
||||
perp_queue_pks.clone(),
|
||||
serum_queue_pks.clone(),
|
||||
group_pk,
|
||||
metrics_tx.clone(),
|
||||
)
|
||||
.expect("init transaction builder");
|
||||
|
||||
transaction_sender::init(instruction_receiver, blockhash, rpc_client, Keypair::new());
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::Pubkey;
|
||||
use bytemuck::cast_ref;
|
||||
use solana_geyser_connector_lib::{
|
||||
chain_data::{AccountData, ChainData, SlotData},
|
||||
metrics::Metrics,
|
||||
|
@ -10,19 +11,19 @@ use anchor_lang::AccountDeserialize;
|
|||
use log::*;
|
||||
use solana_sdk::{
|
||||
account::{ReadableAccount, WritableAccount},
|
||||
instruction::{Instruction, AccountMeta},
|
||||
stake_history::Epoch,
|
||||
instruction::Instruction,
|
||||
};
|
||||
use std::{
|
||||
borrow::BorrowMut,
|
||||
collections::{HashMap, HashSet},
|
||||
collections::{HashMap, HashSet}, iter::{once, empty},
|
||||
convert::TryFrom
|
||||
};
|
||||
|
||||
pub enum EventQueueFilterMessage {}
|
||||
|
||||
|
||||
pub fn init(
|
||||
perp_queue_pks: Vec<(Pubkey, Pubkey)>,
|
||||
serum_queue_pks: Vec<(Pubkey, Pubkey)>,
|
||||
group_pk: Pubkey,
|
||||
metrics_sender: Metrics,
|
||||
) -> anyhow::Result<(
|
||||
async_channel::Sender<AccountWrite>,
|
||||
|
@ -94,13 +95,14 @@ pub fn init(
|
|||
|
||||
for mkt in all_queue_pks.iter() {
|
||||
let last_evq_version = last_evq_versions.get(&mkt.1.to_string()).unwrap_or(&(0, 0));
|
||||
let mkt_pk = mkt.1;
|
||||
let mkt_pk = mkt.0;
|
||||
let evq_pk = mkt.1;
|
||||
|
||||
match chain_cache.account(&mkt_pk) {
|
||||
match chain_cache.account(&evq_pk) {
|
||||
Ok(account_info) => {
|
||||
// only process if the account state changed
|
||||
let evq_version = (account_info.slot, account_info.write_version);
|
||||
let evq_pk_string = mkt.1.to_string();
|
||||
let evq_pk_string = evq_pk.to_string();
|
||||
trace!("evq {} write_version {:?}", evq_pk_string, evq_version);
|
||||
if evq_version == *last_evq_version {
|
||||
continue;
|
||||
|
@ -110,7 +112,7 @@ pub fn init(
|
|||
let account = &account_info.account;
|
||||
let is_perp = mango_v4::check_id(account.owner());
|
||||
if is_perp {
|
||||
let event_queue = mango_v4::state::EventQueue::try_deserialize(
|
||||
let event_queue: mango_v4::state::EventQueue = mango_v4::state::EventQueue::try_deserialize(
|
||||
account.data().borrow_mut(),
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -119,6 +121,48 @@ pub fn init(
|
|||
evq_pk_string,
|
||||
event_queue.header.seq_num
|
||||
);
|
||||
|
||||
if !event_queue.empty() {
|
||||
let mango_accounts: HashSet<_> = event_queue.iter().take(10).flat_map(|e| match mango_v4::state::EventType::try_from(e.event_type).expect("mango v4 event") {
|
||||
mango_v4::state::EventType::Fill => {
|
||||
let fill: &mango_v4::state::FillEvent = cast_ref(e);
|
||||
vec![fill.maker, fill.taker]
|
||||
}
|
||||
mango_v4::state::EventType::Out => {
|
||||
let out: &mango_v4::state::OutEvent = cast_ref(e);
|
||||
vec![out.owner]
|
||||
}
|
||||
mango_v4::state::EventType::Liquidate => vec![]
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut ams: Vec<_> = anchor_lang::ToAccountMetas::to_account_metas(
|
||||
&mango_v4::accounts::PerpConsumeEvents {
|
||||
group: group_pk,
|
||||
perp_market: mkt_pk,
|
||||
event_queue: evq_pk,
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
||||
ams.append(&mut mango_accounts
|
||||
.iter()
|
||||
.map(|pk| AccountMeta { pubkey: *pk, is_signer: false, is_writable: true })
|
||||
.collect());
|
||||
|
||||
let ix = Instruction {
|
||||
program_id: mango_v4::id(),
|
||||
accounts: ams,
|
||||
data: anchor_lang::InstructionData::data(&mango_v4::instruction::PerpConsumeEvents {
|
||||
limit: 10,
|
||||
}),
|
||||
};
|
||||
|
||||
instruction_sender.send(vec![ix]).await;
|
||||
}
|
||||
|
||||
|
||||
|
||||
match seq_num_cache.get(&evq_pk_string) {
|
||||
Some(old_seq_num) => match perp_events_cache.get(&evq_pk_string) {
|
||||
Some(old_events) => {}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::sync::{Arc, RwLock};
|
||||
use solana_client::{nonblocking::rpc_client::RpcClient, rpc_config::RpcSendTransactionConfig};
|
||||
use solana_sdk::{
|
||||
hash::Hash, instruction::Instruction, signature::Keypair, signature::Signer,
|
||||
transaction::Transaction,
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use tokio::spawn;
|
||||
|
||||
pub async fn send_loop(
|
||||
|
|
Loading…
Reference in New Issue