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

Add fee to Transaction #281

Merged
merged 6 commits into from
May 30, 2018
Merged
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "solana"
description = "The World's Fastest Blockchain"
version = "0.6.0-alpha"
version = "0.6.0-beta"
documentation = "https://docs.rs/solana"
homepage = "http://solana.com/"
repository = "https://github.com/solana-labs/solana"
Expand Down
69 changes: 48 additions & 21 deletions src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use signature::{KeyPair, PublicKey, Signature};
use std::collections::hash_map::Entry::Occupied;
use std::collections::{HashMap, HashSet, VecDeque};
use std::result;
use std::sync::RwLock;
use std::sync::atomic::{AtomicIsize, AtomicUsize, Ordering};
use std::sync::RwLock;
use transaction::{Instruction, Plan, Transaction};

pub const MAX_ENTRY_IDS: usize = 1024 * 4;
Expand All @@ -25,7 +25,9 @@ pub const MAX_ENTRY_IDS: usize = 1024 * 4;
pub enum BankError {
AccountNotFound(PublicKey),
InsufficientFunds(PublicKey),
InvalidTransferSignature(Signature),
DuplicateSiganture(Signature),
LastIdNotFound(Hash),
NegativeTokens,
}

pub type Result<T> = result::Result<T, BankError>;
Expand Down Expand Up @@ -94,42 +96,41 @@ impl Bank {
last_item.0
}

