Preliminary Wallet-Budget functionality

This commit is contained in:
Tyera Eulberg
2018-09-19 17:44:03 -06:00
committed by Grimes
parent e943ed8caf
commit 5038e5ccd7
3 changed files with 148 additions and 19 deletions

View File

@ -332,6 +332,7 @@ mod test {
to.pubkey(), to.pubkey(),
contract.pubkey(), contract.pubkey(),
dt, dt,
from.pubkey(),
1, 1,
Hash::default(), Hash::default(),
); );
@ -405,6 +406,7 @@ mod test {
to.pubkey(), to.pubkey(),
contract.pubkey(), contract.pubkey(),
dt, dt,
from.pubkey(),
1, 1,
Hash::default(), Hash::default(),
); );
@ -516,8 +518,15 @@ mod test {
] ]
); );
let tx = let tx = Transaction::budget_new_on_date(
Transaction::budget_new_on_date(&keypair, to, contract, date, 192, Hash::default()); &keypair,
to,
contract,
date,
keypair.pubkey(),
192,
Hash::default(),
);
assert_eq!( assert_eq!(
tx.userdata, tx.userdata,
vec![ vec![

View File

@ -152,12 +152,13 @@ impl Transaction {
to: Pubkey, to: Pubkey,
contract: Pubkey, contract: Pubkey,
dt: DateTime<Utc>, dt: DateTime<Utc>,
dt_pubkey: Pubkey,
tokens: i64, tokens: i64,
last_id: Hash, last_id: Hash,
) -> Self { ) -> Self {
let from = from_keypair.pubkey(); let from = from_keypair.pubkey();
let budget = Budget::Or( let budget = Budget::Or(
(Condition::Timestamp(dt, from), Payment { tokens, to }), (Condition::Timestamp(dt, dt_pubkey), Payment { tokens, to }),
(Condition::Signature(from), Payment { tokens, to: from }), (Condition::Signature(from), Payment { tokens, to: from }),
); );
let instruction = Instruction::NewContract(Contract { budget, tokens }); let instruction = Instruction::NewContract(Contract { budget, tokens });

View File

@ -30,7 +30,7 @@ pub enum WalletCommand {
Balance, Balance,
Cancel(Pubkey), Cancel(Pubkey),
Confirm(Signature), Confirm(Signature),
// Pay(to, tokens, timestamp, timestamp_pubkey, witness(es), cancelable) // Pay(tokens, to, timestamp, timestamp_pubkey, witness(es), cancelable)
Pay( Pay(
i64, i64,
Pubkey, Pubkey,
@ -224,7 +224,7 @@ pub fn parse_command(
Err(WalletError::BadParameter("Invalid public key".to_string()))?; Err(WalletError::BadParameter("Invalid public key".to_string()))?;
} }
let process_id = Pubkey::new(&pubkey_vec); let process_id = Pubkey::new(&pubkey_vec);
let datetime = if timestamp_matches.is_present("datetime") { let dt = if timestamp_matches.is_present("datetime") {
// Parse input for serde_json // Parse input for serde_json
let date_string = if !timestamp_matches let date_string = if !timestamp_matches
.value_of("datetime") .value_of("datetime")
@ -239,7 +239,7 @@ pub fn parse_command(
} else { } else {
Utc::now() Utc::now()
}; };
Ok(WalletCommand::TimeElapsed(process_id, datetime)) Ok(WalletCommand::TimeElapsed(process_id, dt))
} }
("", None) => { ("", None) => {
println!("{}", matches.usage()); println!("{}", matches.usage());
@ -312,10 +312,35 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<error::Error
} }
// Cancel a contract by contract Pubkey // Cancel a contract by contract Pubkey
WalletCommand::Cancel(pubkey) => { WalletCommand::Cancel(pubkey) => {
println!("{:?}", pubkey); let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?;
Err(WalletError::BadParameter( if result.as_str().is_none() {
"Cancel not built yet".to_string(), Err(WalletError::RpcRequestError(
))? "Received bad last_id".to_string(),
))?
}
let last_id_str = result.as_str().unwrap();
let last_id_vec = bs58::decode(last_id_str)
.into_vec()
.map_err(|_| WalletError::RpcRequestError("Received bad last_id".to_string()))?;
let last_id = Hash::new(&last_id_vec);
let tx =
Transaction::budget_new_signature(&config.id, pubkey, config.id.pubkey(), last_id);
let serialized = serialize(&tx).unwrap();
let params = json!(serialized);
let signature = WalletRpcRequest::SendTransaction.make_rpc_request(
&config.rpc_addr,
2,
Some(params),
)?;
if signature.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(),
))?
}
let signature_str = signature.as_str().unwrap();
Ok(format!("{}", signature_str))
} }
// Confirm the last client transaction by signature // Confirm the last client transaction by signature
WalletCommand::Confirm(signature) => { WalletCommand::Confirm(signature) => {
@ -337,7 +362,7 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<error::Error
} }
} }
// If client has positive balance, pay tokens to another address // If client has positive balance, pay tokens to another address
WalletCommand::Pay(tokens, to, _, _, _, _) => { WalletCommand::Pay(tokens, to, timestamp, timestamp_pubkey, ref witnesses, cancelable) => {
let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?; let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?;
if result.as_str().is_none() { if result.as_str().is_none() {
Err(WalletError::RpcRequestError( Err(WalletError::RpcRequestError(
@ -350,7 +375,77 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<error::Error
.map_err(|_| WalletError::RpcRequestError("Received bad last_id".to_string()))?; .map_err(|_| WalletError::RpcRequestError("Received bad last_id".to_string()))?;
let last_id = Hash::new(&last_id_vec); let last_id = Hash::new(&last_id_vec);
let tx = Transaction::new(&config.id, to, tokens, last_id); if timestamp == None && *witnesses == None {
let tx = Transaction::new(&config.id, to, tokens, last_id);
let serialized = serialize(&tx).unwrap();
let params = json!(serialized);
let signature = WalletRpcRequest::SendTransaction.make_rpc_request(
&config.rpc_addr,
2,
Some(params),
)?;
if signature.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(),
))?
}
let signature_str = signature.as_str().unwrap();
Ok(format!("{}", signature_str))
} else if *witnesses == None {
let dt = timestamp.unwrap();
let dt_pubkey = match timestamp_pubkey {
Some(pubkey) => pubkey,
None => config.id.pubkey(),
};
let process_id = Keypair::new().pubkey();
let tx = Transaction::budget_new_on_date(
&config.id, to, process_id, dt, dt_pubkey, tokens, last_id,
);
let serialized = serialize(&tx).unwrap();
let params = json!(serialized);
let signature = WalletRpcRequest::SendTransaction.make_rpc_request(
&config.rpc_addr,
2,
Some(params),
)?;
if signature.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(),
))?
}
let signature_str = signature.as_str().unwrap();
Ok(json!({
"signature": signature_str,
"processId": process_id,
}).to_string())
} else if timestamp == None {
Ok("Witness Txs not yet handled".to_string())
} else {
Ok("Witness Txs not yet handled".to_string())
}
}
// Apply time elapsed to contract
WalletCommand::TimeElapsed(pubkey, dt) => {
let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?;
if result.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received bad last_id".to_string(),
))?
}
let last_id_str = result.as_str().unwrap();
let last_id_vec = bs58::decode(last_id_str)
.into_vec()
.map_err(|_| WalletError::RpcRequestError("Received bad last_id".to_string()))?;
let last_id = Hash::new(&last_id_vec);
let tx = Transaction::budget_new_timestamp(
&config.id,
pubkey,
config.id.pubkey(),
dt,
last_id,
);
let serialized = serialize(&tx).unwrap(); let serialized = serialize(&tx).unwrap();
let params = json!(serialized); let params = json!(serialized);
let signature = WalletRpcRequest::SendTransaction.make_rpc_request( let signature = WalletRpcRequest::SendTransaction.make_rpc_request(
@ -367,14 +462,38 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<error::Error
Ok(signature_str.to_string()) Ok(signature_str.to_string())
} }
// Apply time elapsed to contract
WalletCommand::TimeElapsed(pubkey, timestamp) => Err(WalletError::BadParameter(
"TimeElapsed not built yet".to_string(),
))?,
// Apply witness signature to contract // Apply witness signature to contract
WalletCommand::Witness(pubkey) => Err(WalletError::BadParameter( WalletCommand::Witness(pubkey) => {
"Witness not built yet".to_string(), let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?;
))?, if result.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received bad last_id".to_string(),
))?
}
let last_id_str = result.as_str().unwrap();
let last_id_vec = bs58::decode(last_id_str)
.into_vec()
.map_err(|_| WalletError::RpcRequestError("Received bad last_id".to_string()))?;
let last_id = Hash::new(&last_id_vec);
let tx =
Transaction::budget_new_signature(&config.id, pubkey, config.id.pubkey(), last_id);
let serialized = serialize(&tx).unwrap();
let params = json!(serialized);
let signature = WalletRpcRequest::SendTransaction.make_rpc_request(
&config.rpc_addr,
2,
Some(params),
)?;
if signature.as_str().is_none() {
Err(WalletError::RpcRequestError(
"Received result of an unexpected type".to_string(),
))?
}
let signature_str = signature.as_str().unwrap();
Ok(format!("{}", signature_str))
}
} }
} }