Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
9d58b46
GrandpaLightBlockImport
svyatonik Jan 28, 2019
0b3443b
extract authorities in AuraVerifier
svyatonik Jan 28, 2019
31b183d
Merge branch 'master' into light_grandpa_importer2
svyatonik Jan 29, 2019
da6c11e
post-merge fix
svyatonik Jan 29, 2019
2d8a084
Merge branch 'master' into light_grandpa_importer2
svyatonik Feb 1, 2019
d42315b
restore authorities cache
svyatonik Feb 1, 2019
4cbefb6
license
svyatonik Feb 4, 2019
5344c61
new finality proof draft
svyatonik Feb 8, 2019
c3a8125
generalized PendingJustifications
svyatonik Feb 8, 2019
2c4ae73
finality proof messages
svyatonik Feb 11, 2019
fbf49c6
fixed compilation
svyatonik Feb 11, 2019
ac72a40
pass verifier to import_finality_proof
svyatonik Feb 11, 2019
d4becc1
do not fetch remote proof from light import directly
svyatonik Feb 11, 2019
41c4376
FinalityProofProvider
svyatonik Feb 12, 2019
41a1dba
fixed authorities cache test
svyatonik Feb 12, 2019
2c02eff
restored finality proof tests
svyatonik Feb 12, 2019
527596d
finality_proof docs
svyatonik Feb 12, 2019
7c4c71f
Merge branch 'master' into light_grandpa_importer2
svyatonik Feb 13, 2019
f94d5be
use DB backend in test client
svyatonik Feb 13, 2019
ac63880
justification_is_fetched_by_light_client_when_consensus_data_changes
svyatonik Feb 15, 2019
410d02c
Merge branch 'master' into light_grandpa_importer2
svyatonik Mar 7, 2019
8577c87
restore justification_is_fetched_by_light_client_when_consensus_data_…
svyatonik Mar 7, 2019
8a3ba3d
some more tests
svyatonik Mar 11, 2019
b362518
added authorities-related TODO
svyatonik Mar 11, 2019
4c69880
removed unneeded clear_finality_proof_requests field
svyatonik Mar 11, 2019
0db08a0
truncated some long lines
svyatonik Mar 11, 2019
1315130
more granular light import tests
svyatonik Mar 12, 2019
9e5aabe
only provide finality proof if it is generated by the requested set
svyatonik Mar 14, 2019
a746448
Merge branch 'master' into light_grandpa_importer2
svyatonik Mar 14, 2019
f22ebf1
post-merge fix
svyatonik Mar 14, 2019
c6c128b
finality_proof_is_none_if_first_justification_is_generated_by_unknown…
svyatonik Mar 14, 2019
188ab5a
make light+grandpa test rely on finality proofs (instead of simple ju…
svyatonik Mar 15, 2019
6d3ba01
empty_finality_proof_is_returned_to_light_client_when_authority_set_i…
svyatonik Mar 15, 2019
b99f39d
missing trait method impl
svyatonik Mar 19, 2019
5516ece
Merge branch 'master' into light_grandpa_importer2
svyatonik Mar 19, 2019
d6f01fa
fixed proof-of-finality docs
svyatonik Mar 20, 2019
957139f
one more doc fix
svyatonik Mar 20, 2019
262cdfa
fix docs
svyatonik Mar 20, 2019
7e6e837
Merge branch 'master' into light_grandpa_importer2
svyatonik Mar 22, 2019
271655d
Merge branch 'master' into light_grandpa_importer2
svyatonik Apr 1, 2019
63cde59
initialize authorities cache (post-merge fix)
svyatonik Apr 2, 2019
b8c71b5
fixed cache initialization (post-merge fix)
svyatonik Apr 16, 2019
63b5056
Merge branch 'master' into light_grandpa_importer2
svyatonik Apr 16, 2019
100f4c8
post-fix merge: fix light + GRANDPA tests (bad way)
svyatonik Apr 16, 2019
44d7714
proper fix of empty_finality_proof_is_returned_to_light_client_when_a…
svyatonik Apr 16, 2019
70c8b39
fixed easy grumbles
svyatonik Apr 18, 2019
ff3ceeb
import finality proofs in BlockImportWorker thread
svyatonik Apr 18, 2019
e108f63
allow import of finality proofs for non-requested blocks
svyatonik Apr 18, 2019
e2b5458
limit number of fragments in finality proof
svyatonik Apr 18, 2019
366cb2e
Merge branch 'master' into light_grandpa_importer2
svyatonik Apr 18, 2019
bf1706b
Merge branch 'master' into light_grandpa_importer2
svyatonik Apr 30, 2019
0a5513f
Merge branch 'master' into light_grandpa_importer2
svyatonik May 3, 2019
33d195c
GRANDPA post-merge fix
svyatonik May 3, 2019
d6cbbf3
BABE: pos-merge fix
svyatonik May 3, 2019
b7f2dbc
Merge branch 'master' into light_grandpa_importer2
svyatonik May 7, 2019
d42e730
Merge branch 'master' into light_grandpa_importer2
svyatonik May 10, 2019
fa0e328
Merge branch 'master' into light_grandpa_importer2
svyatonik May 10, 2019
6c80a6e
Merge branch 'master' into light_grandpa_importer2
svyatonik May 13, 2019
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
Prev Previous commit
Next Next commit
fixed cache initialization (post-merge fix)
  • Loading branch information
svyatonik committed Apr 16, 2019
commit b8c71b50aae4c3eccd2d0fe028c150e4f86fe77b
48 changes: 32 additions & 16 deletions core/client/db/src/cache/list_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ use log::warn;
use client::error::{ErrorKind as ClientErrorKind, Result as ClientResult};
use runtime_primitives::traits::{Block as BlockT, NumberFor, As, Zero};

use crate::cache::{CacheItemT, ComplexBlockId};
use crate::cache::{CacheItemT, ComplexBlockId, EntryType};
use crate::cache::list_entry::{Entry, StorageEntry};
use crate::cache::list_storage::{Storage, StorageTransaction, Metadata};

Expand Down Expand Up @@ -174,17 +174,18 @@ impl<Block: BlockT, T: CacheItemT, S: Storage<Block, T>> ListCache<Block, T, S>
parent: ComplexBlockId<Block>,
block: ComplexBlockId<Block>,
value: Option<T>,
is_final: bool,
entry_type: EntryType,
) -> ClientResult<Option<CommitOperation<Block, T>>> {
// this guarantee is currently provided by LightStorage && we're relying on it here
debug_assert!(!is_final || self.best_finalized_block.hash == parent.hash);
debug_assert!(entry_type != EntryType::Final || self.best_finalized_block.hash == parent.hash);

// we do not store any values behind finalized
if block.number != Zero::zero() && self.best_finalized_block.number >= block.number {
return Ok(None);
}

// if the block is not final, it is possibly appended to/forking from existing unfinalized fork
let is_final = entry_type == EntryType::Final || entry_type == EntryType::Genesis;
if !is_final {
let mut fork_and_action = None;

Expand Down Expand Up @@ -831,12 +832,27 @@ pub mod tests {

#[test]
fn list_on_block_insert_works() {
let nfin = EntryType::NonFinal;
let fin = EntryType::Final;

// when trying to insert block < finalized number
assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100))
.on_block_insert(&mut DummyTransaction::new(), test_id(49), test_id(50), Some(50), false).unwrap().is_none());
.on_block_insert(
&mut DummyTransaction::new(),
test_id(49),
test_id(50),
Some(50),
nfin,
).unwrap().is_none());
// when trying to insert block @ finalized number
assert!(ListCache::new(DummyStorage::new(), 1024, test_id(100))
.on_block_insert(&mut DummyTransaction::new(), test_id(99), test_id(100), Some(100), false).unwrap().is_none());
.on_block_insert(
&mut DummyTransaction::new(),
test_id(99),
test_id(100),
Some(100),
nfin,
).unwrap().is_none());

