Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ members = [
"poh",
"poh-bench",
"program-test",
"programs/address-map",
"programs/address-map-tests",
"programs/bpf_loader",
"programs/compute-budget",
"programs/config",
Expand Down
21 changes: 21 additions & 0 deletions programs/address-map-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This package only exists to avoid circular dependencies during cargo publish:
# solana-runtime -> solana-address-program-runtime -> solana-program-test -> solana-runtime

[package]
name = "solana-address-map-program-tests"
version = "1.9.0"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
edition = "2018"
publish = false

[dev-dependencies]
bincode = "1.3.3"
solana-address-map-program = { path = "../address-map", version = "=1.9.0" }
solana-program-test = { path = "../../program-test", version = "=1.9.0" }
solana-sdk = { path = "../../sdk", version = "=1.9.0" }

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
246 changes: 246 additions & 0 deletions programs/address-map-tests/tests/processor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
use {
solana_address_map_program::{
id,
instruction::{
activate, close_account, deactivate, initialize_account, insert_entries, set_authority,
},
processor::process_instruction,
state::{AddressMap, AddressMapState},
},
solana_program_test::*,
solana_sdk::{
clock::{Epoch, Slot},
epoch_schedule::EpochSchedule,
instruction::InstructionError,
native_token::LAMPORTS_PER_SOL,
pubkey::Pubkey,
signature::{Keypair, Signer},
system_instruction::transfer,
transaction::{Transaction, TransactionError},
},
};

const WARP_EPOCH: Epoch = 1;

async fn setup_warped_context() -> ProgramTestContext {
let program_test = ProgramTest::new("", id(), Some(process_instruction));
let mut context = program_test.start_with_context().await;
let epoch_schedule = EpochSchedule::default();
let warp_slot = epoch_schedule.get_first_slot_in_epoch(WARP_EPOCH);
context.warp_to_slot(warp_slot).unwrap();
context
}

#[tokio::test]
async fn test_initialize_account() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;

// First initialization should succeed
{
let authority_address = Pubkey::new_unique();
let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority_address, WARP_EPOCH, 0);
let transaction = Transaction::new_signed_with_payer(
&[init_account_instruction],
Some(&payer.pubkey()),
&[payer],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
Comment thread
jstarry marked this conversation as resolved.
let map_account = client.get_account(map_address).await.unwrap().unwrap();
let map = AddressMap::deserialize(&map_account.data).unwrap();
assert_eq!(map.authority, Some(authority_address));
assert_eq!(map.activation_slot, Slot::MAX);
assert_eq!(map.deactivation_slot, Slot::MAX);
assert_eq!(map.num_entries, 0u8);
}

// Second initialization should fail
{
let authority_address = Pubkey::new_unique();
let transaction = Transaction::new_signed_with_payer(
&[initialize_account(payer.pubkey(), authority_address, WARP_EPOCH, 0).0],
Some(&payer.pubkey()),
&[payer],
recent_blockhash,
);

assert_eq!(
client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap(),
TransactionError::InstructionError(0, InstructionError::AccountAlreadyInitialized),
);
}
}

#[tokio::test]
async fn test_initialize_account_wrong_epoch() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let transaction = Transaction::new_signed_with_payer(
&[initialize_account(payer.pubkey(), Pubkey::new_unique(), WARP_EPOCH + 1, 0).0],
Some(&payer.pubkey()),
&[payer],
recent_blockhash,
);

assert_eq!(
client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap(),
TransactionError::InstructionError(0, InstructionError::InvalidArgument),
);
}

#[tokio::test]
async fn test_set_authority() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let authority = Keypair::new();
let new_authority = Pubkey::new_unique();

let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority.pubkey(), WARP_EPOCH, 0);
let transaction = Transaction::new_signed_with_payer(
&[
init_account_instruction,
set_authority(map_address, authority.pubkey(), Some(new_authority)),
],
Some(&payer.pubkey()),
&[payer, &authority],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
let map_account = client.get_account(map_address).await.unwrap().unwrap();
let map = AddressMap::deserialize(&map_account.data).unwrap();
assert_eq!(map.authority, Some(new_authority));
}

