Merge remote-tracking branch 'parity/should-seal' into auth-round

This commit is contained in:
keorn 2016-09-14 10:59:33 +02:00
commit 7f05021075
5 changed files with 59 additions and 15 deletions

View File

@ -99,7 +99,9 @@ impl Engine for BasicAuthority {
/// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current).
fn on_close_block(&self, _block: &mut ExecutedBlock) {} fn on_close_block(&self, _block: &mut ExecutedBlock) {}
fn seals_internally(&self) -> bool { true } fn is_sealer(&self, author: &Address) -> Option<bool> {
Some(self.our_params.authorities.contains(author))
}
/// Attempt to seal the block internally. /// Attempt to seal the block internally.
/// ///
@ -252,4 +254,14 @@ mod tests {
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
assert!(b.try_seal(engine, seal).is_ok()); assert!(b.try_seal(engine, seal).is_ok());
} }
#[test]
fn seals_internally() {
let tap = AccountProvider::transient_provider();
let authority = tap.insert_account("".sha3(), "").unwrap();
let engine = new_test_authority().engine;
assert!(!engine.is_sealer(&Address::default()).unwrap());
assert!(engine.is_sealer(&authority).unwrap());
}
} }

View File

@ -58,7 +58,7 @@ impl Engine for InstantSeal {
Schedule::new_homestead() Schedule::new_homestead()
} }
fn seals_internally(&self) -> bool { true } fn is_sealer(&self, _author: &Address) -> Option<bool> { Some(true) }
fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> { fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option<Vec<Bytes>> {
Some(Vec::new()) Some(Vec::new())

View File

@ -73,8 +73,11 @@ pub trait Engine : Sync + Send {
/// Block transformation functions, after the transactions. /// Block transformation functions, after the transactions.
fn on_close_block(&self, _block: &mut ExecutedBlock) {} fn on_close_block(&self, _block: &mut ExecutedBlock) {}
/// If true, generate_seal has to be implemented. /// If Some(true) this author is able to generate seals, generate_seal has to be implemented.
fn seals_internally(&self) -> bool { false } /// None indicates that this Engine never seals internally regardless of author (e.g. PoW).
fn is_sealer(&self, _author: &Address) -> Option<bool> { None }
/// Checks if default address is able to seal.
fn is_default_sealer(&self) -> Option<bool> { self.is_sealer(&Default::default()) }
/// Attempt to seal the block internally. /// Attempt to seal the block internally.
/// ///
/// If `Some` is returned, then you get a valid seal. /// If `Some` is returned, then you get a valid seal.

View File

@ -175,6 +175,7 @@ pub struct Miner {
sealing_block_last_request: Mutex<u64>, sealing_block_last_request: Mutex<u64>,
// for sealing... // for sealing...
options: MinerOptions, options: MinerOptions,
seals_internally: bool,
gas_range_target: RwLock<(U256, U256)>, gas_range_target: RwLock<(U256, U256)>,
author: RwLock<Address>, author: RwLock<Address>,
@ -194,7 +195,11 @@ impl Miner {
options: Default::default(), options: Default::default(),
next_allowed_reseal: Mutex::new(Instant::now()), next_allowed_reseal: Mutex::new(Instant::now()),
sealing_block_last_request: Mutex::new(0), sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(SealingWork{queue: UsingQueue::new(20), enabled: false}), sealing_work: Mutex::new(SealingWork{
queue: UsingQueue::new(20),
enabled: spec.engine.is_default_sealer().unwrap_or(false)
}),
seals_internally: spec.engine.is_default_sealer().is_some(),
gas_range_target: RwLock::new((U256::zero(), U256::zero())), gas_range_target: RwLock::new((U256::zero(), U256::zero())),
author: RwLock::new(Address::default()), author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
@ -213,7 +218,13 @@ impl Miner {
transaction_queue: txq, transaction_queue: txq,
next_allowed_reseal: Mutex::new(Instant::now()), next_allowed_reseal: Mutex::new(Instant::now()),
sealing_block_last_request: Mutex::new(0), sealing_block_last_request: Mutex::new(0),
sealing_work: Mutex::new(SealingWork{queue: UsingQueue::new(options.work_queue_size), enabled: options.force_sealing || !options.new_work_notify.is_empty()}), sealing_work: Mutex::new(SealingWork{
queue: UsingQueue::new(options.work_queue_size),
enabled: options.force_sealing
|| !options.new_work_notify.is_empty()
|| spec.engine.is_default_sealer().unwrap_or(false)
}),
seals_internally: spec.engine.is_default_sealer().is_some(),
gas_range_target: RwLock::new((U256::zero(), U256::zero())), gas_range_target: RwLock::new((U256::zero(), U256::zero())),
author: RwLock::new(Address::default()), author: RwLock::new(Address::default()),
extra_data: RwLock::new(Vec::new()), extra_data: RwLock::new(Vec::new()),
@ -360,7 +371,7 @@ impl Miner {
true true
} }
} else { } else {
// sealing is disabled. trace!(target: "miner", "requires_reseal: sealing is disabled");
false false
} }
} }
@ -578,6 +589,10 @@ impl MinerService for Miner {
} }
fn set_author(&self, author: Address) { fn set_author(&self, author: Address) {
if self.seals_internally {
let mut sealing_work = self.sealing_work.lock();
sealing_work.enabled = self.engine.is_sealer(&author).unwrap_or(false);
}
*self.author.write() = author; *self.author.write() = author;
} }
@ -703,7 +718,7 @@ impl MinerService for Miner {
if imported.is_ok() && self.options.reseal_on_own_tx && self.tx_reseal_allowed() { if imported.is_ok() && self.options.reseal_on_own_tx && self.tx_reseal_allowed() {
// Make sure to do it after transaction is imported and lock is droped. // Make sure to do it after transaction is imported and lock is droped.
// We need to create pending block and enable sealing. // We need to create pending block and enable sealing.
if self.engine.seals_internally() || !self.prepare_work_sealing(chain) { if self.seals_internally || !self.prepare_work_sealing(chain) {
// If new block has not been prepared (means we already had one) // If new block has not been prepared (means we already had one)
// or Engine might be able to seal internally, // or Engine might be able to seal internally,
// we need to update sealing. // we need to update sealing.
@ -821,7 +836,7 @@ impl MinerService for Miner {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
trace!(target: "miner", "update_sealing: preparing a block"); trace!(target: "miner", "update_sealing: preparing a block");
let (block, original_work_hash) = self.prepare_block(chain); let (block, original_work_hash) = self.prepare_block(chain);
if self.engine.seals_internally() { if self.seals_internally {
trace!(target: "miner", "update_sealing: engine indicates internal sealing"); trace!(target: "miner", "update_sealing: engine indicates internal sealing");
self.seal_and_import_block_internally(chain, block); self.seal_and_import_block_internally(chain, block);
} else { } else {
@ -1027,7 +1042,7 @@ mod tests {
assert_eq!(miner.pending_transactions_hashes().len(), 1); assert_eq!(miner.pending_transactions_hashes().len(), 1);
assert_eq!(miner.pending_receipts().len(), 1); assert_eq!(miner.pending_receipts().len(), 1);
// This method will let us know if pending block was created (before calling that method) // This method will let us know if pending block was created (before calling that method)
assert_eq!(miner.prepare_work_sealing(&client), false); assert!(!miner.prepare_work_sealing(&client));
} }
#[test] #[test]
@ -1046,16 +1061,26 @@ mod tests {
assert_eq!(miner.pending_transactions().len(), 0); assert_eq!(miner.pending_transactions().len(), 0);
assert_eq!(miner.pending_receipts().len(), 0); assert_eq!(miner.pending_receipts().len(), 0);
// This method will let us know if pending block was created (before calling that method) // This method will let us know if pending block was created (before calling that method)
assert_eq!(miner.prepare_work_sealing(&client), true); assert!(miner.prepare_work_sealing(&client));
}
#[test]
fn should_not_seal_unless_enabled() {
let miner = miner();
let client = TestBlockChainClient::default();
// By default resealing is not required.
assert!(!miner.requires_reseal(1u8.into()));
miner.import_external_transactions(&client, vec![transaction()]).pop().unwrap().unwrap();
assert!(miner.prepare_work_sealing(&client));
// Unless asked to prepare work.
assert!(miner.requires_reseal(1u8.into()));
} }
#[test] #[test]
fn internal_seals_without_work() { fn internal_seals_without_work() {
let miner = Miner::with_spec(&Spec::new_test_instant()); let miner = Miner::with_spec(&Spec::new_test_instant());
{
let mut sealing_work = miner.sealing_work.lock();
sealing_work.enabled = true;
}
let c = generate_dummy_client(2); let c = generate_dummy_client(2);
let client = c.reference().as_ref(); let client = c.reference().as_ref();

4
script/deploy.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/bash
ll
ls
la