Refactor wallet processing

Yuge functions
This commit is contained in:
Stephen Akridge 2019-02-09 13:15:44 -08:00 committed by sakridge
parent 1c61415cee
commit ed4e9febe0
1 changed files with 380 additions and 308 deletions

View File

@ -313,26 +313,14 @@ pub fn parse_command(
Ok(response) Ok(response)
} }
pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::Error>> { type ProcessResult = Result<String, Box<dyn error::Error>>;
if let WalletCommand::Address = config.command {
// Get address of this client
return Ok(format!("{}", config.id.pubkey()));
}
let drone_addr = config.drone_addr(); fn process_airdrop(
let rpc_client = if config.rpc_client.is_none() { rpc_client: &RpcClient,
let rpc_addr = config.rpc_addr(); config: &WalletConfig,
RpcClient::new(rpc_addr) drone_addr: SocketAddr,
} else { tokens: u64,
// Primarily for testing ) -> ProcessResult {
config.rpc_client.clone().unwrap()
};
match config.command {
// Get address of this client
WalletCommand::Address => unreachable!(),
// Request an airdrop from Solana Drone;
WalletCommand::Airdrop(tokens) => {
println!( println!(
"Requesting airdrop of {:?} tokens from {}", "Requesting airdrop of {:?} tokens from {}",
tokens, drone_addr tokens, drone_addr
@ -370,9 +358,9 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
))?; ))?;
} }
Ok(format!("Your balance is: {:?}", current_balance)) Ok(format!("Your balance is: {:?}", current_balance))
} }
// Check client balance
WalletCommand::Balance => { fn process_balance(config: &WalletConfig, rpc_client: &RpcClient) -> ProcessResult {
let params = json!([format!("{}", config.id.pubkey())]); let params = json!([format!("{}", config.id.pubkey())]);
let balance = rpc_client let balance = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)? .retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)?
@ -384,17 +372,9 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
"Received result of an unexpected type".to_string(), "Received result of an unexpected type".to_string(),
))?, ))?,
} }
} }
// Cancel a contract by contract Pubkey
WalletCommand::Cancel(pubkey) => { fn process_confirm(rpc_client: &RpcClient, signature: Signature) -> ProcessResult {
let last_id = get_last_id(&rpc_client)?;
let mut tx =
BudgetTransaction::new_signature(&config.id, pubkey, config.id.pubkey(), last_id);
let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?;
Ok(signature_str.to_string())
}
// Confirm the last client transaction by signature
WalletCommand::Confirm(signature) => {
let params = json!([format!("{}", signature)]); let params = json!([format!("{}", signature)]);
let confirmation = rpc_client let confirmation = rpc_client
.retry_make_rpc_request(1, &RpcRequest::ConfirmTransaction, Some(params), 5)? .retry_make_rpc_request(1, &RpcRequest::ConfirmTransaction, Some(params), 5)?
@ -411,9 +391,13 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
"Received result of an unexpected type".to_string(), "Received result of an unexpected type".to_string(),
))?, ))?,
} }
} }
// Deploy a custom program to the chain
WalletCommand::Deploy(ref program_location) => { fn process_deploy(
rpc_client: &RpcClient,
config: &WalletConfig,
program_location: &str,
) -> ProcessResult {
let params = json!([format!("{}", config.id.pubkey())]); let params = json!([format!("{}", config.id.pubkey())]);
let balance = rpc_client let balance = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)? .retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)?
@ -464,10 +448,7 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
0, 0,
); );
send_and_confirm_tx(&rpc_client, &mut tx, &program_id).map_err(|_| { send_and_confirm_tx(&rpc_client, &mut tx, &program_id).map_err(|_| {
WalletError::DynamicProgramError(format!( WalletError::DynamicProgramError(format!("Program write failed at offset {:?}", offset))
"Program write failed at offset {:?}",
offset
))
})?; })?;
offset += USERDATA_CHUNK_SIZE as u32; offset += USERDATA_CHUNK_SIZE as u32;
} }
@ -479,28 +460,25 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
})?; })?;
let mut tx = SystemTransaction::new_spawn(&program_id, last_id, 0); let mut tx = SystemTransaction::new_spawn(&program_id, last_id, 0);
send_and_confirm_tx(&rpc_client, &mut tx, &program_id).map_err(|_| { send_and_confirm_tx(&rpc_client, &mut tx, &program_id)
WalletError::DynamicProgramError("Program spawn failed".to_string()) .map_err(|_| WalletError::DynamicProgramError("Program spawn failed".to_string()))?;
})?;
Ok(json!({ Ok(json!({
"programId": format!("{}", program_id.pubkey()), "programId": format!("{}", program_id.pubkey()),
}) })
.to_string()) .to_string())
} }
WalletCommand::GetTransactionCount => {
let transaction_count = rpc_client fn process_pay(
.retry_make_rpc_request(1, &RpcRequest::GetTransactionCount, None, 5)? rpc_client: &RpcClient,
.as_u64(); config: &WalletConfig,
match transaction_count { tokens: u64,
Some(count) => Ok(count.to_string()), to: Pubkey,
None => Err(WalletError::RpcRequestError( timestamp: Option<DateTime<Utc>>,
"Received result of an unexpected type".to_string(), timestamp_pubkey: Option<Pubkey>,
))?, witnesses: &Option<Vec<Pubkey>>,
} cancelable: Option<Pubkey>,
} ) -> ProcessResult {
// If client has positive balance, pay tokens to another address
WalletCommand::Pay(tokens, to, timestamp, timestamp_pubkey, ref witnesses, cancelable) => {
let last_id = get_last_id(&rpc_client)?; let last_id = get_last_id(&rpc_client)?;
if timestamp == None && *witnesses == None { if timestamp == None && *witnesses == None {
@ -619,9 +597,35 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
} else { } else {
Ok("Combo transactions not yet handled".to_string()) Ok("Combo transactions not yet handled".to_string())
} }
}
fn process_cancel(rpc_client: &RpcClient, config: &WalletConfig, pubkey: Pubkey) -> ProcessResult {
let last_id = get_last_id(&rpc_client)?;
let mut tx = BudgetTransaction::new_signature(&config.id, pubkey, config.id.pubkey(), last_id);
let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?;
Ok(signature_str.to_string())
}
fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult {
let transaction_count = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetTransactionCount, None, 5)?
.as_u64();
match transaction_count {
Some(count) => Ok(count.to_string()),
None => Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(),
))?,
} }
// Apply time elapsed to contract }
WalletCommand::TimeElapsed(to, pubkey, dt) => {
fn process_time_elapsed(
rpc_client: &RpcClient,
config: &WalletConfig,
drone_addr: SocketAddr,
to: Pubkey,
pubkey: Pubkey,
dt: DateTime<Utc>,
) -> ProcessResult {
let params = json!([format!("{}", config.id.pubkey())]); let params = json!([format!("{}", config.id.pubkey())]);
let balance = rpc_client let balance = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)? .retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)?
@ -637,9 +641,15 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?; let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?;
Ok(signature_str.to_string()) Ok(signature_str.to_string())
} }
// Apply witness signature to contract
WalletCommand::Witness(to, pubkey) => { fn process_witness(
rpc_client: &RpcClient,
config: &WalletConfig,
drone_addr: SocketAddr,
to: Pubkey,
pubkey: Pubkey,
) -> ProcessResult {
let params = json!([format!("{}", config.id.pubkey())]); let params = json!([format!("{}", config.id.pubkey())]);
let balance = rpc_client let balance = rpc_client
.retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)? .retry_make_rpc_request(1, &RpcRequest::GetBalance, Some(params), 5)?
@ -654,6 +664,68 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<dyn error::E
let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?; let signature_str = send_and_confirm_tx(&rpc_client, &mut tx, &config.id)?;
Ok(signature_str.to_string()) Ok(signature_str.to_string())
}
pub fn process_command(config: &WalletConfig) -> ProcessResult {
if let WalletCommand::Address = config.command {
// Get address of this client
return Ok(format!("{}", config.id.pubkey()));
}
let drone_addr = config.drone_addr();
let rpc_client = if config.rpc_client.is_none() {
let rpc_addr = config.rpc_addr();
RpcClient::new(rpc_addr)
} else {
// Primarily for testing
config.rpc_client.clone().unwrap()
};
match config.command {
// Get address of this client
WalletCommand::Address => unreachable!(),
// Request an airdrop from Solana Drone;
WalletCommand::Airdrop(tokens) => process_airdrop(&rpc_client, config, drone_addr, tokens),
// Check client balance
WalletCommand::Balance => process_balance(config, &rpc_client),
// Cancel a contract by contract Pubkey
WalletCommand::Cancel(pubkey) => process_cancel(&rpc_client, config, pubkey),
// Confirm the last client transaction by signature
WalletCommand::Confirm(signature) => process_confirm(&rpc_client, signature),
// Deploy a custom program to the chain
WalletCommand::Deploy(ref program_location) => {
process_deploy(&rpc_client, config, program_location)
}
WalletCommand::GetTransactionCount => process_get_transaction_count(&rpc_client),
// If client has positive balance, pay tokens to another address
WalletCommand::Pay(tokens, to, timestamp, timestamp_pubkey, ref witnesses, cancelable) => {
process_pay(
&rpc_client,
config,
tokens,
to,
timestamp,
timestamp_pubkey,
witnesses,
cancelable,
)
}
// Apply time elapsed to contract
WalletCommand::TimeElapsed(to, pubkey, dt) => {
process_time_elapsed(&rpc_client, config, drone_addr, to, pubkey, dt)
}
// Apply witness signature to contract
WalletCommand::Witness(to, pubkey) => {
process_witness(&rpc_client, config, drone_addr, to, pubkey)
} }
} }
} }