Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use PDA for verified_messages account #10

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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
64 changes: 26 additions & 38 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use audius_reward_manager::{
},
processor::SENDER_SEED_PREFIX,
state::{RewardManager, SenderAccount, VerifiedMessages},
utils::find_derived_pair,
utils::find_derived_pair
};

use hex::FromHex;
Expand Down Expand Up @@ -143,6 +143,7 @@ fn command_create_sender(
);

println!("New sender account created: {:?}", derived_address);
println!("Owner {:}", config.owner.pubkey());

let transaction = CustomTransaction {
instructions: vec![create_sender(
Expand Down Expand Up @@ -243,28 +244,21 @@ fn command_add_sender(
fn command_verify_transfer_signature(
config: &Config,
reward_manager_pubkey: Pubkey,
verified_messages_keypair: Option<Keypair>,
exact_verified_messages_pubkey: Option<Pubkey>,
signer_pubkey: Pubkey,
signer_secret: String,
transfer_id: String,
recipient_eth_address: String,
amount: u64,
bot_oracle_pubkey: Option<Pubkey>,
) -> CommandResult {
let verified_messages_keypair = verified_messages_keypair.unwrap_or_else(Keypair::new);
let verified_messages_pubkey =
exact_verified_messages_pubkey.unwrap_or_else(|| verified_messages_keypair.pubkey());

println!("Verified messages {}", verified_messages_pubkey);

let decoded_recipient_address =
<[u8; 20]>::from_hex(recipient_eth_address).expect(HEX_ETH_ADDRESS_DECODING_ERROR);

let message = if let Some(bot_oracle_pubkey) = bot_oracle_pubkey {
let bot_oracle_account = config.rpc_client.get_account_data(&bot_oracle_pubkey)?;
let bot_oracle = SenderAccount::unpack(bot_oracle_account.as_slice())?;

println!("Signing as normal sender");
// Sender message
[
decoded_recipient_address.as_ref(),
Expand All @@ -277,6 +271,7 @@ fn command_verify_transfer_signature(
]
.concat()
} else {
println!("Signing as bot oracle!");
// Bot oracle message
[
decoded_recipient_address.as_ref(),
Expand All @@ -289,36 +284,24 @@ fn command_verify_transfer_signature(
};

let mut instructions = Vec::new();
let verified_messages_balance = config
.rpc_client
.get_minimum_balance_for_rent_exemption(VerifiedMessages::LEN)?;
let mut signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];

if exact_verified_messages_pubkey.is_none() {
instructions.push(system_instruction::create_account(
&config.fee_payer.pubkey(),
&verified_messages_pubkey,
verified_messages_balance,
VerifiedMessages::LEN as u64,
&audius_reward_manager::id(),
));
signers.push(&verified_messages_keypair);
}

let decoded_secret = <[u8; 32]>::from_hex(signer_secret).expect(HEX_ETH_SECRET_DECODING_ERROR);
instructions.push(new_secp256k1_instruction_2_0(
&secp256k1::SecretKey::parse(&decoded_secret)?,
message.as_ref(),
instructions.len() as u8,
));

instructions.push(verify_transfer_signature(
&audius_reward_manager::id(),
&verified_messages_pubkey,
&reward_manager_pubkey,
&signer_pubkey,
)?);
instructions.push(
verify_transfer_signature(
&audius_reward_manager::id(),
&reward_manager_pubkey,
&signer_pubkey,
&config.fee_payer.pubkey(),
transfer_id
)
?);

let signers = vec![config.fee_payer.as_ref(), config.owner.as_ref()];
let transaction = CustomTransaction {
instructions,
signers,
Expand All @@ -339,6 +322,13 @@ fn command_transfer(
) -> CommandResult {
let reward_manager = config.rpc_client.get_account_data(&reward_manager_pubkey)?;
let reward_manager = RewardManager::unpack(reward_manager.as_slice())?;
println!("RewardManager num votes: {:?}", reward_manager.min_votes);

let verified_messages = config.rpc_client.get_account_data(&verified_messages_pubkey)?;
let verified_messages = VerifiedMessages::unpack(verified_messages.as_slice())?;
println!("VerifiedMsgs reward_manager: {:?}", verified_messages.reward_manager);
println!("VerifiedMsgs number of messages: {:?}", verified_messages.messages.len());
println!("VerifiedMsgs : {:?}", verified_messages);

let decoded_recipient_address =
<[u8; 20]>::from_hex(recipient_eth_address).expect(HEX_ETH_ADDRESS_DECODING_ERROR);
Expand Down Expand Up @@ -586,7 +576,7 @@ fn main() {
)
.arg(
Arg::with_name("verified_messages_pubkey")
.long("pubkey")
.long("verified-messages-pubkey")
.validator(is_pubkey)
.value_name("ADDRESS")
.takes_value(true)
Expand Down Expand Up @@ -792,8 +782,8 @@ fn main() {
}
("verify-transfer-signature", Some(arg_matches)) => {
let reward_manager: Pubkey = pubkey_of(arg_matches, "reward_manager").unwrap();
let verified_messages_keypair = keypair_of(arg_matches, "verified_messages_keypair");
let verified_messages_pubkey = pubkey_of(arg_matches, "verified_messages_pubkey");
// let verified_messages_keypair = keypair_of(arg_matches, "verified_messages_keypair");
// let verified_messages_pubkey = pubkey_of(arg_matches, "verified_messages_pubkey");
let signer_pubkey: Pubkey = pubkey_of(arg_matches, "address").unwrap();
let signer_secret: String = value_t_or_exit!(arg_matches, "secret", String);
let transfer_id: String = value_t_or_exit!(arg_matches, "transfer_id", String);
Expand All @@ -806,8 +796,6 @@ fn main() {
command_verify_transfer_signature(
&config,
reward_manager,
verified_messages_keypair,
verified_messages_pubkey,
signer_pubkey,
signer_secret,
transfer_id,
Expand Down Expand Up @@ -851,7 +839,7 @@ fn main() {
Ok(())
})
.map_err(|err| {
eprintln!("{}", err);
exit(1);
eprintln!("{:?}", err);
exit(2)
});
}
1 change: 1 addition & 0 deletions cli/test1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[154,171,17,10,116,210,17,225,61,243,190,214,174,5,192,5,199,190,110,16,236,116,198,122,126,140,120,162,37,34,83,250,95,254,201,89,3,252,32,15,72,251,27,103,180,116,79,207,221,37,188,87,51,82,138,79,113,209,85,247,254,117,5,81]
48 changes: 40 additions & 8 deletions program/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
//! Instruction types

use crate::{
processor::{SENDER_SEED_PREFIX, TRANSFER_SEED_PREFIX},
processor::{
SENDER_SEED_PREFIX,
TRANSFER_SEED_PREFIX,
VERIFY_TRANSFER_SEED_PREFIX
},
utils::{find_derived_pair, find_program_address, EthereumAddress},
};
use borsh::{BorshDeserialize, BorshSerialize};
Expand Down Expand Up @@ -37,6 +41,13 @@ pub struct AddSenderArgs {
pub operator: EthereumAddress,
}

/// Verify `Transfer` instruction args
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
pub struct VerifyTransferSignatureArgs {
/// ID generated on backend
pub id: String
}

/// `Transfer` instruction args
#[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug, Clone)]
pub struct TransferArgs {
Expand Down Expand Up @@ -94,11 +105,15 @@ pub enum Instructions {

/// Verify transfer signature
///
/// 0. `[writable]` New or existing account storing verified messages
/// 0. `[writable]` New or existing account PDA storing verified messages
/// 1. `[]` Reward manager
/// 2. `[]` Sender
/// 3. `[]` Sysvar instruction id
VerifyTransferSignature,
/// 2. `[]` Reward manager authority
/// 3. `[signer]` Funder
/// 4. `[]` Sender
/// 5. `[]` Sysvar rent
/// 6. `[]` Instruction info
/// 7. `[]` System program id
VerifyTransferSignature(VerifyTransferSignatureArgs),

/// Transfer tokens to pointed receiver
///
Expand Down Expand Up @@ -270,17 +285,34 @@ where
/// Create `VerifyTransferSignature` instruction
pub fn verify_transfer_signature(
program_id: &Pubkey,
verified_messages: &Pubkey,
reward_manager: &Pubkey,
sender: &Pubkey,
funder: &Pubkey,
id: String
) -> Result<Instruction, ProgramError> {
let data = Instructions::VerifyTransferSignature.try_to_vec()?;
let data = Instructions::VerifyTransferSignature(
VerifyTransferSignatureArgs {
id: id.clone()
}
).try_to_vec()?;

let (reward_manager_authority, verified_messages, _) = find_derived_pair(
program_id,
reward_manager,
[VERIFY_TRANSFER_SEED_PREFIX.as_bytes().as_ref(), id.as_ref()]
.concat()
.as_ref(),
);

let accounts = vec![
AccountMeta::new(*verified_messages, false),
AccountMeta::new(verified_messages, false),
AccountMeta::new_readonly(*reward_manager, false),
AccountMeta::new_readonly(reward_manager_authority, false),
AccountMeta::new(*funder, true),
AccountMeta::new_readonly(*sender, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(sysvar::instructions::id(), false),
AccountMeta::new_readonly(system_program::id(), false),
];

Ok(Instruction {
Expand Down
2 changes: 1 addition & 1 deletion program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ pub mod entrypoint;
// Export current sdk types for downstream users building with a different sdk version
pub use solana_program;

solana_program::declare_id!("p1AVmrdt7m6AGCxDfiDQqxBVhY1Zjk7avk1nGLQyjMC");
solana_program::declare_id!("8p14azmrinvyksG3BAu38eU5DUXXFKFyvV2gb31Uzgr3");
58 changes: 55 additions & 3 deletions program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{
error::AudiusProgramError,
instruction::{
AddSenderArgs, CreateSenderArgs, InitRewardManagerArgs, Instructions, TransferArgs,
AddSenderArgs, CreateSenderArgs, InitRewardManagerArgs, Instructions, TransferArgs, VerifyTransferSignatureArgs
},
state::{RewardManager, SenderAccount, VerifiedMessage, VerifiedMessages},
utils::*,
Expand All @@ -25,6 +25,8 @@ use solana_program::{
pub const SENDER_SEED_PREFIX: &str = "S_";
/// Transfer program account seed
pub const TRANSFER_SEED_PREFIX: &str = "T_";
/// Verify transfer program account seed
pub const VERIFY_TRANSFER_SEED_PREFIX: &str = "V_";
/// Transfer account space
pub const TRANSFER_ACC_SPACE: usize = 0;

Expand Down Expand Up @@ -219,16 +221,52 @@ impl Processor {
program_id: &Pubkey,
verified_messages_info: &AccountInfo<'a>,
reward_manager_info: &AccountInfo<'a>,
authority_info: &AccountInfo<'a>,
funder_info: &AccountInfo<'a>,
rent_info: &AccountInfo<'a>,
sender_info: &AccountInfo<'a>,
instruction_info: &AccountInfo<'a>,
verify_transfer_data: VerifyTransferSignatureArgs,
) -> ProgramResult {
assert_owned_by(verified_messages_info, program_id)?;
assert_owned_by(reward_manager_info, program_id)?;
assert_owned_by(sender_info, program_id)?;

let sender_account = SenderAccount::unpack(&sender_info.data.borrow())?;
assert_account_key(reward_manager_info, &sender_account.reward_manager)?;

// Verify derived address matches expected value
let derived_seed = [
VERIFY_TRANSFER_SEED_PREFIX.as_bytes().as_ref(),
verify_transfer_data.id.as_ref(),
]
.concat();

let (reward_manager_authority, derived_address, bump_seed) =
find_derived_pair(program_id, reward_manager_info.key, derived_seed.as_ref());

assert_account_key(authority_info, &reward_manager_authority)?;
assert_account_key(verified_messages_info, &derived_address)?;

let signers_seeds = &[
&reward_manager_authority.to_bytes()[..32],
&derived_seed.as_slice(),
&[bump_seed],
];

if verified_messages_info.data_len() == 0 && verified_messages_info.lamports() == 0 {
let rent = Rent::from_account_info(rent_info)?;
create_account(
program_id,
funder_info.clone(),
verified_messages_info.clone(),
VerifiedMessages::LEN,
&[signers_seeds],
&rent,
)?;
} else {
assert_owned_by(verified_messages_info, program_id)?;
}

let mut verified_messages =
VerifiedMessages::unpack_unchecked(&verified_messages_info.data.borrow())?;
if verified_messages.is_initialized() {
Expand Down Expand Up @@ -467,20 +505,34 @@ impl Processor {
operator,
)
}
Instructions::VerifyTransferSignature => {
Instructions::VerifyTransferSignature(
VerifyTransferSignatureArgs {
id
}
) => {
msg!("Instruction: VerifyTransferSignature");

let verified_messages = next_account_info(account_info_iter)?;
let reward_manager = next_account_info(account_info_iter)?;
let authority = next_account_info(account_info_iter)?;
let funder_info = next_account_info(account_info_iter)?;
let sender = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
let instructions_info = next_account_info(account_info_iter)?;
let _system_program_id = next_account_info(account_info_iter)?;

Self::process_verify_transfer_signature(
program_id,
verified_messages,
reward_manager,
authority,
funder_info,
rent_info,
sender,
instructions_info,
VerifyTransferSignatureArgs {
id
},
)
}
Instructions::Transfer(TransferArgs {
Expand Down
Loading