Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions auction-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ version = "0.10.0"
edition = "2021"
license-file = "license.txt"

[build-dependencies]
anchor-lang-idl = { version = "0.1.1", features = ["convert"] }

[dependencies]
tokio = { version = "1.28", features = ["macros", "sync", "rt-multi-thread", "signal"] }
tokio-stream = "0.1.14"
Expand Down
44 changes: 43 additions & 1 deletion auction-server/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,44 @@
use std::process::Command;
use {
anchor_lang_idl::{
convert::convert_idl,
types::IdlInstructionAccountItem,
},
std::{
fs,
process::Command,
},
};

const SUBMIT_BID_INSTRUCTION_SVM: &str = "submit_bid";
const PERMISSION_ACCOUNT_SVM: &str = "permission";

fn verify_idl() {
let idl_json = fs::read("../contracts/svm/target/idl/express_relay.json")
.expect("Failed to read IDL JSON");
let express_relay_idl =
convert_idl(idl_json.as_slice()).expect("Failed to convert IDL to Rust");
match express_relay_idl
.instructions
.iter()
.find(|i| i.name == SUBMIT_BID_INSTRUCTION_SVM)
{
Some(instruction) => {
if !instruction.accounts.iter().any(|a| match a {
IdlInstructionAccountItem::Single(a) => a.name == PERMISSION_ACCOUNT_SVM,
IdlInstructionAccountItem::Composite(a) => a.name == PERMISSION_ACCOUNT_SVM,
}) {
panic!(
"{} account not found in {} instruction",
PERMISSION_ACCOUNT_SVM, SUBMIT_BID_INSTRUCTION_SVM
);
}
}
None => panic!(
"{} instruction not found in IDL",
SUBMIT_BID_INSTRUCTION_SVM
),
}
}

fn main() {
let contract_setup = r#"
Expand All @@ -24,4 +64,6 @@ fn main() {
String::from_utf8_lossy(&output.stdout)
);
}

verify_idl();
}
76 changes: 64 additions & 12 deletions auction-server/src/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,17 @@ use {
},
traced_client::TracedClient,
},
::express_relay as express_relay_svm,
anchor_lang::Discriminator,
::express_relay::{
self as express_relay_svm,
},
anchor_lang::{
AnchorDeserialize,
Discriminator,
},
anchor_lang_idl::types::{
Idl,
IdlInstructionAccountItem,
},
anyhow::{
anyhow,
Result,
Expand Down Expand Up @@ -82,7 +91,11 @@ use {
Deserializer,
Serialize,
},
solana_sdk::transaction::VersionedTransaction,
solana_sdk::{
instruction::CompiledInstruction,
pubkey::Pubkey,
transaction::VersionedTransaction,
},
sqlx::types::time::OffsetDateTime,
std::{
result,
Expand Down Expand Up @@ -880,8 +893,8 @@ pub async fn run_tracker_loop(store: Arc<Store>, chain_id: String) -> Result<()>
pub fn verify_submit_bid_instruction_svm(
chain_store: &ChainStoreSvm,
transaction: VersionedTransaction,
) -> Result<(), RestError> {
if transaction
) -> Result<CompiledInstruction, RestError> {
let submit_bid_instructions: Vec<CompiledInstruction> = transaction
.message
.instructions()
.iter()
Expand All @@ -895,15 +908,48 @@ pub fn verify_submit_bid_instruction_svm(
.data
.starts_with(&express_relay_svm::instruction::SubmitBid::discriminator())
})
.count()
!= 1
{
return Err(RestError::BadParameters(
.cloned()
.collect();

match submit_bid_instructions.len() {
1 => Ok(submit_bid_instructions[0].clone()),
_ => Err(RestError::BadParameters(
"Bid has to include exactly one submit_bid instruction to Express Relay program"
.to_string(),
));
)),
}
Ok(())
}

fn find_account_position_svm(idl: Idl, instruction: &str, account: &str) -> Option<usize> {
let instruction = idl.instructions.iter().find(|i| i.name == instruction)?;
instruction.accounts.iter().position(|a| match a {
IdlInstructionAccountItem::Single(a) => a.name == account,
IdlInstructionAccountItem::Composite(a) => a.name == account,
})
}

const SUBMIT_BID_INSTRUCTION_SVM: &str = "submit_bid";
const PERMISSION_ACCOUNT_SVM: &str = "permission";

fn extract_bid_data_svm(
idl: Idl,
accounts: &[Pubkey],
instruction: CompiledInstruction,
) -> Result<(u64, Pubkey), RestError> {
let discriminator = express_relay_svm::instruction::SubmitBid::discriminator();
let submit_bid_data = express_relay_svm::SubmitBidArgs::try_from_slice(
&instruction.data.as_slice()[discriminator.len()..],
)
.map_err(|e| RestError::BadParameters(format!("Invalid submit_bid instruction data: {}", e)))?;
let permission_account_position =
find_account_position_svm(idl, SUBMIT_BID_INSTRUCTION_SVM, PERMISSION_ACCOUNT_SVM).ok_or(
RestError::BadParameters("Invalid submit_bid instruction accounts".to_string()),
)?;
let account_position = instruction.accounts[permission_account_position];
Ok((
submit_bid_data.bid_amount,
accounts[account_position as usize],
))
}

#[tracing::instrument(skip_all)]
Expand All @@ -918,7 +964,13 @@ pub async fn handle_bid_svm(
.get(&bid.chain_id)
.ok_or(RestError::InvalidChainId)?;

verify_submit_bid_instruction_svm(chain_store, bid.transaction.clone())?;
let submit_bid_instruction =
verify_submit_bid_instruction_svm(chain_store, bid.transaction.clone())?;
let (_bid_amount, _permission) = extract_bid_data_svm(
store.express_relay_idl.clone(),
bid.transaction.message.static_account_keys(),
submit_bid_instruction,
)?;

// TODO implement this
Err(RestError::NotImplemented)
Expand Down
Loading