Move budget-specific and system-specific tx constructors into traits
These functions pull in budget-specific and system-specific dependencies that aren't needed by the runtime.
This commit is contained in:
12
src/bank.rs
12
src/bank.rs
@ -26,7 +26,7 @@ use storage_program::StorageProgram;
|
||||
use system_program::SystemProgram;
|
||||
use tictactoe_program::TicTacToeProgram;
|
||||
use timing::{duration_as_us, timestamp};
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
use window::WINDOW_SIZE;
|
||||
|
||||
/// An Account with userdata that is stored on chain
|
||||
@ -673,7 +673,7 @@ impl Bank {
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
) -> Result<Signature> {
|
||||
let tx = Transaction::new(keypair, to, n, last_id);
|
||||
let tx = Transaction::system_new(keypair, to, n, last_id);
|
||||
let signature = tx.signature;
|
||||
self.process_transaction(&tx).map(|_| signature)
|
||||
}
|
||||
@ -798,7 +798,7 @@ mod tests {
|
||||
let dest = Keypair::new();
|
||||
|
||||
// source with 0 contract context
|
||||
let tx = Transaction::new(&mint.keypair(), dest.pubkey(), 2, mint.last_id());
|
||||
let tx = Transaction::system_new(&mint.keypair(), dest.pubkey(), 2, mint.last_id());
|
||||
let signature = tx.signature;
|
||||
assert!(!bank.has_signature(&signature));
|
||||
let res = bank.process_transaction(&tx);
|
||||
@ -930,8 +930,8 @@ mod tests {
|
||||
let mint = Mint::new(2);
|
||||
let bank = Bank::new(&mint);
|
||||
let keypair = Keypair::new();
|
||||
let tx0 = Transaction::new(&mint.keypair(), keypair.pubkey(), 2, mint.last_id());
|
||||
let tx1 = Transaction::new(&keypair, mint.pubkey(), 1, mint.last_id());
|
||||
let tx0 = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 2, mint.last_id());
|
||||
let tx1 = Transaction::system_new(&keypair, mint.pubkey(), 1, mint.last_id());
|
||||
let txs = vec![tx0, tx1];
|
||||
let results = bank.process_transactions(&txs);
|
||||
assert!(results[1].is_err());
|
||||
@ -946,7 +946,7 @@ mod tests {
|
||||
let bank = Bank::new(&mint);
|
||||
let keypair = Keypair::new();
|
||||
let entry = next_entry(&mint.last_id(), 1, vec![]);
|
||||
let tx = Transaction::new(&mint.keypair(), keypair.pubkey(), 1, entry.id);
|
||||
let tx = Transaction::system_new(&mint.keypair(), keypair.pubkey(), 1, entry.id);
|
||||
|
||||
// First, ensure the TX is rejected because of the unregistered last ID
|
||||
assert_eq!(
|
||||
|
@ -248,7 +248,7 @@ mod tests {
|
||||
use packet::{to_packets, PacketRecycler};
|
||||
use signature::{Keypair, KeypairUtil};
|
||||
use std::thread::sleep;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_banking_stage_shutdown() {
|
||||
@ -304,14 +304,14 @@ mod tests {
|
||||
|
||||
// good tx
|
||||
let keypair = mint.keypair();
|
||||
let tx = Transaction::new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
let tx = Transaction::system_new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
|
||||
// good tx, but no verify
|
||||
let tx_no_ver = Transaction::new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
let tx_no_ver = Transaction::system_new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
|
||||
// bad tx, AccountNotFound
|
||||
let keypair = Keypair::new();
|
||||
let tx_anf = Transaction::new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
let tx_anf = Transaction::system_new(&keypair, keypair.pubkey(), 1, start_hash);
|
||||
|
||||
// send 'em over
|
||||
let recycler = PacketRecycler::default();
|
||||
@ -350,7 +350,7 @@ mod tests {
|
||||
|
||||
// Process a batch that includes a transaction that receives two tokens.
|
||||
let alice = Keypair::new();
|
||||
let tx = Transaction::new(&mint.keypair(), alice.pubkey(), 2, mint.last_id());
|
||||
let tx = Transaction::system_new(&mint.keypair(), alice.pubkey(), 2, mint.last_id());
|
||||
|
||||
let packets = to_packets(&recycler, &[tx]);
|
||||
verified_sender
|
||||
@ -358,7 +358,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
// Process a second batch that spends one of those tokens.
|
||||
let tx = Transaction::new(&alice, mint.pubkey(), 1, mint.last_id());
|
||||
let tx = Transaction::system_new(&alice, mint.pubkey(), 1, mint.last_id());
|
||||
let packets = to_packets(&recycler, &[tx]);
|
||||
verified_sender
|
||||
.send(vec![(packets[0].clone(), vec![1u8])])
|
||||
|
@ -21,7 +21,7 @@ use solana::service::Service;
|
||||
use solana::signature::{read_keypair, GenKeys, Keypair, KeypairUtil};
|
||||
use solana::thin_client::{poll_gossip_for_leader, ThinClient};
|
||||
use solana::timing::{duration_as_ms, duration_as_s};
|
||||
use solana::transaction::Transaction;
|
||||
use solana::transaction::{SystemTransaction, Transaction};
|
||||
use solana::wallet::request_airdrop;
|
||||
use solana::window::default_window;
|
||||
use std::collections::VecDeque;
|
||||
@ -187,9 +187,9 @@ fn generate_txs(
|
||||
.par_iter()
|
||||
.map(|keypair| {
|
||||
if !reclaim {
|
||||
Transaction::new(&id, keypair.pubkey(), 1, *last_id)
|
||||
Transaction::system_new(&id, keypair.pubkey(), 1, *last_id)
|
||||
} else {
|
||||
Transaction::new(keypair, id.pubkey(), 1, *last_id)
|
||||
Transaction::system_new(keypair, id.pubkey(), 1, *last_id)
|
||||
}
|
||||
}).collect();
|
||||
|
||||
|
@ -271,7 +271,7 @@ mod test {
|
||||
use chrono::prelude::{DateTime, NaiveDate, Utc};
|
||||
use hash::Hash;
|
||||
use signature::{GenKeys, Keypair, KeypairUtil, Pubkey};
|
||||
use transaction::Transaction;
|
||||
use transaction::{BudgetTransaction, Transaction};
|
||||
#[test]
|
||||
fn test_serializer() {
|
||||
let mut a = Account::new(0, 512, BudgetState::id());
|
||||
|
@ -22,7 +22,7 @@ use tokio;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::prelude::*;
|
||||
use tokio_codec::{BytesCodec, Decoder};
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
pub const TIME_SLICE: u64 = 60;
|
||||
pub const REQUEST_CAP: u64 = 500_000_000;
|
||||
@ -127,7 +127,7 @@ impl Drone {
|
||||
airdrop_request_amount, client_pubkey
|
||||
);
|
||||
request_amount = airdrop_request_amount;
|
||||
Transaction::new(
|
||||
Transaction::system_new(
|
||||
&self.mint_keypair,
|
||||
client_pubkey,
|
||||
airdrop_request_amount as i64,
|
||||
|
@ -230,7 +230,7 @@ mod tests {
|
||||
use entry::Entry;
|
||||
use hash::hash;
|
||||
use signature::{Keypair, KeypairUtil};
|
||||
use transaction::Transaction;
|
||||
use transaction::{BudgetTransaction, SystemTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_entry_verify() {
|
||||
@ -248,8 +248,8 @@ mod tests {
|
||||
|
||||
// First, verify entries
|
||||
let keypair = Keypair::new();
|
||||
let tx0 = Transaction::new(&keypair, keypair.pubkey(), 0, zero);
|
||||
let tx1 = Transaction::new(&keypair, keypair.pubkey(), 1, zero);
|
||||
let tx0 = Transaction::system_new(&keypair, keypair.pubkey(), 0, zero);
|
||||
let tx1 = Transaction::system_new(&keypair, keypair.pubkey(), 1, zero);
|
||||
let mut e0 = Entry::new(&zero, 0, vec![tx0.clone(), tx1.clone()]);
|
||||
assert!(e0.verify(&zero));
|
||||
|
||||
@ -312,7 +312,7 @@ mod tests {
|
||||
fn test_next_entry_panic() {
|
||||
let zero = Hash::default();
|
||||
let keypair = Keypair::new();
|
||||
let tx = Transaction::new(&keypair, keypair.pubkey(), 0, zero);
|
||||
let tx = Transaction::system_new(&keypair, keypair.pubkey(), 0, zero);
|
||||
next_entry(&zero, 0, vec![tx]);
|
||||
}
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ mod tests {
|
||||
use signature::{Keypair, KeypairUtil};
|
||||
use std;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use transaction::Transaction;
|
||||
use transaction::{BudgetTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_verify_slice() {
|
||||
|
@ -4,7 +4,7 @@ use entry::Entry;
|
||||
use hash::{hash, Hash};
|
||||
use ring::rand::SystemRandom;
|
||||
use signature::{Keypair, KeypairUtil, Pubkey};
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
use untrusted::Input;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -241,7 +241,7 @@ mod tests {
|
||||
use signature::{Keypair, KeypairUtil};
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::sync::Arc;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_rpc_request() {
|
||||
|
@ -106,7 +106,7 @@ mod test {
|
||||
use std::sync::RwLock;
|
||||
use std::thread;
|
||||
use system_program::SystemProgram;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_create_noop() {
|
||||
@ -336,7 +336,7 @@ mod test {
|
||||
let to = Keypair::new();
|
||||
let mut accounts = vec![Account::default(), Account::default()];
|
||||
accounts[0].tokens = 1;
|
||||
let tx = Transaction::new(&from, to.pubkey(), 1, Hash::default());
|
||||
let tx = Transaction::system_new(&from, to.pubkey(), 1, Hash::default());
|
||||
let hash = RwLock::new(HashMap::new());
|
||||
SystemProgram::process_transaction(&tx, &mut accounts, &hash);
|
||||
assert_eq!(accounts[0].tokens, 0);
|
||||
|
@ -22,7 +22,7 @@ use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use timing;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
use influx_db_client as influxdb;
|
||||
use metrics;
|
||||
@ -154,7 +154,7 @@ impl ThinClient {
|
||||
last_id: &Hash,
|
||||
) -> io::Result<Signature> {
|
||||
let now = Instant::now();
|
||||
let tx = Transaction::new(keypair, to, n, *last_id);
|
||||
let tx = Transaction::system_new(keypair, to, n, *last_id);
|
||||
let result = self.transfer_signed(&tx);
|
||||
metrics::submit(
|
||||
influxdb::Point::new("thinclient")
|
||||
@ -530,13 +530,13 @@ mod tests {
|
||||
);
|
||||
let last_id = client.get_last_id();
|
||||
|
||||
let tx = Transaction::new(&alice.keypair(), bob_pubkey, 500, last_id);
|
||||
let tx = Transaction::system_new(&alice.keypair(), bob_pubkey, 500, last_id);
|
||||
|
||||
let _sig = client.transfer_signed(&tx).unwrap();
|
||||
|
||||
let last_id = client.get_last_id();
|
||||
|
||||
let mut tr2 = Transaction::new(&alice.keypair(), bob_pubkey, 501, last_id);
|
||||
let mut tr2 = Transaction::system_new(&alice.keypair(), bob_pubkey, 501, last_id);
|
||||
let mut instruction2 = deserialize(&tr2.userdata).unwrap();
|
||||
if let SystemProgram::Move { ref mut tokens } = instruction2 {
|
||||
*tokens = 502;
|
||||
|
@ -71,225 +71,7 @@ impl Transaction {
|
||||
tx.sign(from_keypair);
|
||||
tx
|
||||
}
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
pub fn budget_new_taxed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
fee: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let payment = Payment {
|
||||
tokens: tokens - fee,
|
||||
to,
|
||||
};
|
||||
let budget = Budget::Pay(payment);
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
pub fn budget_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self {
|
||||
Self::budget_new_taxed(from_keypair, to, tokens, 0, last_id)
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Timestamp. Used for unit-testing.
|
||||
pub fn budget_new_timestamp(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let instruction = Instruction::ApplyTimestamp(dt);
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Signature. Used for unit-testing.
|
||||
pub fn budget_new_signature(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let instruction = Instruction::ApplySignature;
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn budget_new_vote(from_keypair: &Keypair, vote: Vote, last_id: Hash, fee: i64) -> Self {
|
||||
let instruction = Instruction::NewVote(vote);
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(from_keypair, &[], BudgetState::id(), userdata, last_id, fee)
|
||||
}
|
||||
|
||||
/// Create and sign a postdated Transaction. Used for unit-testing.
|
||||
pub fn budget_new_on_date(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
dt_pubkey: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let budget = if let Some(from) = cancelable {
|
||||
Budget::Or(
|
||||
(Condition::Timestamp(dt, dt_pubkey), Payment { tokens, to }),
|
||||
(Condition::Signature(from), Payment { tokens, to: from }),
|
||||
)
|
||||
} else {
|
||||
Budget::After(Condition::Timestamp(dt, dt_pubkey), Payment { tokens, to })
|
||||
};
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
/// Create and sign a multisig Transaction.
|
||||
pub fn budget_new_when_signed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
witness: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let budget = if let Some(from) = cancelable {
|
||||
Budget::Or(
|
||||
(Condition::Signature(witness), Payment { tokens, to }),
|
||||
(Condition::Signature(from), Payment { tokens, to: from }),
|
||||
)
|
||||
} else {
|
||||
Budget::After(Condition::Signature(witness), Payment { tokens, to })
|
||||
};
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction
|
||||
pub fn system_create(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
tokens: i64,
|
||||
space: u64,
|
||||
program_id: Pubkey,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let create = SystemProgram::CreateAccount {
|
||||
tokens, //TODO, the tokens to allocate might need to be higher then 0 in the future
|
||||
space,
|
||||
program_id,
|
||||
};
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction
|
||||
pub fn system_assign(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
program_id: Pubkey,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let create = SystemProgram::Assign { program_id };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction with some defaults
|
||||
pub fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self {
|
||||
Transaction::system_create(from_keypair, to, last_id, tokens, 0, Pubkey::default(), 0)
|
||||
}
|
||||
/// Create and sign new SystemProgram::Move transaction
|
||||
pub fn system_move(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let create = SystemProgram::Move { tokens };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::Load transaction
|
||||
pub fn system_load(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
program_id: Pubkey,
|
||||
name: String,
|
||||
) -> Self {
|
||||
let load = SystemProgram::Load { program_id, name };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[],
|
||||
SystemProgram::id(),
|
||||
serialize(&load).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::Move transaction
|
||||
pub fn new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self {
|
||||
Transaction::system_move(from_keypair, to, tokens, last_id, 0)
|
||||
}
|
||||
/// Get the transaction data to sign.
|
||||
fn get_sign_data(&self) -> Vec<u8> {
|
||||
let mut data = serialize(&(&self.keys)).expect("serialize keys");
|
||||
@ -354,6 +136,304 @@ impl Transaction {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait BudgetTransaction {
|
||||
fn budget_new_taxed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
fee: i64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn budget_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self;
|
||||
|
||||
fn budget_new_timestamp(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn budget_new_signature(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn budget_new_vote(from_keypair: &Keypair, vote: Vote, last_id: Hash, fee: i64) -> Self;
|
||||
|
||||
fn budget_new_on_date(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
dt_pubkey: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn budget_new_when_signed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
witness: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl BudgetTransaction for Transaction {
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
fn budget_new_taxed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
fee: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let payment = Payment {
|
||||
tokens: tokens - fee,
|
||||
to,
|
||||
};
|
||||
let budget = Budget::Pay(payment);
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
fn budget_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self {
|
||||
Self::budget_new_taxed(from_keypair, to, tokens, 0, last_id)
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Timestamp. Used for unit-testing.
|
||||
fn budget_new_timestamp(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let instruction = Instruction::ApplyTimestamp(dt);
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Signature. Used for unit-testing.
|
||||
fn budget_new_signature(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let instruction = Instruction::ApplySignature;
|
||||
let userdata = serialize(&instruction).unwrap();
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
fn budget_new_vote(from_keypair: &Keypair, vote: Vote, last_id: Hash, fee: i64) -> Self {
|
||||
let instruction = Instruction::NewVote(vote);
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(from_keypair, &[], BudgetState::id(), userdata, last_id, fee)
|
||||
}
|
||||
|
||||
/// Create and sign a postdated Transaction. Used for unit-testing.
|
||||
fn budget_new_on_date(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
dt_pubkey: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let budget = if let Some(from) = cancelable {
|
||||
Budget::Or(
|
||||
(Condition::Timestamp(dt, dt_pubkey), Payment { tokens, to }),
|
||||
(Condition::Signature(from), Payment { tokens, to: from }),
|
||||
)
|
||||
} else {
|
||||
Budget::After(Condition::Timestamp(dt, dt_pubkey), Payment { tokens, to })
|
||||
};
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
/// Create and sign a multisig Transaction.
|
||||
fn budget_new_when_signed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
witness: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
let budget = if let Some(from) = cancelable {
|
||||
Budget::Or(
|
||||
(Condition::Signature(witness), Payment { tokens, to }),
|
||||
(Condition::Signature(from), Payment { tokens, to: from }),
|
||||
)
|
||||
} else {
|
||||
Budget::After(Condition::Signature(witness), Payment { tokens, to })
|
||||
};
|
||||
let instruction = Instruction::NewContract(Contract { budget, tokens });
|
||||
let userdata = serialize(&instruction).expect("serialize instruction");
|
||||
Self::new_with_userdata(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
BudgetState::id(),
|
||||
userdata,
|
||||
last_id,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SystemTransaction {
|
||||
fn system_create(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
tokens: i64,
|
||||
space: u64,
|
||||
program_id: Pubkey,
|
||||
fee: i64,
|
||||
) -> Self;
|
||||
|
||||
fn system_assign(from_keypair: &Keypair, last_id: Hash, program_id: Pubkey, fee: i64) -> Self;
|
||||
|
||||
fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self;
|
||||
|
||||
fn system_move(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
) -> Self;
|
||||
|
||||
fn system_load(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
program_id: Pubkey,
|
||||
name: String,
|
||||
) -> Self;
|
||||
}
|
||||
|
||||
impl SystemTransaction for Transaction {
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction
|
||||
fn system_create(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
tokens: i64,
|
||||
space: u64,
|
||||
program_id: Pubkey,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let create = SystemProgram::CreateAccount {
|
||||
tokens, //TODO, the tokens to allocate might need to be higher then 0 in the future
|
||||
space,
|
||||
program_id,
|
||||
};
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction
|
||||
fn system_assign(from_keypair: &Keypair, last_id: Hash, program_id: Pubkey, fee: i64) -> Self {
|
||||
let create = SystemProgram::Assign { program_id };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::CreateAccount transaction with some defaults
|
||||
fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: i64, last_id: Hash) -> Self {
|
||||
Transaction::system_create(from_keypair, to, last_id, tokens, 0, Pubkey::default(), 0)
|
||||
}
|
||||
/// Create and sign new SystemProgram::Move transaction
|
||||
fn system_move(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: i64,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
) -> Self {
|
||||
let create = SystemProgram::Move { tokens };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[to],
|
||||
SystemProgram::id(),
|
||||
serialize(&create).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemProgram::Load transaction
|
||||
fn system_load(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
fee: i64,
|
||||
program_id: Pubkey,
|
||||
name: String,
|
||||
) -> Self {
|
||||
let load = SystemProgram::Load { program_id, name };
|
||||
Transaction::new_with_userdata(
|
||||
from_keypair,
|
||||
&[],
|
||||
SystemProgram::id(),
|
||||
serialize(&load).unwrap(),
|
||||
last_id,
|
||||
fee,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_tx() -> Transaction {
|
||||
let keypair1 = Keypair::new();
|
||||
let pubkey1 = keypair1.pubkey();
|
||||
|
@ -166,7 +166,7 @@ pub mod tests {
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
use streamer;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
use tvu::Tvu;
|
||||
use window::{self, SharedWindow};
|
||||
|
||||
|
@ -16,7 +16,7 @@ use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use streamer::BlobSender;
|
||||
use timing;
|
||||
use transaction::Transaction;
|
||||
use transaction::{BudgetTransaction, Transaction};
|
||||
|
||||
pub const VOTE_TIMEOUT_MS: u64 = 1000;
|
||||
|
||||
@ -177,7 +177,7 @@ pub mod tests {
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use transaction::Transaction;
|
||||
use transaction::{SystemTransaction, Transaction};
|
||||
|
||||
#[test]
|
||||
fn test_send_leader_vote() {
|
||||
|
@ -22,7 +22,7 @@ use std::path::Path;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use std::{error, fmt, mem};
|
||||
use transaction::Transaction;
|
||||
use transaction::{BudgetTransaction, SystemTransaction, Transaction};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum WalletCommand {
|
||||
@ -367,7 +367,7 @@ pub fn process_command(config: &WalletConfig) -> Result<String, Box<error::Error
|
||||
let last_id = get_last_id(&config)?;
|
||||
|
||||
if timestamp == None && *witnesses == None {
|
||||
let tx = Transaction::new(&config.id, to, tokens, last_id);
|
||||
let tx = Transaction::system_new(&config.id, to, tokens, last_id);
|
||||
let signature_str = serialize_and_send_tx(&config, &tx)?;
|
||||
Ok(signature_str.to_string())
|
||||
} else if *witnesses == None {
|
||||
|
Reference in New Issue
Block a user