#[tokio::test]
async fn test_insert_entries() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let authority = Keypair::new();

let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority.pubkey(), WARP_EPOCH, 10);
let mut entries = Vec::with_capacity(10);
entries.resize_with(10, Pubkey::new_unique);
let transaction = Transaction::new_signed_with_payer(
&[
init_account_instruction,
insert_entries(map_address, authority.pubkey(), 0, entries.clone()),
],
Some(&payer.pubkey()),
&[payer, &authority],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
let map_account = client.get_account(map_address).await.unwrap().unwrap();
let map = AddressMap::deserialize(&map_account.data).unwrap();
let map_entries = map.deserialize_entries(&map_account.data).unwrap();
assert_eq!(map_entries, entries);
}

#[tokio::test]
async fn test_activate() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let authority = Keypair::new();

let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority.pubkey(), WARP_EPOCH, 0);
let transaction = Transaction::new_signed_with_payer(
&[
init_account_instruction,
activate(map_address, authority.pubkey()),
],
Some(&payer.pubkey()),
&[payer, &authority],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
let map_account = client.get_account(map_address).await.unwrap().unwrap();
let map = AddressMap::deserialize(&map_account.data).unwrap();
let current_slot = client.get_root_slot().await.unwrap();
assert_eq!(map.activation_slot, current_slot);
}

#[tokio::test]
async fn test_deactivate() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let authority = Keypair::new();

let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority.pubkey(), WARP_EPOCH, 0);
let transaction = Transaction::new_signed_with_payer(
&[
init_account_instruction,
activate(map_address, authority.pubkey()),
deactivate(map_address, authority.pubkey()),
],
Some(&payer.pubkey()),
&[payer, &authority],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
let map_account = client.get_account(map_address).await.unwrap().unwrap();
let map = AddressMap::deserialize(&map_account.data).unwrap();
let current_slot = client.get_root_slot().await.unwrap();
assert_eq!(map.deactivation_slot, current_slot);
}

#[tokio::test]
async fn test_close_account() {
let mut context = setup_warped_context().await;
let client = &mut context.banks_client;
let payer = &context.payer;
let recent_blockhash = context.last_blockhash;
let authority = Keypair::new();

let (init_account_instruction, map_address) =
initialize_account(payer.pubkey(), authority.pubkey(), WARP_EPOCH, 0);
let transaction = Transaction::new_signed_with_payer(
&[
init_account_instruction,
close_account(map_address, payer.pubkey(), authority.pubkey()),
transfer(&payer.pubkey(), &map_address, LAMPORTS_PER_SOL),
],
Some(&payer.pubkey()),
&[payer, &authority],
recent_blockhash,
);

assert!(client.process_transaction(transaction).await.is_ok());
let closed_account = client.get_account(map_address).await.unwrap().unwrap();
let uninitialized_data = bincode::serialize(&AddressMapState::Uninitialized).unwrap();
assert_eq!(
Comment thread
jstarry marked this conversation as resolved.
closed_account.data[0..uninitialized_data.len()],
uninitialized_data[..]
);
assert_eq!(closed_account.lamports, LAMPORTS_PER_SOL);
}
32 changes: 32 additions & 0 deletions programs/address-map/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "solana-address-map-program"
version = "1.9.0"
description = "Solana address map program"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-address-map-program"
edition = "2018"

[dependencies]
bincode = "1.3.3"
log = "0.4.14"
num-derive = "0.3"
num-traits = "0.2"
serde = { version = "1.0.127", features = ["derive"] }
solana-frozen-abi = { path = "../../frozen-abi", version = "=1.9.0" }
solana-frozen-abi-macro = { path = "../../frozen-abi/macro", version = "=1.9.0" }
solana-program-runtime = { path = "../../program-runtime", version = "=1.9.0" }
solana-sdk = { path = "../../sdk", version = "=1.9.0" }
thiserror = "1.0"

[build-dependencies]
rustc_version = "0.4"

[lib]
crate-type = ["lib"]
name = "solana_address_map_program"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
1 change: 1 addition & 0 deletions programs/address-map/build.rs
Loading