Ensure that the spl-token 2 native mint account is owned by the spl-token 2 program.

Workaround for https://github.com/solana-labs/solana-program-library/issues/374 until spl-token 3 is shipped
This commit is contained in:
Michael Vines
2020-08-31 21:51:52 -07:00
committed by mergify[bot]
parent 53a900a28c
commit 7341e60043
4 changed files with 157 additions and 12 deletions

View File

@ -96,7 +96,9 @@ solana_sdk::pubkeys!(
mod tests { mod tests {
use super::*; use super::*;
use solana_sdk::{ use solana_sdk::{
account::Account, epoch_schedule::EpochSchedule, genesis_config::GenesisConfig, account::Account,
epoch_schedule::EpochSchedule,
genesis_config::{GenesisConfig, OperatingMode},
}; };
use solana_stake_program::stake_state::{Authorized, Lockup, Meta, StakeState}; use solana_stake_program::stake_state::{Authorized, Lockup, Meta, StakeState};
use std::{collections::BTreeMap, sync::Arc}; use std::{collections::BTreeMap, sync::Arc};
@ -147,6 +149,7 @@ mod tests {
let genesis_config = GenesisConfig { let genesis_config = GenesisConfig {
accounts, accounts,
epoch_schedule: EpochSchedule::new(slots_per_epoch), epoch_schedule: EpochSchedule::new(slots_per_epoch),
operating_mode: OperatingMode::Stable,
..GenesisConfig::default() ..GenesisConfig::default()
}; };
let mut bank = Arc::new(Bank::new(&genesis_config)); let mut bank = Arc::new(Bank::new(&genesis_config));

View File

@ -2873,7 +2873,7 @@ pub mod tests {
let largest_accounts: Vec<RpcAccountBalance> = let largest_accounts: Vec<RpcAccountBalance> =
serde_json::from_value(json["result"]["value"].clone()) serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization"); .expect("actual response deserialization");
assert_eq!(largest_accounts.len(), 19); assert_eq!(largest_accounts.len(), 20);
// Get Alice balance // Get Alice balance
let req = format!( let req = format!(
@ -2910,7 +2910,7 @@ pub mod tests {
let largest_accounts: Vec<RpcAccountBalance> = let largest_accounts: Vec<RpcAccountBalance> =
serde_json::from_value(json["result"]["value"].clone()) serde_json::from_value(json["result"]["value"].clone())
.expect("actual response deserialization"); .expect("actual response deserialization");
assert_eq!(largest_accounts.len(), 18); assert_eq!(largest_accounts.len(), 19);
let req = r#"{"jsonrpc":"2.0","id":1,"method":"getLargestAccounts","params":[{"filter":"nonCirculating"}]}"#; let req = r#"{"jsonrpc":"2.0","id":1,"method":"getLargestAccounts","params":[{"filter":"nonCirculating"}]}"#;
let res = io.handle_request_sync(&req, meta); let res = io.handle_request_sync(&req, meta);
let json: Value = serde_json::from_str(&res.unwrap()).unwrap(); let json: Value = serde_json::from_str(&res.unwrap()).unwrap();
@ -4906,7 +4906,7 @@ pub mod tests {
.expect("actual response deserialization"); .expect("actual response deserialization");
let accounts: Vec<RpcKeyedAccount> = let accounts: Vec<RpcKeyedAccount> =
serde_json::from_value(result["result"].clone()).unwrap(); serde_json::from_value(result["result"].clone()).unwrap();
assert_eq!(accounts.len(), 3); assert_eq!(accounts.len(), 4);
// Test returns only mint accounts // Test returns only mint accounts
let req = format!( let req = format!(

View File

@ -386,7 +386,7 @@ mod tests {
use solana_runtime::{ use solana_runtime::{
bank::Bank, bank_forks::CompressionType, snapshot_utils::SnapshotVersion, bank::Bank, bank_forks::CompressionType, snapshot_utils::SnapshotVersion,
}; };
use solana_sdk::signature::Signer; use solana_sdk::{genesis_config::OperatingMode, signature::Signer};
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
#[test] #[test]
@ -438,7 +438,10 @@ mod tests {
} }
fn create_bank_forks() -> Arc<RwLock<BankForks>> { fn create_bank_forks() -> Arc<RwLock<BankForks>> {
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); let GenesisConfigInfo {
mut genesis_config, ..
} = create_genesis_config(10_000);
genesis_config.operating_mode = OperatingMode::Stable;
let bank = Bank::new(&genesis_config); let bank = Bank::new(&genesis_config);
Arc::new(RwLock::new(BankForks::new(bank))) Arc::new(RwLock::new(BankForks::new(bank)))
} }

View File

@ -44,7 +44,9 @@ use solana_sdk::{
hash::{extend_and_hash, hashv, Hash}, hash::{extend_and_hash, hashv, Hash},
incinerator, incinerator,
inflation::Inflation, inflation::Inflation,
native_loader, nonce, native_loader,
native_token::sol_to_lamports,
nonce,
program_utils::limited_deserialize, program_utils::limited_deserialize,
pubkey::Pubkey, pubkey::Pubkey,
sanitize::Sanitize, sanitize::Sanitize,
@ -71,6 +73,29 @@ use std::{
sync::{Arc, RwLock, RwLockReadGuard}, sync::{Arc, RwLock, RwLockReadGuard},
}; };
// Partial SPL Token v2.0.x declarations inlined to avoid an external dependency on the spl-token crate
pub mod inline_spl_token_v2_0 {
solana_sdk::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
pub mod native_mint {
solana_sdk::declare_id!("So11111111111111111111111111111111111111112");
/*
Mint {
mint_authority: COption::None,
supply: 0,
decimals: 9,
is_initialized: true,
freeze_authority: COption::None,
}
*/
pub const ACCOUNT_DATA: [u8; 82] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
}
}
pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0; pub const SECONDS_PER_YEAR: f64 = 365.25 * 24.0 * 60.0 * 60.0;
pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5; pub const MAX_LEADER_SCHEDULE_STAKES: Epoch = 5;
@ -3208,6 +3233,7 @@ impl Bank {
self.reinvoke_entered_epoch_callback(initiate_callback); self.reinvoke_entered_epoch_callback(initiate_callback);
self.recheck_cross_program_support(); self.recheck_cross_program_support();
self.recheck_compute_budget(); self.recheck_compute_budget();
self.reconfigure_token2_native_mint();
} }
fn ensure_builtins(&mut self, init_or_warp: bool) { fn ensure_builtins(&mut self, init_or_warp: bool) {
@ -3257,6 +3283,49 @@ impl Bank {
self.set_compute_budget(compute_budget); self.set_compute_budget(compute_budget);
} }
fn reconfigure_token2_native_mint(self: &mut Bank) {
let reconfigure_token2_native_mint = match self.operating_mode() {
OperatingMode::Development => true,
OperatingMode::Preview => self.epoch() == 95,
OperatingMode::Stable => self.epoch() == 75,
};
if reconfigure_token2_native_mint {
let mut native_mint_account = solana_sdk::account::Account {
owner: inline_spl_token_v2_0::id(),
data: inline_spl_token_v2_0::native_mint::ACCOUNT_DATA.to_vec(),
lamports: sol_to_lamports(1.),
executable: false,
rent_epoch: self.epoch() + 1,
};
// As a workaround for
// https://github.com/solana-labs/solana-program-library/issues/374, ensure that the
// spl-token 2 native mint account is owned by the spl-token 2 program.
let store = if let Some(existing_native_mint_account) =
self.get_account(&inline_spl_token_v2_0::native_mint::id())
{
if existing_native_mint_account.owner == solana_sdk::system_program::id() {
native_mint_account.lamports = existing_native_mint_account.lamports;
true
} else {
false
}
} else {
self.capitalization
.fetch_add(native_mint_account.lamports, Ordering::Relaxed);
true
};
if store {
self.store_account(
&inline_spl_token_v2_0::native_mint::id(),
&native_mint_account,
);
}
}
}
fn fix_recent_blockhashes_sysvar_delay(&self) -> bool { fn fix_recent_blockhashes_sysvar_delay(&self) -> bool {
let activation_slot = match self.operating_mode() { let activation_slot = match self.operating_mode() {
OperatingMode::Development => 0, OperatingMode::Development => 0,
@ -3483,6 +3552,7 @@ mod tests {
accounts: (0..42) accounts: (0..42)
.map(|_| (Pubkey::new_rand(), Account::new(42, 0, &Pubkey::default()))) .map(|_| (Pubkey::new_rand(), Account::new(42, 0, &Pubkey::default())))
.collect(), .collect(),
operating_mode: OperatingMode::Stable,
..GenesisConfig::default() ..GenesisConfig::default()
})); }));
assert_eq!(bank.capitalization(), 42 * 42); assert_eq!(bank.capitalization(), 42 * 42);
@ -4948,6 +5018,7 @@ mod tests {
hashes_per_tick: None, hashes_per_tick: None,
target_tick_count: None, target_tick_count: None,
}, },
operating_mode: OperatingMode::Stable,
..GenesisConfig::default() ..GenesisConfig::default()
})); }));
@ -5059,6 +5130,7 @@ mod tests {
hashes_per_tick: None, hashes_per_tick: None,
target_tick_count: None, target_tick_count: None,
}, },
operating_mode: OperatingMode::Stable,
..GenesisConfig::default() ..GenesisConfig::default()
})); }));
@ -8008,6 +8080,7 @@ mod tests {
&[], &[],
); );
genesis_config.creation_time = 0; genesis_config.creation_time = 0;
genesis_config.operating_mode = OperatingMode::Stable;
let mut bank = Arc::new(Bank::new(&genesis_config)); let mut bank = Arc::new(Bank::new(&genesis_config));
// Check a few slots, cross an epoch boundary // Check a few slots, cross an epoch boundary
assert_eq!(bank.get_slots_in_epoch(0), 32); assert_eq!(bank.get_slots_in_epoch(0), 32);
@ -8016,25 +8089,25 @@ mod tests {
if bank.slot == 0 { if bank.slot == 0 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"DJ5664svVgjZ8sRLZSrdYAjaAzJe3aEGVBDpZEeoZJ5u" "HrxvKJxPhzgXgoJ2Rg91acrXWki6SErJk1sfxfTDWsZt"
); );
} }
if bank.slot == 32 { if bank.slot == 32 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"GDH7kUpcQuMT23pPeU9vZdmyMSPQPwzoqdNgFaLga7x3" "AemCVcpsULuA76fpDYzs74futtMQtNNiF1gz3VSVP4AS"
); );
} }
if bank.slot == 64 { if bank.slot == 64 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"J4L6bT3KnMMXSufcUSy6Lg9TNi2pFVsYNvQ1Fzms2j1Z" "4ECxp4u4SRwn2w7YUj28nnADMx7kQ2gYRB7PA617eWu6"
); );
} }
if bank.slot == 128 { if bank.slot == 128 {
assert_eq!( assert_eq!(
bank.hash().to_string(), bank.hash().to_string(),
"BiCUyj8PsbsLW79waf1ifr3wDuZSFwLBhTkdbgHFjrtJ" "AeHGi2VWQ7gWh6KkMQjrhY1ZrLUedgMxfvPRR82dyg6L"
); );
break; break;
} }
@ -8125,7 +8198,7 @@ mod tests {
.map(|_| bank.process_stale_slot_with_budget(0, force_to_return_alive_account)) .map(|_| bank.process_stale_slot_with_budget(0, force_to_return_alive_account))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
consumed_budgets.sort(); consumed_budgets.sort();
assert_eq!(consumed_budgets, vec![0, 1, 8]); assert_eq!(consumed_budgets, vec![0, 1, 9]);
} }
#[test] #[test]
@ -8360,4 +8433,70 @@ mod tests {
.unwrap() .unwrap()
.add_native_program("mock_program", &program_id); .add_native_program("mock_program", &program_id);
} }
#[test]
fn test_reconfigure_token2_native_mint() {
solana_logger::setup();
let mut genesis_config =
create_genesis_config_with_leader(5, &Pubkey::new_rand(), 0).genesis_config;
// OperatingMode::Development - Native mint exists immediately
assert_eq!(genesis_config.operating_mode, OperatingMode::Development);
let bank = Arc::new(Bank::new(&genesis_config));
assert_eq!(
bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
1000000000
);
// OperatingMode::Preview - Native mint blinks into existence at epoch 95
genesis_config.operating_mode = OperatingMode::Preview;
let bank = Arc::new(Bank::new(&genesis_config));
assert_eq!(
bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
0
);
bank.deposit(&inline_spl_token_v2_0::native_mint::id(), 4200000000);
let bank = Bank::new_from_parent(
&bank,
&Pubkey::default(),
genesis_config.epoch_schedule.get_first_slot_in_epoch(95),
);
let native_mint_account = bank
.get_account(&inline_spl_token_v2_0::native_mint::id())
.unwrap();
assert_eq!(native_mint_account.data.len(), 82);
assert_eq!(
bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
4200000000
);
assert_eq!(native_mint_account.owner, inline_spl_token_v2_0::id());
// OperatingMode::Stable - Native mint blinks into existence at epoch 75
genesis_config.operating_mode = OperatingMode::Stable;
let bank = Arc::new(Bank::new(&genesis_config));
assert_eq!(
bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
0
);
bank.deposit(&inline_spl_token_v2_0::native_mint::id(), 4200000000);
let bank = Bank::new_from_parent(
&bank,
&Pubkey::default(),
genesis_config.epoch_schedule.get_first_slot_in_epoch(75),
);
let native_mint_account = bank
.get_account(&inline_spl_token_v2_0::native_mint::id())
.unwrap();
assert_eq!(native_mint_account.data.len(), 82);
assert_eq!(
bank.get_balance(&inline_spl_token_v2_0::native_mint::id()),
4200000000
);
assert_eq!(native_mint_account.owner, inline_spl_token_v2_0::id());
}
} }