// when trying to insert non-final block AND it appends to the best block of unfinalized fork
// AND new value is the same as in the fork' best block
Expand All @@ -848,15 +864,15 @@ pub mod tests {
);
cache.unfinalized[0].best_block = Some(test_id(4));
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, test_id(4), test_id(5), Some(4), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, test_id(4), test_id(5), Some(4), nfin).unwrap(),
Some(CommitOperation::AppendNewBlock(0, test_id(5))));
assert!(tx.inserted_entries().is_empty());
assert!(tx.removed_entries().is_empty());
assert!(tx.updated_meta().is_none());
// when trying to insert non-final block AND it appends to the best block of unfinalized fork
// AND new value is the same as in the fork' best block
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, test_id(4), test_id(5), Some(5), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, test_id(4), test_id(5), Some(5), nfin).unwrap(),
Some(CommitOperation::AppendNewEntry(0, Entry { valid_from: test_id(5), value: Some(5) })));
assert_eq!(*tx.inserted_entries(), vec![test_id(5).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -872,15 +888,15 @@ pub mod tests {
1024, test_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(4), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(4), nfin).unwrap(),
Some(CommitOperation::AppendNewBlock(0, correct_id(5))));
assert!(tx.inserted_entries().is_empty());
assert!(tx.removed_entries().is_empty());
assert!(tx.updated_meta().is_none());
// when trying to insert non-final block AND it is the first block that appends to the best block of unfinalized fork
// AND new value is the same as in the fork' best block
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(5), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(4), correct_id(5), Some(5), nfin).unwrap(),
Some(CommitOperation::AppendNewEntry(0, Entry { valid_from: correct_id(5), value: Some(5) })));
assert_eq!(*tx.inserted_entries(), vec![correct_id(5).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -898,7 +914,7 @@ pub mod tests {
1024, correct_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(3), fork_id(0, 3, 4), Some(14), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(3), fork_id(0, 3, 4), Some(14), nfin).unwrap(),
Some(CommitOperation::AddNewFork(Entry { valid_from: fork_id(0, 3, 4), value: Some(14) })));
assert_eq!(*tx.inserted_entries(), vec![fork_id(0, 3, 4).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -913,7 +929,7 @@ pub mod tests {
1024, correct_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), false).unwrap(), None);
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), nfin).unwrap(), None);
assert!(tx.inserted_entries().is_empty());
assert!(tx.removed_entries().is_empty());
assert!(tx.updated_meta().is_none());
Expand All @@ -926,7 +942,7 @@ pub mod tests {
1024, correct_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), false).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), nfin).unwrap(),
Some(CommitOperation::AddNewFork(Entry { valid_from: correct_id(3), value: Some(3) })));
assert_eq!(*tx.inserted_entries(), vec![correct_id(3).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -935,7 +951,7 @@ pub mod tests {
// when inserting finalized entry AND there are no previous finalzed entries
let cache = ListCache::new(DummyStorage::new(), 1024, correct_id(2));
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), true).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), fin).unwrap(),
Some(CommitOperation::BlockFinalized(correct_id(3), Some(Entry { valid_from: correct_id(3), value: Some(3) }), Default::default())));
assert_eq!(*tx.inserted_entries(), vec![correct_id(3).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -948,14 +964,14 @@ pub mod tests {
1024, correct_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), true).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(),
Some(CommitOperation::BlockFinalized(correct_id(3), None, Default::default())));
assert!(tx.inserted_entries().is_empty());
assert!(tx.removed_entries().is_empty());
assert!(tx.updated_meta().is_none());
// when inserting finalized entry AND value differs from previous finalized
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), true).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(3), fin).unwrap(),
Some(CommitOperation::BlockFinalized(correct_id(3), Some(Entry { valid_from: correct_id(3), value: Some(3) }), Default::default())));
assert_eq!(*tx.inserted_entries(), vec![correct_id(3).hash].into_iter().collect());
assert!(tx.removed_entries().is_empty());
Expand All @@ -970,7 +986,7 @@ pub mod tests {
1024, correct_id(2)
);
let mut tx = DummyTransaction::new();
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), true).unwrap(),
assert_eq!(cache.on_block_insert(&mut tx, correct_id(2), correct_id(3), Some(2), fin).unwrap(),
Some(CommitOperation::BlockFinalized(correct_id(3), None, vec![0].into_iter().collect())));
}