fn reserve_signature(signatures: &RwLock<HashSet<Signature>>, sig: &Signature) -> bool {
fn reserve_signature(signatures: &RwLock<HashSet<Signature>>, sig: &Signature) -> Result<()> {
if signatures
.read()
.expect("'signatures' read lock")
.contains(sig)
{
return false;
return Err(BankError::DuplicateSiganture(*sig));
}
signatures
.write()
.expect("'signatures' write lock")
.insert(*sig);
true
Ok(())
}

fn forget_signature(signatures: &RwLock<HashSet<Signature>>, sig: &Signature) -> bool {
fn forget_signature(signatures: &RwLock<HashSet<Signature>>, sig: &Signature) {
signatures
.write()
.expect("'signatures' write lock in forget_signature")
.remove(sig)
.remove(sig);
}

fn forget_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) -> bool {
fn forget_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) {
if let Some(entry) = self.last_ids
.read()
.expect("'last_ids' read lock in forget_signature_with_last_id")
.iter()
.rev()
.find(|x| x.0 == *last_id)
{
return Self::forget_signature(&entry.1, sig);
Self::forget_signature(&entry.1, sig);
}
return false;
}

fn reserve_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) -> bool {
fn reserve_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) -> Result<()> {
if let Some(entry) = self.last_ids
.read()
.expect("'last_ids' read lock in reserve_signature_with_last_id")
Expand All @@ -139,7 +140,7 @@ impl Bank {
{
return Self::reserve_signature(&entry.1, sig);
}
false
Err(BankError::LastIdNotFound(*last_id))
}

/// Tell the bank which Entry IDs exist on the ledger. This function
Expand All @@ -161,6 +162,9 @@ impl Bank {
fn apply_debits(&self, tx: &Transaction) -> Result<()> {
if let Instruction::NewContract(contract) = &tx.instruction {
trace!("Transaction {}", contract.tokens);
if contract.tokens < 0 {
return Err(BankError::NegativeTokens);
}
}
let bals = self.balances
.read()
Expand All @@ -171,9 +175,7 @@ impl Bank {
return Err(BankError::AccountNotFound(tx.from));
}

if !self.reserve_signature_with_last_id(&tx.sig, &tx.last_id) {
return Err(BankError::InvalidTransferSignature(tx.sig));
}
self.reserve_signature_with_last_id(&tx.sig, &tx.last_id)?;

loop {
let result = if let Instruction::NewContract(contract) = &tx.instruction {
Expand Down Expand Up @@ -403,6 +405,18 @@ mod tests {
assert_eq!(bank.transaction_count(), 2);
}

#[test]
fn test_invalid_tokens() {
let mint = Mint::new(1);
let pubkey = KeyPair::new().pubkey();
let bank = Bank::new(&mint);
assert_eq!(
bank.transfer(-1, &mint.keypair(), pubkey, mint.last_id()),
Err(BankError::NegativeTokens)
);
assert_eq!(bank.transaction_count(), 0);
}

#[test]
fn test_account_not_found() {
let mint = Mint::new(1);
Expand Down Expand Up @@ -528,18 +542,28 @@ mod tests {
let mint = Mint::new(1);
let bank = Bank::new(&mint);
let sig = Signature::default();
assert!(bank.reserve_signature_with_last_id(&sig, &mint.last_id()));
assert!(!bank.reserve_signature_with_last_id(&sig, &mint.last_id()));
assert!(
bank.reserve_signature_with_last_id(&sig, &mint.last_id())
.is_ok()
);
assert_eq!(
bank.reserve_signature_with_last_id(&sig, &mint.last_id()),
Err(BankError::DuplicateSiganture(sig))
);
}

#[test]
fn test_forget_signature() {
let mint = Mint::new(1);
let bank = Bank::new(&mint);
let sig = Signature::default();
bank.reserve_signature_with_last_id(&sig, &mint.last_id());
assert!(bank.forget_signature_with_last_id(&sig, &mint.last_id()));
assert!(!bank.forget_signature_with_last_id(&sig, &mint.last_id()));
bank.reserve_signature_with_last_id(&sig, &mint.last_id())
.unwrap();
bank.forget_signature_with_last_id(&sig, &mint.last_id());
assert!(
bank.reserve_signature_with_last_id(&sig, &mint.last_id())
.is_ok()
);
}

#[test]
Expand All @@ -552,7 +576,10 @@ mod tests {
bank.register_entry_id(&last_id);
}
// Assert we're no longer able to use the oldest entry ID.
assert!(!bank.reserve_signature_with_last_id(&sig, &mint.last_id()));
assert_eq!(
bank.reserve_signature_with_last_id(&sig, &mint.last_id()),
Err(BankError::LastIdNotFound(mint.last_id()))
);
}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions src/banking_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use rayon::prelude::*;
use record_stage::Signal;
use result::Result;
use std::net::SocketAddr;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Arc;
use std::thread::{spawn, JoinHandle};
use std::time::Duration;
use std::time::Instant;
Expand Down Expand Up @@ -255,8 +255,8 @@ mod bench {
use record_stage::Signal;
use signature::{KeyPair, KeyPairUtil};
use std::iter;
use std::sync::Arc;
use std::sync::mpsc::channel;
use std::sync::Arc;
use transaction::Transaction;

#[bench]
Expand Down
2 changes: 1 addition & 1 deletion src/bin/client-demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use std::net::{IpAddr, SocketAddr, UdpSocket};
use std::process::exit;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock};
use std::thread::JoinHandle;
use std::thread::sleep;
use std::thread::JoinHandle;
use std::time::Duration;
use std::time::Instant;

Expand Down
2 changes: 1 addition & 1 deletion src/bin/fullnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use std::fs::File;
use std::io::{stdin, Read};
use std::net::{IpAddr, SocketAddr, UdpSocket};
use std::process::exit;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
//use std::time::Duration;

fn print_usage(program: &str, opts: Options) {
Expand Down
2 changes: 1 addition & 1 deletion src/entry_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use packet;
use result::Result;
use serde_json;
use std::collections::VecDeque;
use std::io::Write;
use std::io::sink;
use std::io::Write;
use std::sync::mpsc::Receiver;
use std::sync::{Arc, Mutex};
use std::time::Duration;
Expand Down
2 changes: 1 addition & 1 deletion src/fetch_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

use packet;
use std::net::UdpSocket;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread::JoinHandle;
use streamer;

Expand Down
2 changes: 1 addition & 1 deletion src/hash.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! The `hash` module provides functions for creating SHA-256 hashes.

use generic_array::GenericArray;
use generic_array::typenum::U32;
use generic_array::GenericArray;
use sha2::{Digest, Sha256};

pub type Hash = GenericArray<u8, U32>;
Expand Down
2 changes: 1 addition & 1 deletion src/replicate_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use bank::Bank;
use ledger;
use packet;
use result::Result;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::{spawn, JoinHandle};
use std::time::Duration;
use streamer;
Expand Down
2 changes: 1 addition & 1 deletion src/request_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use request::Request;
use request_processor::RequestProcessor;
use result::Result;
use std::net::SocketAddr;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{channel, Receiver};
use std::sync::Arc;
use std::thread::{spawn, JoinHandle};
use std::time::Instant;
use streamer;
Expand Down
2 changes: 1 addition & 1 deletion src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ mod tests {
use std::io::Write;
use std::net::SocketAddr;
use std::panic;
use std::sync::mpsc::channel;
use std::sync::mpsc::RecvError;
use std::sync::mpsc::RecvTimeoutError;
use std::sync::mpsc::channel;
use std::thread;

fn addr_parse_error() -> Result<SocketAddr> {
Expand Down
2 changes: 1 addition & 1 deletion src/rpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use packet;
use request_processor::RequestProcessor;
use request_stage::RequestStage;
use std::net::UdpSocket;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::channel;
use std::sync::Arc;
use std::thread::JoinHandle;
use streamer;

Expand Down
2 changes: 1 addition & 1 deletion src/signature.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! The `signature` module provides functionality for public, and private keys.

use generic_array::GenericArray;
use generic_array::typenum::{U32, U64};
use generic_array::GenericArray;
use rand::{ChaChaRng, Rng, SeedableRng};
use rayon::prelude::*;
use ring::error::Unspecified;
Expand Down
2 changes: 1 addition & 1 deletion src/streamer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,8 @@ mod test {
use std::sync::{Arc, RwLock};
use std::thread::sleep;
use std::time::Duration;
use streamer::{default_window, BlobReceiver, PacketReceiver};
use streamer::{blob_receiver, receiver, responder, retransmitter, window};
use streamer::{default_window, BlobReceiver, PacketReceiver};

fn get_msgs(r: PacketReceiver, num: &mut usize) {
for _t in 0..5 {
Expand Down
2 changes: 1 addition & 1 deletion src/thin_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ mod tests {
use server::Server;
use signature::{KeyPair, KeyPairUtil};
use std::io::sink;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;
use transaction::{Instruction, Plan};
Expand Down
Loading