Skip to content

Commit

Permalink
Add enable_dc_burn setting to mobile packet verifier (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Plant authored Mar 31, 2023
1 parent 0b124c4 commit 1d12f86
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 89 deletions.
192 changes: 103 additions & 89 deletions mobile_packet_verifier/src/burner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct Burner {
program_cache: BurnProgramCache,
keypair: [u8; 64],
cluster: String,
enable_dc_burn: bool,
}

#[derive(thiserror::Error, Debug)]
Expand Down Expand Up @@ -92,6 +93,7 @@ impl Burner {
valid_sessions,
keypair: keypair.to_bytes(),
cluster: settings.cluster.clone(),
enable_dc_burn: settings.enable_dc_burn,
})
}

Expand Down Expand Up @@ -119,99 +121,12 @@ impl Burner {
},
) in payer_totals.into_iter()
{
// Fetch the sub dao epoch info:
const EPOCH_LENGTH: u64 = 60 * 60 * 24;
let epoch = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs()
/ EPOCH_LENGTH;
let (sub_dao_epoch_info, _) = Pubkey::find_program_address(
&[
"sub_dao_epoch_info".as_bytes(),
self.program_cache.sub_dao.as_ref(),
&epoch.to_le_bytes(),
],
&helium_sub_daos::ID,
);

let amount = bytes_to_dc(total_bytes);

// Burn the DC for the payer
let ddc_key = crate::pdas::delegated_data_credits(&self.program_cache.sub_dao, &payer);
let account_data = self.provider.get_account_data(&ddc_key).await?;
let mut account_data = account_data.as_ref();
let escrow_account =
DelegatedDataCreditsV0::try_deserialize(&mut account_data)?.escrow_account;

tracing::info!("Burning {} DC from {}", amount, payer);

let instructions = {
let request = RequestBuilder::from(
data_credits::id(),
&self.cluster,
std::rc::Rc::new(Keypair::from_bytes(&self.keypair).unwrap()),
Some(CommitmentConfig::confirmed()),
RequestNamespace::Global,
);

let accounts = accounts::BurnDelegatedDataCreditsV0 {
sub_dao_epoch_info,
dao: self.program_cache.dao,
sub_dao: self.program_cache.sub_dao,
account_payer: self.program_cache.account_payer,
data_credits: self.program_cache.data_credits,
delegated_data_credits: ddc_key,
token_program: spl_token::id(),
helium_sub_daos_program: helium_sub_daos::id(),
system_program: solana_program::system_program::id(),
dc_burn_authority: self.program_cache.dc_burn_authority,
dc_mint: self.program_cache.dc_mint,
escrow_account,
registrar: self.program_cache.registrar,
};
let args = instruction::BurnDelegatedDataCreditsV0 {
args: data_credits::BurnDelegatedDataCreditsArgsV0 { amount },
};

// As far as I can tell, the instructions function does not actually have any
// error paths.
request
.accounts(accounts)
.args(args)
.instructions()
.unwrap()
};

let blockhash = self.provider.get_latest_blockhash().await?;
let signer = Keypair::from_bytes(&self.keypair).unwrap();

let tx = SolanaTransaction::new_signed_with_payer(
&instructions,
Some(&signer.pubkey()),
&[&signer],
blockhash,
);

// Preflight can be flakey, so we skip it for now
let config = RpcSendTransactionConfig {
skip_preflight: true,
..Default::default()
};
let signature = self
.provider
.send_transaction_with_config(&tx, config)
.await?;
let result = self.provider.confirm_transaction(&signature).await?;

if !result {
return Err(BurnError::TransactionFailed(signature));
if self.enable_dc_burn {
self.burn_data_credits(&payer, amount).await?;
}

tracing::info!(
"Successfully burned data credits. Transaction: {}",
signature
);

// Delete from the data transfer session and write out to S3

sqlx::query("DELETE FROM data_tranfer_sessions WHERE payer = $1")
Expand Down Expand Up @@ -239,6 +154,105 @@ impl Burner {

Ok(())
}

async fn burn_data_credits(
&self,
payer: &PublicKeyBinary,
amount: u64,
) -> Result<(), BurnError> {
tracing::info!("Burning {} DC from {}", amount, payer);

// Fetch the sub dao epoch info:
const EPOCH_LENGTH: u64 = 60 * 60 * 24;
let epoch = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs()
/ EPOCH_LENGTH;
let (sub_dao_epoch_info, _) = Pubkey::find_program_address(
&[
"sub_dao_epoch_info".as_bytes(),
self.program_cache.sub_dao.as_ref(),
&epoch.to_le_bytes(),
],
&helium_sub_daos::ID,
);

// Burn the DC for the payer
let ddc_key = crate::pdas::delegated_data_credits(&self.program_cache.sub_dao, payer);
let account_data = self.provider.get_account_data(&ddc_key).await?;
let mut account_data = account_data.as_ref();
let escrow_account =
DelegatedDataCreditsV0::try_deserialize(&mut account_data)?.escrow_account;

let instructions = {
let request = RequestBuilder::from(
data_credits::id(),
&self.cluster,
std::rc::Rc::new(Keypair::from_bytes(&self.keypair).unwrap()),
Some(CommitmentConfig::confirmed()),
RequestNamespace::Global,
);

let accounts = accounts::BurnDelegatedDataCreditsV0 {
sub_dao_epoch_info,
dao: self.program_cache.dao,
sub_dao: self.program_cache.sub_dao,
account_payer: self.program_cache.account_payer,
data_credits: self.program_cache.data_credits,
delegated_data_credits: ddc_key,
token_program: spl_token::id(),
helium_sub_daos_program: helium_sub_daos::id(),
system_program: solana_program::system_program::id(),
dc_burn_authority: self.program_cache.dc_burn_authority,
dc_mint: self.program_cache.dc_mint,
escrow_account,
registrar: self.program_cache.registrar,
};
let args = instruction::BurnDelegatedDataCreditsV0 {
args: data_credits::BurnDelegatedDataCreditsArgsV0 { amount },
};

// As far as I can tell, the instructions function does not actually have any
// error paths.
request
.accounts(accounts)
.args(args)
.instructions()
.unwrap()
};

let blockhash = self.provider.get_latest_blockhash().await?;
let signer = Keypair::from_bytes(&self.keypair).unwrap();

let tx = SolanaTransaction::new_signed_with_payer(
&instructions,
Some(&signer.pubkey()),
&[&signer],
blockhash,
);

// Preflight can be flakey, so we skip it for now
let config = RpcSendTransactionConfig {
skip_preflight: true,
..Default::default()
};
let signature = self
.provider
.send_transaction_with_config(&tx, config)
.await?;
let result = self.provider.confirm_transaction(&signature).await?;

if !result {
return Err(BurnError::TransactionFailed(signature));
}

tracing::info!(
"Successfully burned data credits. Transaction: {}",
signature
);

Ok(())
}
}

const BYTES_PER_DC: u64 = 20_000;
Expand Down
2 changes: 2 additions & 0 deletions mobile_packet_verifier/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct Settings {
pub ingest: file_store::Settings,
pub output: file_store::Settings,
pub metrics: poc_metrics::Settings,
#[serde(default)]
pub enable_dc_burn: bool,
}

pub fn default_url() -> http::Uri {
Expand Down

0 comments on commit 1d12f86

Please sign in to comment.