Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit d5b13aa

Browse files
committed
Merge branch 'js' into jg-gitlab-build
* js: (23 commits) alignment back to normal Print backtrace on panic (#2535) NEVER export class instance functions stop wrongly using main app IdentityIcon pass value through as-is events is using a proper table fixes registration in place Backports to master (#2530) lookup hash ethcore_hashContent call single input for commit/filename basic githubhint layout Handle reorganizations in the state cache (#2490) terminate after 30 seconds (#2513) registry: fix setting A records registry: reducer returned invalid state registry: don't hash for A records registry: sha3 value first registry: connect record management component ...
2 parents 67a3f32 + 52184d1 commit d5b13aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1614
-193
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ethcore/src/client/client.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,7 @@ impl Client {
304304
// Enact Verified Block
305305
let parent = chain_has_parent.unwrap();
306306
let last_hashes = self.build_last_hashes(header.parent_hash().clone());
307-
let is_canon = header.parent_hash() == &chain.best_block_hash();
308-
let db = if is_canon { self.state_db.lock().boxed_clone_canon() } else { self.state_db.lock().boxed_clone() };
307+
let db = self.state_db.lock().boxed_clone_canon(&header.parent_hash());
309308

310309
let enact_result = enact_verified(block, engine, self.tracedb.read().tracing_enabled(), db, &parent, last_hashes, self.factories.clone());
311310
if let Err(e) = enact_result {
@@ -459,6 +458,8 @@ impl Client {
459458
enacted: route.enacted.clone(),
460459
retracted: route.retracted.len()
461460
});
461+
let is_canon = route.enacted.last().map_or(false, |h| h == hash);
462+
state.sync_cache(&route.enacted, &route.retracted, is_canon);
462463
// Final commit to the DB
463464
self.db.read().write_buffered(batch);
464465
chain.commit();
@@ -533,9 +534,11 @@ impl Client {
533534

534535
/// Get a copy of the best block's state.
535536
pub fn state(&self) -> State {
537+
let header = self.best_block_header();
538+
let header = HeaderView::new(&header);
536539
State::from_existing(
537-
self.state_db.lock().boxed_clone(),
538-
HeaderView::new(&self.best_block_header()).state_root(),
540+
self.state_db.lock().boxed_clone_canon(&header.hash()),
541+
header.state_root(),
539542
self.engine.account_start_nonce(),
540543
self.factories.clone())
541544
.expect("State root of best block header always valid.")
@@ -1092,7 +1095,7 @@ impl MiningBlockChainClient for Client {
10921095
engine,
10931096
self.factories.clone(),
10941097
false, // TODO: this will need to be parameterised once we want to do immediate mining insertion.
1095-
self.state_db.lock().boxed_clone(),
1098+
self.state_db.lock().boxed_clone_canon(&h),
10961099
&chain.block_header(&h).expect("h is best block hash: so its header must exist: qed"),
10971100
self.build_last_hashes(h.clone()),
10981101
author,
@@ -1128,6 +1131,7 @@ impl MiningBlockChainClient for Client {
11281131
let block_data = block.rlp_bytes();
11291132
let route = self.commit_block(block, &h, &block_data);
11301133
trace!(target: "client", "Imported sealed block #{} ({})", number, h);
1134+
self.state_db.lock().sync_cache(&route.enacted, &route.retracted, false);
11311135

11321136
let (enacted, retracted) = self.calculate_enacted_retracted(&[route]);
11331137
self.miner.chain_new_blocks(self, &[h.clone()], &[], &enacted, &retracted);

ethcore/src/miner/miner.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl Miner {
194194
true => None,
195195
false => Some(WorkPoster::new(&options.new_work_notify))
196196
};
197-
let txq = Arc::new(Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)));
197+
let txq = Arc::new(Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, !U256::zero(), options.tx_gas_limit)));
198198
Miner {
199199
transaction_queue: txq,
200200
next_allowed_reseal: Mutex::new(Instant::now()),
@@ -443,6 +443,8 @@ impl Miner {
443443
let gas_limit = HeaderView::new(&chain.best_block_header()).gas_limit();
444444
let mut queue = self.transaction_queue.lock();
445445
queue.set_gas_limit(gas_limit);
446+
// Set total qx queue gas limit to be 2x the block gas limit.
447+
queue.set_total_gas_limit(gas_limit << 1);
446448
}
447449

448450
/// Returns true if we had to prepare new pending block.

ethcore/src/miner/transaction_queue.rs

+58-17
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct TransactionOrder {
130130
/// (e.g. Tx(nonce:5), State(nonce:0) -> height: 5)
131131
/// High nonce_height = Low priority (processed later)
132132
nonce_height: U256,
133+
/// Gas specified in the transaction.
134+
gas: U256,
133135
/// Gas Price of the transaction.
134136
/// Low gas price = Low priority (processed later)
135137
gas_price: U256,
@@ -146,6 +148,7 @@ impl TransactionOrder {
146148
fn for_transaction(tx: &VerifiedTransaction, base_nonce: U256) -> Self {
147149
TransactionOrder {
148150
nonce_height: tx.nonce() - base_nonce,
151+
gas: tx.transaction.gas.clone(),
149152
gas_price: tx.transaction.gas_price,
150153
hash: tx.hash(),
151154
origin: tx.origin,
@@ -287,6 +290,7 @@ struct TransactionSet {
287290
by_address: Table<Address, U256, TransactionOrder>,
288291
by_gas_price: GasPriceQueue,
289292
limit: usize,
293+
gas_limit: U256,
290294
}
291295

292296
impl TransactionSet {
@@ -317,15 +321,18 @@ impl TransactionSet {
317321
/// It drops transactions from this set but also removes associated `VerifiedTransaction`.
318322
/// Returns addresses and lowest nonces of transactions removed because of limit.
319323
fn enforce_limit(&mut self, by_hash: &mut HashMap<H256, VerifiedTransaction>) -> Option<HashMap<Address, U256>> {
320-
let len = self.by_priority.len();
321-
if len <= self.limit {
322-
return None;
323-
}
324-
324+
let mut count = 0;
325+
let mut gas: U256 = 0.into();
325326
let to_drop : Vec<(Address, U256)> = {
326327
self.by_priority
327328
.iter()
328-
.skip(self.limit)
329+
.skip_while(|order| {
330+
count = count + 1;
331+
let r = gas.overflowing_add(order.gas);
332+
if r.1 { return false }
333+
gas = r.0;
334+
count <= self.limit && gas <= self.gas_limit
335+
})
329336
.map(|order| by_hash.get(&order.hash)
330337
.expect("All transactions in `self.by_priority` and `self.by_address` are kept in sync with `by_hash`."))
331338
.map(|tx| (tx.sender(), tx.nonce()))
@@ -432,23 +439,25 @@ impl Default for TransactionQueue {
432439
impl TransactionQueue {
433440
/// Creates new instance of this Queue
434441
pub fn new() -> Self {
435-
Self::with_limits(1024, !U256::zero())
442+
Self::with_limits(1024, !U256::zero(), !U256::zero())
436443
}
437444

438445
/// Create new instance of this Queue with specified limits
439-
pub fn with_limits(limit: usize, tx_gas_limit: U256) -> Self {
446+
pub fn with_limits(limit: usize, gas_limit: U256, tx_gas_limit: U256) -> Self {
440447
let current = TransactionSet {
441448
by_priority: BTreeSet::new(),
442449
by_address: Table::new(),
443450
by_gas_price: Default::default(),
444451
limit: limit,
452+
gas_limit: gas_limit,
445453
};
446454

447455
let future = TransactionSet {
448456
by_priority: BTreeSet::new(),
449457
by_address: Table::new(),
450458
by_gas_price: Default::default(),
451459
limit: limit,
460+
gas_limit: gas_limit,
452461
};
453462

454463
TransactionQueue {
@@ -504,6 +513,13 @@ impl TransactionQueue {
504513
};
505514
}
506515

516+
/// Sets new total gas limit.
517+
pub fn set_total_gas_limit(&mut self, gas_limit: U256) {
518+
self.future.gas_limit = gas_limit;
519+
self.current.gas_limit = gas_limit;
520+
self.future.enforce_limit(&mut self.by_hash);
521+
}
522+
507523
/// Set the new limit for the amount of gas any individual transaction may have.
508524
/// Any transaction already imported to the queue is not affected.
509525
pub fn set_tx_gas_limit(&mut self, limit: U256) {
@@ -827,6 +843,16 @@ impl TransactionQueue {
827843
let nonce = tx.nonce();
828844
let hash = tx.hash();
829845

846+
{
847+
// Rough size sanity check
848+
let gas = &tx.transaction.gas;
849+
if U256::from(tx.transaction.data.len()) > *gas {
850+
// Droping transaction
851+
trace!(target: "txqueue", "Dropping oversized transaction: {:?} (gas: {} < size {})", hash, gas, tx.transaction.data.len());
852+
return Err(TransactionError::LimitReached);
853+
}
854+
}
855+
830856
// The transaction might be old, let's check that.
831857
// This has to be the first test, otherwise calculating
832858
// nonce height would result in overflow.
@@ -979,14 +1005,15 @@ mod test {
9791005
}
9801006

9811007
fn default_nonce() -> U256 { 123.into() }
1008+
fn default_gas_val() -> U256 { 100_000.into() }
9821009
fn default_gas_price() -> U256 { 1.into() }
9831010

9841011
fn new_unsigned_tx(nonce: U256, gas_price: U256) -> Transaction {
9851012
Transaction {
9861013
action: Action::Create,
9871014
value: U256::from(100),
9881015
data: "3331600055".from_hex().unwrap(),
989-
gas: U256::from(100_000),
1016+
gas: default_gas_val(),
9901017
gas_price: gas_price,
9911018
nonce: nonce
9921019
}
@@ -1051,7 +1078,7 @@ mod test {
10511078
#[test]
10521079
fn should_return_correct_nonces_when_dropped_because_of_limit() {
10531080
// given
1054-
let mut txq = TransactionQueue::with_limits(2, !U256::zero());
1081+
let mut txq = TransactionQueue::with_limits(2, !U256::zero(), !U256::zero());
10551082
let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
10561083
let sender = tx1.sender().unwrap();
10571084
let nonce = tx1.nonce;
@@ -1089,7 +1116,8 @@ mod test {
10891116
by_priority: BTreeSet::new(),
10901117
by_address: Table::new(),
10911118
by_gas_price: Default::default(),
1092-
limit: 1
1119+
limit: 1,
1120+
gas_limit: !U256::zero(),
10931121
};
10941122
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
10951123
let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External).unwrap();
@@ -1129,7 +1157,8 @@ mod test {
11291157
by_priority: BTreeSet::new(),
11301158
by_address: Table::new(),
11311159
by_gas_price: Default::default(),
1132-
limit: 1
1160+
limit: 1,
1161+
gas_limit: !U256::zero(),
11331162
};
11341163
// Create two transactions with same nonce
11351164
// (same hash)
@@ -1177,7 +1206,8 @@ mod test {
11771206
by_priority: BTreeSet::new(),
11781207
by_address: Table::new(),
11791208
by_gas_price: Default::default(),
1180-
limit: 2
1209+
limit: 2,
1210+
gas_limit: !U256::zero(),
11811211
};
11821212
let tx = new_tx_default();
11831213
let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External).unwrap();
@@ -1194,7 +1224,8 @@ mod test {
11941224
by_priority: BTreeSet::new(),
11951225
by_address: Table::new(),
11961226
by_gas_price: Default::default(),
1197-
limit: 1
1227+
limit: 1,
1228+
gas_limit: !U256::zero(),
11981229
};
11991230

12001231
assert_eq!(set.gas_price_entry_limit(), 0.into());
@@ -1690,7 +1721,7 @@ mod test {
16901721
#[test]
16911722
fn should_drop_old_transactions_when_hitting_the_limit() {
16921723
// given
1693-
let mut txq = TransactionQueue::with_limits(1, !U256::zero());
1724+
let mut txq = TransactionQueue::with_limits(1, !U256::zero(), !U256::zero());
16941725
let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
16951726
let sender = tx.sender().unwrap();
16961727
let nonce = tx.nonce;
@@ -1711,7 +1742,7 @@ mod test {
17111742

17121743
#[test]
17131744
fn should_limit_future_transactions() {
1714-
let mut txq = TransactionQueue::with_limits(1, !U256::zero());
1745+
let mut txq = TransactionQueue::with_limits(1, !U256::zero(), !U256::zero());
17151746
txq.current.set_limit(10);
17161747
let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
17171748
let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
@@ -1728,6 +1759,16 @@ mod test {
17281759
assert_eq!(txq.status().future, 1);
17291760
}
17301761

1762+
#[test]
1763+
fn should_limit_by_gas() {
1764+
let mut txq = TransactionQueue::with_limits(100, default_gas_val() * U256::from(2), !U256::zero());
1765+
let (tx1, _) = new_tx_pair_default(U256::from(4), U256::from(1));
1766+
let (tx3, _) = new_tx_pair_default(U256::from(4), U256::from(2));
1767+
txq.add(tx1.clone(), &default_account_details, TransactionOrigin::External).unwrap();
1768+
txq.add(tx3.clone(), &default_account_details, TransactionOrigin::External).unwrap();
1769+
assert_eq!(txq.status().pending, 2);
1770+
}
1771+
17311772
#[test]
17321773
fn should_drop_transactions_with_old_nonces() {
17331774
let mut txq = TransactionQueue::new();
@@ -1971,7 +2012,7 @@ mod test {
19712012
#[test]
19722013
fn should_keep_right_order_in_future() {
19732014
// given
1974-
let mut txq = TransactionQueue::with_limits(1, !U256::zero());
2015+
let mut txq = TransactionQueue::with_limits(1, !U256::zero(), !U256::zero());
19752016
let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
19762017
let prev_nonce = |a: &Address| AccountDetails { nonce: default_account_details(a).nonce - U256::one(), balance:
19772018
default_account_details(a).balance };

ethcore/src/state/mod.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ impl AccountEntry {
164164
/// use that.
165165
/// ****************************************************************************
166166
///
167-
/// Upon destruction all the local cache data merged into the global cache.
168-
/// The merge might be rejected if current state is non-canonical.
167+
/// Upon destruction all the local cache data propagated into the global cache.
168+
/// Propagated items might be rejected if current state is non-canonical.
169169
///
170170
/// State snapshotting.
171171
///
@@ -318,7 +318,7 @@ impl State {
318318

319319
/// Destroy the current object and return root and database.
320320
pub fn drop(mut self) -> (H256, StateDB) {
321-
self.commit_cache();
321+
self.propagate_to_global_cache();
322322
(self.root, self.db)
323323
}
324324

@@ -533,11 +533,12 @@ impl State {
533533
Ok(())
534534
}
535535

536-
fn commit_cache(&mut self) {
536+
/// Propagate local cache into shared canonical state cache.
537+
fn propagate_to_global_cache(&mut self) {
537538
let mut addresses = self.cache.borrow_mut();
538539
trace!("Committing cache {:?} entries", addresses.len());
539540
for (address, a) in addresses.drain().filter(|&(_, ref a)| a.state == AccountState::Committed || a.state == AccountState::CleanFresh) {
540-
self.db.cache_account(address, a.account);
541+
self.db.add_to_account_cache(address, a.account, a.state == AccountState::Committed);
541542
}
542543
}
543544

0 commit comments

Comments
 (0)