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

Commit eaba689

Browse files
committed
Merge branch 'master' into td-pubsub
2 parents 2da7ac0 + d153954 commit eaba689

File tree

13 files changed

+97
-6
lines changed

13 files changed

+97
-6
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,9 @@
55
polkadot/runtime/wasm/target/
66
substrate/executor/wasm/target/
77
substrate/test-runtime/wasm/target/
8+
substrate/pwasm-alloc/target/
9+
substrate/pwasm-libc/target/
10+
substrate/pwasm-alloc/Cargo.lock
11+
substrate/pwasm-libc/Cargo.lock
812
demo/runtime/wasm/target/
913
**/._*
Binary file not shown.
Binary file not shown.

polkadot/consensus/src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,15 @@ impl<C: PolkadotApi, R: TableRouter> bft::Proposer for Proposer<C, R> {
585585
}
586586

587587
let polkadot_block = block_builder.bake();
588-
info!("Proposing block [number: {}; extrinsics: [{}], parent_hash: {}]", polkadot_block.header.number, polkadot_block.extrinsics.len(), polkadot_block.header.parent_hash);
588+
info!("Proposing block [number: {}; hash: {}; parent_hash: {}; extrinsics: [{}]]",
589+
polkadot_block.header.number,
590+
Hash::from(polkadot_block.header.blake2_256()),
591+
polkadot_block.header.parent_hash,
592+
polkadot_block.extrinsics.iter()
593+
.map(|xt| format!("{}", Hash::from(xt.blake2_256())))
594+
.collect::<Vec<_>>()
595+
.join(", ")
596+
);
589597

590598
let substrate_block = Slicable::decode(&mut polkadot_block.encode().as_slice())
591599
.expect("polkadot blocks defined to serialize to substrate blocks correctly; qed");
Binary file not shown.
Binary file not shown.

