fmt
This commit is contained in:
parent
46059a37eb
commit
f5eedd2d19
53
src/bank.rs
53
src/bank.rs
|
@ -70,7 +70,8 @@ impl Bank {
|
||||||
/// Commit funds to the 'to' party.
|
/// Commit funds to the 'to' party.
|
||||||
fn apply_payment(&self, payment: &Payment) {
|
fn apply_payment(&self, payment: &Payment) {
|
||||||
// First we check balances with a read lock to maximize potential parallelization.
|
// First we check balances with a read lock to maximize potential parallelization.
|
||||||
if self.balances
|
if self
|
||||||
|
.balances
|
||||||
.read()
|
.read()
|
||||||
.expect("'balances' read lock in apply_payment")
|
.expect("'balances' read lock in apply_payment")
|
||||||
.contains_key(&payment.to)
|
.contains_key(&payment.to)
|
||||||
|
@ -119,7 +120,8 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forget_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) {
|
fn forget_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) {
|
||||||
if let Some(entry) = self.last_ids
|
if let Some(entry) = self
|
||||||
|
.last_ids
|
||||||
.read()
|
.read()
|
||||||
.expect("'last_ids' read lock in forget_signature_with_last_id")
|
.expect("'last_ids' read lock in forget_signature_with_last_id")
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -131,7 +133,8 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reserve_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) -> Result<()> {
|
fn reserve_signature_with_last_id(&self, sig: &Signature, last_id: &Hash) -> Result<()> {
|
||||||
if let Some(entry) = self.last_ids
|
if let Some(entry) = self
|
||||||
|
.last_ids
|
||||||
.read()
|
.read()
|
||||||
.expect("'last_ids' read lock in reserve_signature_with_last_id")
|
.expect("'last_ids' read lock in reserve_signature_with_last_id")
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -148,7 +151,8 @@ impl Bank {
|
||||||
/// the oldest ones once its internal cache is full. Once boot, the
|
/// the oldest ones once its internal cache is full. Once boot, the
|
||||||
/// bank will reject transactions using that `last_id`.
|
/// bank will reject transactions using that `last_id`.
|
||||||
pub fn register_entry_id(&self, last_id: &Hash) {
|
pub fn register_entry_id(&self, last_id: &Hash) {
|
||||||
let mut last_ids = self.last_ids
|
let mut last_ids = self
|
||||||
|
.last_ids
|
||||||
.write()
|
.write()
|
||||||
.expect("'last_ids' write lock in register_entry_id");
|
.expect("'last_ids' write lock in register_entry_id");
|
||||||
if last_ids.len() >= MAX_ENTRY_IDS {
|
if last_ids.len() >= MAX_ENTRY_IDS {
|
||||||
|
@ -166,7 +170,8 @@ impl Bank {
|
||||||
return Err(BankError::NegativeTokens);
|
return Err(BankError::NegativeTokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let bals = self.balances
|
let bals = self
|
||||||
|
.balances
|
||||||
.read()
|
.read()
|
||||||
.expect("'balances' read lock in apply_debits");
|
.expect("'balances' read lock in apply_debits");
|
||||||
let option = bals.get(&tx.from);
|
let option = bals.get(&tx.from);
|
||||||
|
@ -211,14 +216,18 @@ impl Bank {
|
||||||
match &tx.instruction {
|
match &tx.instruction {
|
||||||
Instruction::NewContract(contract) => {
|
Instruction::NewContract(contract) => {
|
||||||
let mut plan = contract.plan.clone();
|
let mut plan = contract.plan.clone();
|
||||||
plan.apply_witness(&Witness::Timestamp(*self.last_time
|
plan.apply_witness(&Witness::Timestamp(
|
||||||
|
*self
|
||||||
|
.last_time
|
||||||
.read()
|
.read()
|
||||||
.expect("timestamp creation in apply_credits")));
|
.expect("timestamp creation in apply_credits"),
|
||||||
|
));
|
||||||
|
|
||||||
if let Some(ref payment) = plan.final_payment() {
|
if let Some(ref payment) = plan.final_payment() {
|
||||||
self.apply_payment(payment);
|
self.apply_payment(payment);
|
||||||
} else {
|
} else {
|
||||||
let mut pending = self.pending
|
let mut pending = self
|
||||||
|
.pending
|
||||||
.write()
|
.write()
|
||||||
.expect("'pending' write lock in apply_credits");
|
.expect("'pending' write lock in apply_credits");
|
||||||
pending.insert(tx.sig, plan);
|
pending.insert(tx.sig, plan);
|
||||||
|
@ -245,7 +254,8 @@ impl Bank {
|
||||||
// Run all debits first to filter out any transactions that can't be processed
|
// Run all debits first to filter out any transactions that can't be processed
|
||||||
// in parallel deterministically.
|
// in parallel deterministically.
|
||||||
info!("processing Transactions {}", txs.len());
|
info!("processing Transactions {}", txs.len());
|
||||||
let results: Vec<_> = txs.into_par_iter()
|
let results: Vec<_> = txs
|
||||||
|
.into_par_iter()
|
||||||
.map(|tx| self.apply_debits(&tx).map(|_| tx))
|
.map(|tx| self.apply_debits(&tx).map(|_| tx))
|
||||||
.collect(); // Calling collect() here forces all debits to complete before moving on.
|
.collect(); // Calling collect() here forces all debits to complete before moving on.
|
||||||
|
|
||||||
|
@ -272,7 +282,8 @@ impl Bank {
|
||||||
|
|
||||||
/// Process a Witness Signature.
|
/// Process a Witness Signature.
|
||||||
fn apply_signature(&self, from: PublicKey, tx_sig: Signature) -> Result<()> {
|
fn apply_signature(&self, from: PublicKey, tx_sig: Signature) -> Result<()> {
|
||||||
if let Occupied(mut e) = self.pending
|
if let Occupied(mut e) = self
|
||||||
|
.pending
|
||||||
.write()
|
.write()
|
||||||
.expect("write() in apply_signature")
|
.expect("write() in apply_signature")
|
||||||
.entry(tx_sig)
|
.entry(tx_sig)
|
||||||
|
@ -291,7 +302,8 @@ impl Bank {
|
||||||
fn apply_timestamp(&self, from: PublicKey, dt: DateTime<Utc>) -> Result<()> {
|
fn apply_timestamp(&self, from: PublicKey, dt: DateTime<Utc>) -> Result<()> {
|
||||||
// If this is the first timestamp we've seen, it probably came from the genesis block,
|
// If this is the first timestamp we've seen, it probably came from the genesis block,
|
||||||
// so we'll trust it.
|
// so we'll trust it.
|
||||||
if *self.last_time
|
if *self
|
||||||
|
.last_time
|
||||||
.read()
|
.read()
|
||||||
.expect("'last_time' read lock on first timestamp check")
|
.expect("'last_time' read lock on first timestamp check")
|
||||||
== Utc.timestamp(0, 0)
|
== Utc.timestamp(0, 0)
|
||||||
|
@ -302,7 +314,8 @@ impl Bank {
|
||||||
.insert(from);
|
.insert(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.time_sources
|
if self
|
||||||
|
.time_sources
|
||||||
.read()
|
.read()
|
||||||
.expect("'time_sources' read lock")
|
.expect("'time_sources' read lock")
|
||||||
.contains(&from)
|
.contains(&from)
|
||||||
|
@ -319,13 +332,17 @@ impl Bank {
|
||||||
|
|
||||||
// Hold 'pending' write lock until the end of this function. Otherwise another thread can
|
// Hold 'pending' write lock until the end of this function. Otherwise another thread can
|
||||||
// double-spend if it enters before the modified plan is removed from 'pending'.
|
// double-spend if it enters before the modified plan is removed from 'pending'.
|
||||||
let mut pending = self.pending
|
let mut pending = self
|
||||||
|
.pending
|
||||||
.write()
|
.write()
|
||||||
.expect("'pending' write lock in apply_timestamp");
|
.expect("'pending' write lock in apply_timestamp");
|
||||||
for (key, plan) in pending.iter_mut() {
|
for (key, plan) in pending.iter_mut() {
|
||||||
plan.apply_witness(&Witness::Timestamp(*self.last_time
|
plan.apply_witness(&Witness::Timestamp(
|
||||||
|
*self
|
||||||
|
.last_time
|
||||||
.read()
|
.read()
|
||||||
.expect("'last_time' read lock when creating timestamp")));
|
.expect("'last_time' read lock when creating timestamp"),
|
||||||
|
));
|
||||||
if let Some(ref payment) = plan.final_payment() {
|
if let Some(ref payment) = plan.final_payment() {
|
||||||
self.apply_payment(payment);
|
self.apply_payment(payment);
|
||||||
completed.push(key.clone());
|
completed.push(key.clone());
|
||||||
|
@ -370,7 +387,8 @@ impl Bank {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_balance(&self, pubkey: &PublicKey) -> Option<i64> {
|
pub fn get_balance(&self, pubkey: &PublicKey) -> Option<i64> {
|
||||||
let bals = self.balances
|
let bals = self
|
||||||
|
.balances
|
||||||
.read()
|
.read()
|
||||||
.expect("'balances' read lock in get_balance");
|
.expect("'balances' read lock in get_balance");
|
||||||
bals.get(pubkey).map(|x| x.load(Ordering::Relaxed) as i64)
|
bals.get(pubkey).map(|x| x.load(Ordering::Relaxed) as i64)
|
||||||
|
@ -512,7 +530,8 @@ mod tests {
|
||||||
let bank = Bank::new(&mint);
|
let bank = Bank::new(&mint);
|
||||||
let pubkey = KeyPair::new().pubkey();
|
let pubkey = KeyPair::new().pubkey();
|
||||||
let dt = Utc::now();
|
let dt = Utc::now();
|
||||||
let sig = bank.transfer_on_date(1, &mint.keypair(), pubkey, dt, mint.last_id())
|
let sig = bank
|
||||||
|
.transfer_on_date(1, &mint.keypair(), pubkey, dt, mint.last_id())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Assert the debit counts as a transaction.
|
// Assert the debit counts as a transaction.
|
||||||
|
|
15
src/crdt.rs
15
src/crdt.rs
|
@ -326,7 +326,8 @@ impl Crdt {
|
||||||
}
|
}
|
||||||
fn get_updates_since(&self, v: u64) -> (PublicKey, u64, Vec<ReplicatedData>) {
|
fn get_updates_since(&self, v: u64) -> (PublicKey, u64, Vec<ReplicatedData>) {
|
||||||
//trace!("get updates since {}", v);
|
//trace!("get updates since {}", v);
|
||||||
let data = self.table
|
let data = self
|
||||||
|
.table
|
||||||
.values()
|
.values()
|
||||||
.filter(|x| self.local[&x.id] > v)
|
.filter(|x| self.local[&x.id] > v)
|
||||||
.cloned()
|
.cloned()
|
||||||
|
@ -338,7 +339,8 @@ impl Crdt {
|
||||||
|
|
||||||
pub fn window_index_request(&self, ix: u64) -> Result<(SocketAddr, Vec<u8>)> {
|
pub fn window_index_request(&self, ix: u64) -> Result<(SocketAddr, Vec<u8>)> {
|
||||||
let daddr = "0.0.0.0:0".parse().unwrap();
|
let daddr = "0.0.0.0:0".parse().unwrap();
|
||||||
let valid: Vec<_> = self.table
|
let valid: Vec<_> = self
|
||||||
|
.table
|
||||||
.values()
|
.values()
|
||||||
.filter(|r| r.id != self.me && r.replicate_addr != daddr)
|
.filter(|r| r.id != self.me && r.replicate_addr != daddr)
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -391,7 +393,8 @@ impl Crdt {
|
||||||
|
|
||||||
// Lock the object only to do this operation and not for any longer
|
// Lock the object only to do this operation and not for any longer
|
||||||
// especially not when doing the `sock.send_to`
|
// especially not when doing the `sock.send_to`
|
||||||
let (remote_gossip_addr, req) = obj.read()
|
let (remote_gossip_addr, req) = obj
|
||||||
|
.read()
|
||||||
.expect("'obj' read lock in fn run_gossip")
|
.expect("'obj' read lock in fn run_gossip")
|
||||||
.gossip_request()?;
|
.gossip_request()?;
|
||||||
// TODO this will get chatty, so we need to first ask for number of updates since
|
// TODO this will get chatty, so we need to first ask for number of updates since
|
||||||
|
@ -483,7 +486,8 @@ impl Crdt {
|
||||||
trace!("RequestUpdates {}", v);
|
trace!("RequestUpdates {}", v);
|
||||||
let addr = reqdata.gossip_addr;
|
let addr = reqdata.gossip_addr;
|
||||||
// only lock for this call, dont lock during IO `sock.send_to` or `sock.recv_from`
|
// only lock for this call, dont lock during IO `sock.send_to` or `sock.recv_from`
|
||||||
let (from, ups, data) = obj.read()
|
let (from, ups, data) = obj
|
||||||
|
.read()
|
||||||
.expect("'obj' read lock in RequestUpdates")
|
.expect("'obj' read lock in RequestUpdates")
|
||||||
.get_updates_since(v);
|
.get_updates_since(v);
|
||||||
trace!("get updates since response {} {}", v, data.len());
|
trace!("get updates since response {} {}", v, data.len());
|
||||||
|
@ -554,7 +558,8 @@ impl Crdt {
|
||||||
while let Ok(mut more) = requests_receiver.try_recv() {
|
while let Ok(mut more) = requests_receiver.try_recv() {
|
||||||
reqs.append(&mut more);
|
reqs.append(&mut more);
|
||||||
}
|
}
|
||||||
let resp: VecDeque<_> = reqs.iter()
|
let resp: VecDeque<_> = reqs
|
||||||
|
.iter()
|
||||||
.filter_map(|b| Self::handle_blob(obj, window, blob_recycler, &b.read().unwrap()))
|
.filter_map(|b| Self::handle_blob(obj, window, blob_recycler, &b.read().unwrap()))
|
||||||
.collect();
|
.collect();
|
||||||
response_sender.send(resp)?;
|
response_sender.send(resp)?;
|
||||||
|
|
|
@ -29,7 +29,8 @@ fn recv_loop(
|
||||||
let msgs = re.allocate();
|
let msgs = re.allocate();
|
||||||
let msgs_ = msgs.clone();
|
let msgs_ = msgs.clone();
|
||||||
loop {
|
loop {
|
||||||
match msgs.write()
|
match msgs
|
||||||
|
.write()
|
||||||
.expect("write lock in fn recv_loop")
|
.expect("write lock in fn recv_loop")
|
||||||
.recv_from(sock)
|
.recv_from(sock)
|
||||||
{
|
{
|
||||||
|
@ -200,7 +201,8 @@ fn recv_window(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let timer = Duration::from_millis(200);
|
let timer = Duration::from_millis(200);
|
||||||
let mut dq = r.recv_timeout(timer)?;
|
let mut dq = r.recv_timeout(timer)?;
|
||||||
let leader_id = crdt.read()
|
let leader_id = crdt
|
||||||
|
.read()
|
||||||
.expect("'crdt' read lock in fn recv_window")
|
.expect("'crdt' read lock in fn recv_window")
|
||||||
.leader_data()
|
.leader_data()
|
||||||
.id;
|
.id;
|
||||||
|
@ -596,8 +598,8 @@ mod test {
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use streamer::{default_window, BlobReceiver, PacketReceiver};
|
|
||||||
use streamer::{blob_receiver, receiver, responder, window};
|
use streamer::{blob_receiver, receiver, responder, window};
|
||||||
|
use streamer::{default_window, BlobReceiver, PacketReceiver};
|
||||||
|
|
||||||
fn get_msgs(r: PacketReceiver, num: &mut usize) {
|
fn get_msgs(r: PacketReceiver, num: &mut usize) {
|
||||||
for _t in 0..5 {
|
for _t in 0..5 {
|
||||||
|
|
|
@ -184,8 +184,8 @@ mod tests {
|
||||||
use server::Server;
|
use server::Server;
|
||||||
use signature::{KeyPair, KeyPairUtil};
|
use signature::{KeyPair, KeyPairUtil};
|
||||||
use std::io::sink;
|
use std::io::sink;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use transaction::{Instruction, Plan};
|
use transaction::{Instruction, Plan};
|
||||||
|
|
|
@ -155,7 +155,8 @@ impl Transaction {
|
||||||
|
|
||||||
pub fn verify_plan(&self) -> bool {
|
pub fn verify_plan(&self) -> bool {
|
||||||
if let Instruction::NewContract(contract) = &self.instruction {
|
if let Instruction::NewContract(contract) = &self.instruction {
|
||||||
self.fee >= 0 && self.fee <= contract.tokens
|
self.fee >= 0
|
||||||
|
&& self.fee <= contract.tokens
|
||||||
&& contract.plan.verify(contract.tokens - self.fee)
|
&& contract.plan.verify(contract.tokens - self.fee)
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
|
|
@ -150,7 +150,8 @@ pub fn crdt_retransmit() {
|
||||||
trace!("waiting to converge:");
|
trace!("waiting to converge:");
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
for _ in 0..30 {
|
for _ in 0..30 {
|
||||||
done = c1.read().unwrap().table.len() == 3 && c2.read().unwrap().table.len() == 3
|
done = c1.read().unwrap().table.len() == 3
|
||||||
|
&& c2.read().unwrap().table.len() == 3
|
||||||
&& c3.read().unwrap().table.len() == 3;
|
&& c3.read().unwrap().table.len() == 3;
|
||||||
if done {
|
if done {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue