From 429802a138a515aadad32a4fc80dc39f02df1005 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Wed, 20 May 2020 21:26:47 -0700 Subject: [PATCH] Avoid sending duplicate stake delegation transactions for the same epoch (#10158) automerge --- stake-o-matic/src/main.rs | 78 +++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/stake-o-matic/src/main.rs b/stake-o-matic/src/main.rs index b53b0f8a61..494d5a201e 100644 --- a/stake-o-matic/src/main.rs +++ b/stake-o-matic/src/main.rs @@ -542,6 +542,7 @@ fn process_confirmations( ok } +#[allow(clippy::cognitive_complexity)] // Yeah I know... fn main() -> Result<(), Box> { solana_logger::setup_with_default("solana=info"); let config = get_config(); @@ -578,6 +579,7 @@ fn main() -> Result<(), Box> { let mut source_stake_lamports_required = 0; let mut create_stake_transactions = vec![]; let mut delegate_stake_transactions = vec![]; + let mut stake_activated_in_current_epoch: HashSet = HashSet::new(); for RpcVoteAccountInfo { vote_pubkey, @@ -605,7 +607,8 @@ fn main() -> Result<(), Box> { .unwrap(); // Transactions to create the baseline and bonus stake accounts - if let Ok((balance, _)) = get_stake_account(&rpc_client, &baseline_stake_address) { + if let Ok((balance, stake_state)) = get_stake_account(&rpc_client, &baseline_stake_address) + { if balance != config.baseline_stake_amount { error!( "Unexpected balance in stake account {}: {}, expected {}", @@ -613,6 +616,11 @@ fn main() -> Result<(), Box> { ); process::exit(1); } + if let Some(delegation) = stake_state.delegation() { + if epoch_info.epoch == delegation.activation_epoch { + stake_activated_in_current_epoch.insert(baseline_stake_address); + } + } } else { info!( "Need to create baseline stake account for validator {}", @@ -638,7 +646,7 @@ fn main() -> Result<(), Box> { )); } - if let Ok((balance, _)) = get_stake_account(&rpc_client, &bonus_stake_address) { + if let Ok((balance, stake_state)) = get_stake_account(&rpc_client, &bonus_stake_address) { if balance != config.bonus_stake_amount { error!( "Unexpected balance in stake account {}: {}, expected {}", @@ -646,6 +654,11 @@ fn main() -> Result<(), Box> { ); process::exit(1); } + if let Some(delegation) = stake_state.delegation() { + if epoch_info.epoch == delegation.activation_epoch { + stake_activated_in_current_epoch.insert(bonus_stake_address); + } + } } else { info!( "Need to create bonus stake account for validator {}", @@ -683,41 +696,45 @@ fn main() -> Result<(), Box> { ); // Delegate baseline stake - delegate_stake_transactions.push(( - Transaction::new_unsigned(Message::new_with_payer( - &[stake_instruction::delegate_stake( - &baseline_stake_address, - &config.authorized_staker.pubkey(), - &vote_pubkey, - )], - Some(&config.authorized_staker.pubkey()), - )), - format!( - "🥩 `{}` is current. Added ◎{} baseline stake", - node_pubkey, - lamports_to_sol(config.baseline_stake_amount), - ), - )); - - if quality_block_producers.contains(&node_pubkey) { - // Delegate bonus stake + if !stake_activated_in_current_epoch.contains(&baseline_stake_address) { delegate_stake_transactions.push(( - Transaction::new_unsigned( - Message::new_with_payer( + Transaction::new_unsigned(Message::new_with_payer( &[stake_instruction::delegate_stake( - &bonus_stake_address, + &baseline_stake_address, &config.authorized_staker.pubkey(), &vote_pubkey, )], Some(&config.authorized_staker.pubkey()), )), format!( - "🏅 `{}` was a quality block producer during epoch {}. Added ◎{} bonus stake", + "🥩 `{}` is current. Added ◎{} baseline stake", node_pubkey, - last_epoch, - lamports_to_sol(config.bonus_stake_amount), + lamports_to_sol(config.baseline_stake_amount), ), )); + } + + if quality_block_producers.contains(&node_pubkey) { + // Delegate bonus stake + if !stake_activated_in_current_epoch.contains(&bonus_stake_address) { + delegate_stake_transactions.push(( + Transaction::new_unsigned( + Message::new_with_payer( + &[stake_instruction::delegate_stake( + &bonus_stake_address, + &config.authorized_staker.pubkey(), + &vote_pubkey, + )], + Some(&config.authorized_staker.pubkey()), + )), + format!( + "🏅 `{}` was a quality block producer during epoch {}. Added ◎{} bonus stake", + node_pubkey, + last_epoch, + lamports_to_sol(config.bonus_stake_amount), + ), + )); + } } else { // Deactivate bonus stake delegate_stake_transactions.push(( @@ -837,7 +854,14 @@ fn main() -> Result<(), Box> { &config.authorized_staker, )?; - if !process_confirmations(confirmations, Some(¬ifier)) { + if !process_confirmations( + confirmations, + if config.dry_run { + None + } else { + Some(¬ifier) + }, + ) { process::exit(1); }