polkadot/service/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ fn local_testnet_config() -> ChainConfig {
206206
}),
207207
staking: Some(StakingConfig {
208208
current_era: 0,
209-
intentions: vec![],
209+
intentions: initial_authorities.clone(),
210210
transaction_fee: 1,
211211
balances: endowed_accounts.iter().map(|&k|(k, 1u64 << 60)).collect(),
212212
validator_count: 2,

polkadot/transaction-pool/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,13 +292,16 @@ impl<'a, T: 'a + PolkadotApi> Ready<'a, T> {
292292
impl<'a, T: 'a + PolkadotApi> transaction_pool::Ready<VerifiedTransaction> for Ready<'a, T> {
293293
fn is_ready(&mut self, xt: &VerifiedTransaction) -> Readiness {
294294
let sender = xt.inner.signed;
295+
trace!(target: "transaction-pool", "Checking readiness of {} (from {})", xt.hash, TransactionHash::from(sender));
295296

296297
// TODO: find a way to handle index error properly -- will need changes to
297298
// transaction-pool trait.
298299
let (api_handle, at_block) = (&self.api_handle, &self.at_block);
299300
let next_index = self.known_indices.entry(sender)
300301
.or_insert_with(|| api_handle.index(at_block, sender).ok().unwrap_or_else(u64::max_value));
301302

303+
trace!(target: "transaction-pool", "Next index for sender is {}; xt index is {}", next_index, xt.inner.index);
304+
302305
match xt.inner.index.cmp(&next_index) {
303306
Ordering::Greater => Readiness::Future,
304307
Ordering::Equal => Readiness::Ready,

substrate/bft/src/generic/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl<D, S> Locked<D, S> {
293293
enum LocalState {
294294
Start,
295295
Proposed,
296-
Prepared,
296+
Prepared(bool), // whether we thought it valid.
297297
Committed,
298298
VoteAdvance,
299299
}
@@ -582,6 +582,7 @@ impl<C: Context> Strategy<C> {
582582
Some(_) => {
583583
// don't check validity if we are locked.
584584
// this is necessary to preserve the liveness property.
585+
self.local_state = LocalState::Prepared(true);
585586
prepare_for = Some(digest);
586587
}
587588
None => {
@@ -591,6 +592,8 @@ impl<C: Context> Strategy<C> {
591592

592593
if let Async::Ready(valid) = res {
593594
self.evaluating_proposal = None;
595+
self.local_state = LocalState::Prepared(valid);
596+
594597
if valid {
595598
prepare_for = Some(digest);
596599
}
@@ -606,7 +609,6 @@ impl<C: Context> Strategy<C> {
606609
).into();
607610

608611
self.import_and_send_message(message, context, sending);
609-
self.local_state = LocalState::Prepared;
610612
}
611613

612614
Ok(())
@@ -657,6 +659,12 @@ impl<C: Context> Strategy<C> {
657659
// sent an AdvanceRound message yet, do so.
658660
let mut attempt_advance = self.current_accumulator.advance_votes() > self.max_faulty;
659661

662+
// if we evaluated the proposal and it was bad, vote to advance round.
663+
if let LocalState::Prepared(false) = self.local_state {
664+
attempt_advance = true;
665+
}
666+
667+
// if the timeout has fired, vote to advance round.
660668
if let Async::Ready(_) = self.round_timeout.poll()? {
661669
attempt_advance = true;
662670
}

substrate/bft/src/generic/tests.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
1919
use super::*;
2020

21+
use std::collections::BTreeSet;
2122
use std::sync::{Arc, Mutex};
2223
use std::sync::atomic::{AtomicUsize, Ordering};
2324
use std::time::Duration;
@@ -117,6 +118,7 @@ struct TestContext {
117118
node_count: usize,
118119
current_round: Arc<AtomicUsize>,
119120
timer: Timer,
121+
evaluated: Mutex<BTreeSet<usize>>,
120122
}
121123

122124
impl Context for TestContext {
@@ -137,7 +139,7 @@ impl Context for TestContext {
137139
let proposal = {
138140
let mut p = self.proposal.lock().unwrap();
139141
let x = *p;
140-
*p = (*p * 2) + 1;
142+
*p += self.node_count;
141143
x
142144
};
143145

@@ -175,6 +177,10 @@ impl Context for TestContext {
175177
}
176178

177179
fn proposal_valid(&self, proposal: &Candidate) -> FutureResult<bool, Error> {
180+
if !self.evaluated.lock().unwrap().insert(proposal.0) {
181+
panic!("Evaluated proposal {:?} twice", proposal.0);
182+
}
183+
178184
Ok(proposal.0 % 3 != 0).into_future()
179185
}
180186

@@ -230,6 +236,64 @@ fn consensus_completes_with_minimum_good() {
230236
proposal: Mutex::new(i),
231237
current_round: Arc::new(AtomicUsize::new(0)),
232238
timer: timer.clone(),
239+
evaluated: Mutex::new(BTreeSet::new()),
240+
node_count,
241+
};
242+
243+
agree(
244+
ctx,
245+
node_count,
246+
max_faulty,
247+
rx.map_err(|_| Error),
248+
tx.sink_map_err(|_| Error).with(move |t| Ok((i, t))),
249+
)
250+
})
251+
.collect::<Vec<_>>();
252+
253+
let timeout = timeout_in(Duration::from_millis(500)).map_err(|_| Error);
254+
let results = ::futures::future::join_all(nodes)
255+
.map(Some)
256+
.select(timeout.map(|_| None))
257+
.wait()
258+
.map(|(i, _)| i)
259+
.map_err(|(e, _)| e)
260+
.expect("to complete")
261+
.expect("to not time out");
262+
263+
for result in &results {
264+
assert_eq!(&result.justification.digest, &results[0].justification.digest);
265+
}
266+
}
267+
268+
#[test]
269+
fn consensus_completes_with_minimum_good_all_initial_proposals_bad() {
270+
let node_count = 10;
271+
let max_faulty = 3;
272+
273+
let timer = tokio_timer::wheel().tick_duration(ROUND_DURATION).build();
274+
275+
let (network, net_send, net_recv) = Network::new(node_count);
276+
network.route_on_thread();
277+
278+
let nodes = net_send
279+
.into_iter()
280+
.zip(net_recv)
281+
.take(node_count - max_faulty)
282+
.enumerate()
283+
.map(|(i, (tx, rx))| {
284+
// the first 5 proposals are going to be bad.
285+
let proposal = if i < 5 {
286+
i * 3 // proposals considered bad in the tests if they are % 3
287+
} else {
288+
(i * 3) + 1
289+
};
290+
291+
let ctx = TestContext {
292+
local_id: AuthorityId(i),
293+
proposal: Mutex::new(proposal),
294+
current_round: Arc::new(AtomicUsize::new(0)),
295+
timer: timer.clone(),
296+
evaluated: Mutex::new(BTreeSet::new()),
233297
node_count,
234298
};
235299

@@ -279,6 +343,7 @@ fn consensus_does_not_complete_without_enough_nodes() {
279343
proposal: Mutex::new(i),
280344
current_round: Arc::new(AtomicUsize::new(0)),
281345
timer: timer.clone(),
346+
evaluated: Mutex::new(BTreeSet::new()),
282347
node_count,
283348
};
284349

@@ -335,6 +400,7 @@ fn threshold_plus_one_locked_on_proposal_only_one_with_candidate() {
335400
proposal: Mutex::new(i),
336401
current_round: Arc::new(AtomicUsize::new(locked_round + 1)),
337402
timer: timer.clone(),
403+
evaluated: Mutex::new(BTreeSet::new()),
338404
node_count,
339405
};
340406
let mut agreement = agree(
@@ -367,7 +433,7 @@ fn threshold_plus_one_locked_on_proposal_only_one_with_candidate() {
367433
})
368434
.collect::<Vec<_>>();
369435

370-
let timeout = timeout_in(Duration::from_millis(500)).map_err(|_| Error);
436+
let timeout = timeout_in(Duration::from_millis(1000)).map_err(|_| Error);
371437
let results = ::futures::future::join_all(nodes)
372438
.map(Some)
373439
.select(timeout.map(|_| None))
@@ -404,6 +470,7 @@ fn consensus_completes_even_when_nodes_start_with_a_delay() {
404470
proposal: Mutex::new(i),
405471
current_round: Arc::new(AtomicUsize::new(0)),
406472
timer: timer.clone(),
473+
evaluated: Mutex::new(BTreeSet::new()),
407474
node_count,
408475
};
409476

0 commit comments

Comments
 (0)