Expand Down
23 changes: 18 additions & 5 deletions core/client/db/src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ mod list_storage;
/// Minimal post-finalization age age of finalized blocks before they'll pruned.
const PRUNE_DEPTH: u64 = 1024;

/// The type of entry that is inserted to the cache.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum EntryType {
/// Non-final entry.
NonFinal,
/// Final entry.
Final,
/// Genesis entry (inserted during cache initialization).
Genesis,
}

/// Block identifier that holds both hash and number.
#[derive(Clone, Debug, Encode, Decode, PartialEq)]
pub struct ComplexBlockId<Block: BlockT> {
Expand Down Expand Up @@ -190,7 +201,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
parent: ComplexBlockId<Block>,
block: ComplexBlockId<Block>,
data_at: HashMap<CacheKeyId, Vec<u8>>,
is_final: bool,
entry_type: EntryType,
) -> ClientResult<Self> {
assert!(self.cache_at_op.is_empty());

Expand All @@ -211,7 +222,7 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
parent.clone(),
block.clone(),
value.or(cache.value_at_block(&parent)?),
is_final,
entry_type,
)?;
if let Some(op) = op {
self.cache_at_op.insert(name, op);
Expand All @@ -222,8 +233,10 @@ impl<'a, Block: BlockT> DbCacheTransaction<'a, Block> {
data_at.into_iter().try_for_each(|(name, data)| insert_op(name, Some(data)))?;
missed_caches.into_iter().try_for_each(|name| insert_op(name, None))?;

if is_final {
self.best_finalized_block = Some(block);
match entry_type {
EntryType::Final | EntryType::Genesis =>
self.best_finalized_block = Some(block),
EntryType::NonFinal => (),
}

Ok(self)
Expand Down Expand Up @@ -273,7 +286,7 @@ impl<Block: BlockT> BlockchainCache<Block> for DbCacheSync<Block> {
ComplexBlockId::new(Default::default(), Zero::zero()),
ComplexBlockId::new(genesis_hash, Zero::zero()),
cache_contents,
true,
EntryType::Genesis,
)?;
let tx_ops = tx.into_ops();
db.write(dbtx).map_err(db_err)?;
Expand Down
24 changes: 22 additions & 2 deletions core/client/db/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use runtime_primitives::generic::BlockId;
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,
Zero, One, As, NumberFor, Digest, DigestItem};
use consensus_common::well_known_cache_keys;
use crate::cache::{DbCacheSync, DbCache, ComplexBlockId};
use crate::cache::{DbCacheSync, DbCache, ComplexBlockId, EntryType as CacheEntryType};
use crate::utils::{self, meta_keys, Meta, db_err, open_database,
read_db, block_id_to_lookup_key, read_meta};
use crate::DatabaseSettings;
Expand Down Expand Up @@ -436,7 +436,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
ComplexBlockId::new(*header.parent_hash(), if number.is_zero() { Zero::zero() } else { number - One::one() }),
ComplexBlockId::new(hash, number),
cache_at,
finalized,
if finalized { CacheEntryType::Final } else { CacheEntryType::NonFinal },
)?
.into_ops();

Expand Down Expand Up @@ -1042,4 +1042,24 @@ pub(crate) mod tests {
// leaves at same height stay. Leaves at lower heights pruned.
assert_eq!(db.leaves.read().hashes(), vec![block2_a, block2_b, block2_c]);
}

#[test]
fn cache_can_be_initialized_after_genesis_inserted() {
let db = LightStorage::<Block>::new_test();

// before cache is initialized => None
assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None);

// insert genesis block (no value for cache is provided)
insert_block(&db, HashMap::new(), || default_header(&Default::default(), 0));

// after genesis is inserted => None
assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), None);

// initialize cache
db.cache().initialize(b"test", vec![42]).unwrap();

// after genesis is inserted + cache is initialized => Some
assert_eq!(db.cache().get_at(b"test", &BlockId::Number(0)), Some(vec![42]));
}
}