Replace transaction traits with structs
Also: * SystemTransaction::new -> new_account * SystemTransaction::new_create -> new_program_account
This commit is contained in:
@ -13,68 +13,17 @@ use crate::transaction::{self, Transaction};
|
||||
use bincode::deserialize;
|
||||
use chrono::prelude::*;
|
||||
|
||||
pub trait BudgetTransaction {
|
||||
fn budget_new_taxed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: u64,
|
||||
fee: u64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
pub struct BudgetTransaction {}
|
||||
|
||||
fn budget_new(from_keypair: &Keypair, to: Pubkey, tokens: u64, 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_on_date(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
dt_pubkey: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn budget_new_when_signed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
witness: Pubkey,
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
) -> Self;
|
||||
|
||||
fn instruction(&self, program_index: usize) -> Option<Instruction>;
|
||||
fn system_instruction(&self, program_index: usize) -> Option<SystemInstruction>;
|
||||
|
||||
fn verify_plan(&self) -> bool;
|
||||
}
|
||||
|
||||
impl BudgetTransaction for Transaction {
|
||||
impl BudgetTransaction {
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
fn budget_new_taxed(
|
||||
pub fn new_payment(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: u64,
|
||||
fee: u64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
fee: u64,
|
||||
) -> Transaction {
|
||||
let contract = Keypair::new().pubkey();
|
||||
let keys = vec![from_keypair.pubkey(), contract];
|
||||
|
||||
@ -93,7 +42,7 @@ impl BudgetTransaction for Transaction {
|
||||
transaction::Instruction::new(1, &budget_instruction, vec![1]),
|
||||
];
|
||||
|
||||
Self::new_with_instructions(
|
||||
Transaction::new_with_instructions(
|
||||
&[from_keypair],
|
||||
&keys,
|
||||
last_id,
|
||||
@ -104,20 +53,21 @@ impl BudgetTransaction for Transaction {
|
||||
}
|
||||
|
||||
/// Create and sign a new Transaction. Used for unit-testing.
|
||||
fn budget_new(from_keypair: &Keypair, to: Pubkey, tokens: u64, last_id: Hash) -> Self {
|
||||
Self::budget_new_taxed(from_keypair, to, tokens, 0, last_id)
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(from_keypair: &Keypair, to: Pubkey, tokens: u64, last_id: Hash) -> Transaction {
|
||||
Self::new_payment(from_keypair, to, tokens, last_id, 0)
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Timestamp. Used for unit-testing.
|
||||
fn budget_new_timestamp(
|
||||
pub fn new_timestamp(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
dt: DateTime<Utc>,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let instruction = Instruction::ApplyTimestamp(dt);
|
||||
Self::new(
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
budget_program::id(),
|
||||
@ -128,14 +78,14 @@ impl BudgetTransaction for Transaction {
|
||||
}
|
||||
|
||||
/// Create and sign a new Witness Signature. Used for unit-testing.
|
||||
fn budget_new_signature(
|
||||
pub fn new_signature(
|
||||
from_keypair: &Keypair,
|
||||
contract: Pubkey,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let instruction = Instruction::ApplySignature;
|
||||
Self::new(
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
&[contract, to],
|
||||
budget_program::id(),
|
||||
@ -146,7 +96,7 @@ impl BudgetTransaction for Transaction {
|
||||
}
|
||||
|
||||
/// Create and sign a postdated Transaction. Used for unit-testing.
|
||||
fn budget_new_on_date(
|
||||
pub fn new_on_date(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
@ -155,7 +105,7 @@ impl BudgetTransaction for Transaction {
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let expr = if let Some(from) = cancelable {
|
||||
BudgetExpr::Or(
|
||||
(
|
||||
@ -174,7 +124,7 @@ impl BudgetTransaction for Transaction {
|
||||
)
|
||||
};
|
||||
let instruction = Instruction::NewBudget(expr);
|
||||
Self::new(
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
budget_program::id(),
|
||||
@ -184,7 +134,7 @@ impl BudgetTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
/// Create and sign a multisig Transaction.
|
||||
fn budget_new_when_signed(
|
||||
pub fn new_when_signed(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
contract: Pubkey,
|
||||
@ -192,7 +142,7 @@ impl BudgetTransaction for Transaction {
|
||||
cancelable: Option<Pubkey>,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let expr = if let Some(from) = cancelable {
|
||||
BudgetExpr::Or(
|
||||
(
|
||||
@ -211,7 +161,7 @@ impl BudgetTransaction for Transaction {
|
||||
)
|
||||
};
|
||||
let instruction = Instruction::NewBudget(expr);
|
||||
Self::new(
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
&[contract],
|
||||
budget_program::id(),
|
||||
@ -221,19 +171,19 @@ impl BudgetTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn instruction(&self, instruction_index: usize) -> Option<Instruction> {
|
||||
deserialize(&self.userdata(instruction_index)).ok()
|
||||
pub fn system_instruction(tx: &Transaction, index: usize) -> Option<SystemInstruction> {
|
||||
deserialize(&tx.userdata(index)).ok()
|
||||
}
|
||||
|
||||
fn system_instruction(&self, instruction_index: usize) -> Option<SystemInstruction> {
|
||||
deserialize(&self.userdata(instruction_index)).ok()
|
||||
pub fn instruction(tx: &Transaction, index: usize) -> Option<Instruction> {
|
||||
deserialize(&tx.userdata(index)).ok()
|
||||
}
|
||||
|
||||
/// Verify only the payment plan.
|
||||
fn verify_plan(&self) -> bool {
|
||||
if let Some(SystemInstruction::Move { tokens }) = self.system_instruction(0) {
|
||||
if let Some(Instruction::NewBudget(expr)) = self.instruction(1) {
|
||||
if !(self.fee <= tokens && expr.verify(tokens - self.fee)) {
|
||||
pub fn verify_plan(tx: &Transaction) -> bool {
|
||||
if let Some(SystemInstruction::Move { tokens }) = Self::system_instruction(tx, 0) {
|
||||
if let Some(Instruction::NewBudget(expr)) = BudgetTransaction::instruction(&tx, 1) {
|
||||
if !(tx.fee <= tokens && expr.verify(tokens - tx.fee)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -251,26 +201,27 @@ mod tests {
|
||||
fn test_claim() {
|
||||
let keypair = Keypair::new();
|
||||
let zero = Hash::default();
|
||||
let tx0 = Transaction::budget_new(&keypair, keypair.pubkey(), 42, zero);
|
||||
assert!(tx0.verify_plan());
|
||||
let tx0 = BudgetTransaction::new(&keypair, keypair.pubkey(), 42, zero);
|
||||
assert!(BudgetTransaction::verify_plan(&tx0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transfer() {
|
||||
fn test_payment() {
|
||||
let zero = Hash::default();
|
||||
let keypair0 = Keypair::new();
|
||||
let keypair1 = Keypair::new();
|
||||
let pubkey1 = keypair1.pubkey();
|
||||
let tx0 = Transaction::budget_new(&keypair0, pubkey1, 42, zero);
|
||||
assert!(tx0.verify_plan());
|
||||
let tx0 = BudgetTransaction::new(&keypair0, pubkey1, 42, zero);
|
||||
assert!(BudgetTransaction::verify_plan(&tx0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transfer_with_fee() {
|
||||
fn test_payment_with_fee() {
|
||||
let zero = Hash::default();
|
||||
let keypair0 = Keypair::new();
|
||||
let pubkey1 = Keypair::new().pubkey();
|
||||
assert!(Transaction::budget_new_taxed(&keypair0, pubkey1, 1, 1, zero).verify_plan());
|
||||
let tx0 = BudgetTransaction::new_payment(&keypair0, pubkey1, 1, zero, 1);
|
||||
assert!(BudgetTransaction::verify_plan(&tx0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -299,11 +250,11 @@ mod tests {
|
||||
let zero = Hash::default();
|
||||
let keypair = Keypair::new();
|
||||
let pubkey = keypair.pubkey();
|
||||
let mut tx = Transaction::budget_new(&keypair, pubkey, 42, zero);
|
||||
let mut system_instruction = tx.system_instruction(0).unwrap();
|
||||
let mut tx = BudgetTransaction::new(&keypair, pubkey, 42, zero);
|
||||
let mut system_instruction = BudgetTransaction::system_instruction(&tx, 0).unwrap();
|
||||
if let SystemInstruction::Move { ref mut tokens } = system_instruction {
|
||||
*tokens = 1_000_000; // <-- attack, part 1!
|
||||
let mut instruction = tx.instruction(1).unwrap();
|
||||
let mut instruction = BudgetTransaction::instruction(&tx, 1).unwrap();
|
||||
if let Instruction::NewBudget(ref mut expr) = instruction {
|
||||
if let BudgetExpr::Pay(ref mut payment) = expr {
|
||||
payment.tokens = *tokens; // <-- attack, part 2!
|
||||
@ -312,7 +263,7 @@ mod tests {
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
}
|
||||
tx.instructions[0].userdata = serialize(&system_instruction).unwrap();
|
||||
assert!(tx.verify_plan());
|
||||
assert!(BudgetTransaction::verify_plan(&tx));
|
||||
assert!(!tx.verify_signature());
|
||||
}
|
||||
|
||||
@ -323,15 +274,15 @@ mod tests {
|
||||
let thief_keypair = Keypair::new();
|
||||
let pubkey1 = keypair1.pubkey();
|
||||
let zero = Hash::default();
|
||||
let mut tx = Transaction::budget_new(&keypair0, pubkey1, 42, zero);
|
||||
let mut instruction = tx.instruction(1);
|
||||
let mut tx = BudgetTransaction::new(&keypair0, pubkey1, 42, zero);
|
||||
let mut instruction = BudgetTransaction::instruction(&tx, 1);
|
||||
if let Some(Instruction::NewBudget(ref mut expr)) = instruction {
|
||||
if let BudgetExpr::Pay(ref mut payment) = expr {
|
||||
payment.to = thief_keypair.pubkey(); // <-- attack!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
assert!(tx.verify_plan());
|
||||
assert!(BudgetTransaction::verify_plan(&tx));
|
||||
assert!(!tx.verify_signature());
|
||||
}
|
||||
|
||||
@ -340,24 +291,24 @@ mod tests {
|
||||
let keypair0 = Keypair::new();
|
||||
let keypair1 = Keypair::new();
|
||||
let zero = Hash::default();
|
||||
let mut tx = Transaction::budget_new(&keypair0, keypair1.pubkey(), 1, zero);
|
||||
let mut instruction = tx.instruction(1).unwrap();
|
||||
let mut tx = BudgetTransaction::new(&keypair0, keypair1.pubkey(), 1, zero);
|
||||
let mut instruction = BudgetTransaction::instruction(&tx, 1).unwrap();
|
||||
if let Instruction::NewBudget(ref mut expr) = instruction {
|
||||
if let BudgetExpr::Pay(ref mut payment) = expr {
|
||||
payment.tokens = 2; // <-- attack!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
assert!(!tx.verify_plan());
|
||||
assert!(!BudgetTransaction::verify_plan(&tx));
|
||||
|
||||
// Also, ensure all branchs of the plan spend all tokens
|
||||
let mut instruction = tx.instruction(1).unwrap();
|
||||
let mut instruction = BudgetTransaction::instruction(&tx, 1).unwrap();
|
||||
if let Instruction::NewBudget(ref mut expr) = instruction {
|
||||
if let BudgetExpr::Pay(ref mut payment) = expr {
|
||||
payment.tokens = 0; // <-- whoops!
|
||||
}
|
||||
}
|
||||
tx.instructions[1].userdata = serialize(&instruction).unwrap();
|
||||
assert!(!tx.verify_plan());
|
||||
assert!(!BudgetTransaction::verify_plan(&tx));
|
||||
}
|
||||
}
|
||||
|
@ -6,33 +6,27 @@ use crate::pubkey::Pubkey;
|
||||
use crate::signature::Keypair;
|
||||
use crate::transaction::Transaction;
|
||||
|
||||
pub trait LoaderTransaction {
|
||||
fn loader_write(
|
||||
pub struct LoaderTransaction {}
|
||||
|
||||
impl LoaderTransaction {
|
||||
pub fn new_write(
|
||||
from_keypair: &Keypair,
|
||||
loader: Pubkey,
|
||||
offset: u32,
|
||||
bytes: Vec<u8>,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
|
||||
fn loader_finalize(from_keypair: &Keypair, loader: Pubkey, last_id: Hash, fee: u64) -> Self;
|
||||
}
|
||||
|
||||
impl LoaderTransaction for Transaction {
|
||||
fn loader_write(
|
||||
from_keypair: &Keypair,
|
||||
loader: Pubkey,
|
||||
offset: u32,
|
||||
bytes: Vec<u8>,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let instruction = LoaderInstruction::Write { offset, bytes };
|
||||
Transaction::new(from_keypair, &[], loader, &instruction, last_id, fee)
|
||||
}
|
||||
|
||||
fn loader_finalize(from_keypair: &Keypair, loader: Pubkey, last_id: Hash, fee: u64) -> Self {
|
||||
pub fn new_finalize(
|
||||
from_keypair: &Keypair,
|
||||
loader: Pubkey,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Transaction {
|
||||
let instruction = LoaderInstruction::Finalize;
|
||||
Transaction::new(from_keypair, &[], loader, &instruction, last_id, fee)
|
||||
}
|
||||
|
@ -83,40 +83,16 @@ pub fn system_id() -> Pubkey {
|
||||
Pubkey::new(&STORAGE_SYSTEM_ACCOUNT_ID)
|
||||
}
|
||||
|
||||
pub trait StorageTransaction {
|
||||
fn storage_new_mining_proof(
|
||||
pub struct StorageTransaction {}
|
||||
|
||||
impl StorageTransaction {
|
||||
pub fn new_mining_proof(
|
||||
from_keypair: &Keypair,
|
||||
sha_state: Hash,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
signature: Signature,
|
||||
) -> Self;
|
||||
|
||||
fn storage_new_advertise_last_id(
|
||||
from_keypair: &Keypair,
|
||||
storage_last_id: Hash,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
) -> Self;
|
||||
|
||||
fn storage_new_proof_validation(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
proof_mask: Vec<ProofStatus>,
|
||||
) -> Self;
|
||||
|
||||
fn storage_new_reward_claim(from_keypair: &Keypair, last_id: Hash, entry_height: u64) -> Self;
|
||||
}
|
||||
|
||||
impl StorageTransaction for Transaction {
|
||||
fn storage_new_mining_proof(
|
||||
from_keypair: &Keypair,
|
||||
sha_state: Hash,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
signature: Signature,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let program = StorageProgram::SubmitMiningProof {
|
||||
sha_state,
|
||||
entry_height,
|
||||
@ -132,12 +108,12 @@ impl StorageTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn storage_new_advertise_last_id(
|
||||
pub fn new_advertise_last_id(
|
||||
from_keypair: &Keypair,
|
||||
storage_id: Hash,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let program = StorageProgram::AdvertiseStorageLastId {
|
||||
id: storage_id,
|
||||
entry_height,
|
||||
@ -152,12 +128,12 @@ impl StorageTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn storage_new_proof_validation(
|
||||
pub fn new_proof_validation(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
proof_mask: Vec<ProofStatus>,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let program = StorageProgram::ProofValidation {
|
||||
entry_height,
|
||||
proof_mask,
|
||||
@ -172,7 +148,11 @@ impl StorageTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn storage_new_reward_claim(from_keypair: &Keypair, last_id: Hash, entry_height: u64) -> Self {
|
||||
pub fn new_reward_claim(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
entry_height: u64,
|
||||
) -> Transaction {
|
||||
let program = StorageProgram::ClaimStorageReward { entry_height };
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
|
@ -7,42 +7,11 @@ use crate::system_instruction::SystemInstruction;
|
||||
use crate::system_program;
|
||||
use crate::transaction::{Instruction, Transaction};
|
||||
|
||||
pub trait SystemTransaction {
|
||||
fn system_create(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
tokens: u64,
|
||||
space: u64,
|
||||
program_id: Pubkey,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
pub struct SystemTransaction {}
|
||||
|
||||
fn system_assign(from_keypair: &Keypair, last_id: Hash, program_id: Pubkey, fee: u64) -> Self;
|
||||
|
||||
fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: u64, last_id: Hash) -> Self;
|
||||
|
||||
fn system_move(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
|
||||
fn system_move_many(
|
||||
from_keypair: &Keypair,
|
||||
moves: &[(Pubkey, u64)],
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
|
||||
fn system_spawn(from_keypair: &Keypair, last_id: Hash, fee: u64) -> Self;
|
||||
}
|
||||
|
||||
impl SystemTransaction for Transaction {
|
||||
impl SystemTransaction {
|
||||
/// Create and sign new SystemInstruction::CreateAccount transaction
|
||||
fn system_create(
|
||||
pub fn new_program_account(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
last_id: Hash,
|
||||
@ -50,7 +19,7 @@ impl SystemTransaction for Transaction {
|
||||
space: u64,
|
||||
program_id: Pubkey,
|
||||
fee: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let create = SystemInstruction::CreateAccount {
|
||||
tokens, //TODO, the tokens to allocate might need to be higher then 0 in the future
|
||||
space,
|
||||
@ -65,8 +34,25 @@ impl SystemTransaction for Transaction {
|
||||
fee,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create and sign a transaction to create a system account
|
||||
pub fn new_account(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Transaction {
|
||||
let program_id = system_program::id();
|
||||
Self::new_program_account(from_keypair, to, last_id, tokens, 0, program_id, fee)
|
||||
}
|
||||
/// Create and sign new SystemInstruction::Assign transaction
|
||||
fn system_assign(from_keypair: &Keypair, last_id: Hash, program_id: Pubkey, fee: u64) -> Self {
|
||||
pub fn new_assign(
|
||||
from_keypair: &Keypair,
|
||||
last_id: Hash,
|
||||
program_id: Pubkey,
|
||||
fee: u64,
|
||||
) -> Transaction {
|
||||
let assign = SystemInstruction::Assign { program_id };
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
@ -77,18 +63,14 @@ impl SystemTransaction for Transaction {
|
||||
fee,
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemInstruction::CreateAccount transaction with some defaults
|
||||
fn system_new(from_keypair: &Keypair, to: Pubkey, tokens: u64, last_id: Hash) -> Self {
|
||||
Transaction::system_create(from_keypair, to, last_id, tokens, 0, Pubkey::default(), 0)
|
||||
}
|
||||
/// Create and sign new SystemInstruction::Move transaction
|
||||
fn system_move(
|
||||
pub fn new_move(
|
||||
from_keypair: &Keypair,
|
||||
to: Pubkey,
|
||||
tokens: u64,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let move_tokens = SystemInstruction::Move { tokens };
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
@ -100,7 +82,12 @@ impl SystemTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemInstruction::Move transaction to many destinations
|
||||
fn system_move_many(from: &Keypair, moves: &[(Pubkey, u64)], last_id: Hash, fee: u64) -> Self {
|
||||
pub fn new_move_many(
|
||||
from: &Keypair,
|
||||
moves: &[(Pubkey, u64)],
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Transaction {
|
||||
let instructions: Vec<_> = moves
|
||||
.iter()
|
||||
.enumerate()
|
||||
@ -121,7 +108,7 @@ impl SystemTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
/// Create and sign new SystemInstruction::Spawn transaction
|
||||
fn system_spawn(from_keypair: &Keypair, last_id: Hash, fee: u64) -> Self {
|
||||
pub fn new_spawn(from_keypair: &Keypair, last_id: Hash, fee: u64) -> Transaction {
|
||||
let spawn = SystemInstruction::Spawn;
|
||||
Transaction::new(
|
||||
from_keypair,
|
||||
@ -146,7 +133,7 @@ mod tests {
|
||||
let t2 = Keypair::new();
|
||||
let moves = vec![(t1.pubkey(), 1), (t2.pubkey(), 2)];
|
||||
|
||||
let tx = Transaction::system_move_many(&from, &moves, Default::default(), 0);
|
||||
let tx = SystemTransaction::new_move_many(&from, &moves, Default::default(), 0);
|
||||
assert_eq!(tx.account_keys[0], from.pubkey());
|
||||
assert_eq!(tx.account_keys[1], t1.pubkey());
|
||||
assert_eq!(tx.account_keys[2], t2.pubkey());
|
||||
|
@ -174,6 +174,7 @@ impl Transaction {
|
||||
pub fn userdata(&self, instruction_index: usize) -> &[u8] {
|
||||
&self.instructions[instruction_index].userdata
|
||||
}
|
||||
|
||||
fn key_index(&self, instruction_index: usize, accounts_index: usize) -> Option<usize> {
|
||||
self.instructions
|
||||
.get(instruction_index)
|
||||
|
@ -9,31 +9,15 @@ use crate::transaction::{Instruction, Transaction};
|
||||
use crate::vote_program::{self, Vote, VoteInstruction};
|
||||
use bincode::deserialize;
|
||||
|
||||
pub trait VoteTransaction {
|
||||
fn vote_new<T: KeypairUtil>(
|
||||
pub struct VoteTransaction {}
|
||||
|
||||
impl VoteTransaction {
|
||||
pub fn new_vote<T: KeypairUtil>(
|
||||
vote_account: &T,
|
||||
tick_height: u64,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
fn vote_account_new(
|
||||
validator_id: &Keypair,
|
||||
vote_account_id: Pubkey,
|
||||
last_id: Hash,
|
||||
num_tokens: u64,
|
||||
fee: u64,
|
||||
) -> Self;
|
||||
|
||||
fn get_votes(&self) -> Vec<(Pubkey, Vote, Hash)>;
|
||||
}
|
||||
|
||||
impl VoteTransaction for Transaction {
|
||||
fn vote_new<T: KeypairUtil>(
|
||||
vote_account: &T,
|
||||
tick_height: u64,
|
||||
last_id: Hash,
|
||||
fee: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
let vote = Vote { tick_height };
|
||||
let instruction = VoteInstruction::NewVote(vote);
|
||||
Transaction::new(
|
||||
@ -46,13 +30,13 @@ impl VoteTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn vote_account_new(
|
||||
pub fn new_account(
|
||||
validator_id: &Keypair,
|
||||
vote_account_id: Pubkey,
|
||||
last_id: Hash,
|
||||
num_tokens: u64,
|
||||
fee: u64,
|
||||
) -> Self {
|
||||
) -> Transaction {
|
||||
Transaction::new_with_instructions(
|
||||
&[validator_id],
|
||||
&[vote_account_id],
|
||||
@ -74,13 +58,13 @@ impl VoteTransaction for Transaction {
|
||||
)
|
||||
}
|
||||
|
||||
fn get_votes(&self) -> Vec<(Pubkey, Vote, Hash)> {
|
||||
pub fn get_votes(tx: &Transaction) -> Vec<(Pubkey, Vote, Hash)> {
|
||||
let mut votes = vec![];
|
||||
for i in 0..self.instructions.len() {
|
||||
let tx_program_id = self.program_id(i);
|
||||
for i in 0..tx.instructions.len() {
|
||||
let tx_program_id = tx.program_id(i);
|
||||
if vote_program::check_id(&tx_program_id) {
|
||||
if let Ok(Some(VoteInstruction::NewVote(vote))) = deserialize(&self.userdata(i)) {
|
||||
votes.push((self.account_keys[0], vote, self.last_id))
|
||||
if let Ok(Some(VoteInstruction::NewVote(vote))) = deserialize(&tx.userdata(i)) {
|
||||
votes.push((tx.account_keys[0], vote, tx.last_id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user