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
some more tests
  • Loading branch information
svyatonik committed Mar 11, 2019
commit 8a3ba3dfdb993f56d0898bdc3ce38d66b726204d
131 changes: 101 additions & 30 deletions core/finality-grandpa/src/light_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use parking_lot::RwLock;

use client::{
CallExecutor, Client,
backend::Backend,
backend::{AuxStore, Backend},
blockchain::HeaderBackend,
error::Error as ClientError, error::ErrorKind as ClientErrorKind,
};
Expand Down Expand Up @@ -63,38 +63,11 @@ pub fn light_block_import<B, E, Block: BlockT<Hash=H256>, RA, PRA>(
PRA: ProvideRuntimeApi,
PRA::Api: GrandpaApi<Block>,
{
use runtime_primitives::traits::Zero;
let authority_set = match Backend::get_aux(&**client.backend(), LIGHT_AUTHORITY_SET_KEY)? {
None => {
info!(target: "afg", "Loading GRANDPA authorities \
from genesis on what appears to be first startup.");

// no authority set on disk: fetch authorities from genesis state
let genesis_authorities = api.runtime_api().grandpa_authorities(&BlockId::number(Zero::zero()))?;

let authority_set = LightAuthoritySet::genesis(genesis_authorities);
let encoded = authority_set.encode();
Backend::insert_aux(&**client.backend(), &[(LIGHT_AUTHORITY_SET_KEY, &encoded[..])], &[])?;

authority_set
},
Some(raw) => LightAuthoritySet::decode(&mut &raw[..])
.ok_or_else(|| ::client::error::ErrorKind::Backend(
format!("GRANDPA authority set kept in invalid format")
))?
.into(),
};

let consensus_changes = load_decode(&**client.backend(), LIGHT_CONSENSUS_CHANGES_KEY)?
.unwrap_or_else(ConsensusChanges::<Block::Hash, NumberFor<Block>>::empty);

let import_data = load_aux_import_data(&**client.backend(), api)?;
Ok(GrandpaLightBlockImport {
client,
authority_set_provider,
data: Arc::new(RwLock::new(LightImportData {
authority_set,
consensus_changes,
})),
data: Arc::new(RwLock::new(import_data)),
})
}

Expand Down Expand Up @@ -436,6 +409,52 @@ fn do_finalize_block<B, E, Block: BlockT<Hash=H256>, RA>(
Ok(ImportResult::imported())
}

/// Load light impoty aux data from the store.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Load light impoty aux data from the store.
/// Load light import aux data from the store.

fn load_aux_import_data<B, Block: BlockT<Hash=H256>, PRA>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move to aux_schema?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that aux_schema is already bloated a bit, now as it supports version migrations. I.e it will be bigger than light_import.rs if we'll move this. I could move to new aux_schema_light.rs, if you insist, though.

aux_store: &B,
api: Arc<PRA>,
) -> Result<LightImportData<Block>, ClientError>
where
B: AuxStore,
PRA: ProvideRuntimeApi,
PRA::Api: GrandpaApi<Block>,
{
use runtime_primitives::traits::Zero;
let authority_set = match load_decode(aux_store, LIGHT_AUTHORITY_SET_KEY)? {
Some(authority_set) => authority_set,
None => {
info!(target: "afg", "Loading GRANDPA authorities \
from genesis on what appears to be first startup.");

// no authority set on disk: fetch authorities from genesis state
let genesis_authorities = api.runtime_api().grandpa_authorities(&BlockId::number(Zero::zero()))?;

let authority_set = LightAuthoritySet::genesis(genesis_authorities);
let encoded = authority_set.encode();
aux_store.insert_aux(&[(LIGHT_AUTHORITY_SET_KEY, &encoded[..])], &[])?;

authority_set
},
};

let consensus_changes = match load_decode(aux_store, LIGHT_CONSENSUS_CHANGES_KEY)? {
Some(consensus_changes) => consensus_changes,
None => {
let consensus_changes = ConsensusChanges::<Block::Hash, NumberFor<Block>>::empty();

let encoded = authority_set.encode();
aux_store.insert_aux(&[(LIGHT_CONSENSUS_CHANGES_KEY, &encoded[..])], &[])?;

consensus_changes
},
};

Ok(LightImportData {
authority_set,
consensus_changes,
})
}

/// Insert into aux store. If failed, return error && show inconsistency warning.
fn require_insert_aux<T: Encode, B, E, Block: BlockT<Hash=H256>, RA>(
client: &Client<B, E, Block, RA>,
Expand Down Expand Up @@ -463,3 +482,55 @@ fn on_post_finalization_error(error: ClientError, value_type: &str) -> Consensus
warn!(target: "finality", "Node is in a potentially inconsistent state.");
ConsensusError::from(ConsensusErrorKind::ClientImport(error.to_string()))
}

#[cfg(test)]
mod tests {
use super::*;
use substrate_primitives::H256;
use test_client::client::in_mem::Blockchain as InMemoryAuxStore;
use test_client::runtime::Block;
use crate::tests::TestApi;

#[test]
fn aux_data_updated_on_start() {
let aux_store = InMemoryAuxStore::<Block>::new();
let api = Arc::new(TestApi::new(vec![(Ed25519AuthorityId([1; 32]), 1)]));

// when aux store is empty initially
assert!(aux_store.get_aux(LIGHT_AUTHORITY_SET_KEY).unwrap().is_none());
assert!(aux_store.get_aux(LIGHT_CONSENSUS_CHANGES_KEY).unwrap().is_none());

// it is updated on importer start
load_aux_import_data(&aux_store, api).unwrap();
assert!(aux_store.get_aux(LIGHT_AUTHORITY_SET_KEY).unwrap().is_some());
assert!(aux_store.get_aux(LIGHT_CONSENSUS_CHANGES_KEY).unwrap().is_some());
}

#[test]
fn aux_data_loaded_on_restart() {
let aux_store = InMemoryAuxStore::<Block>::new();
let api = Arc::new(TestApi::new(vec![(Ed25519AuthorityId([1; 32]), 1)]));

// when aux store is non-empty initially
let mut consensus_changes = ConsensusChanges::<H256, u64>::empty();
consensus_changes.note_change((42, Default::default()));
aux_store.insert_aux(
&[
(
LIGHT_AUTHORITY_SET_KEY,
LightAuthoritySet::genesis(vec![(Ed25519AuthorityId([42; 32]), 2)]).encode().as_slice(),
),
(
LIGHT_CONSENSUS_CHANGES_KEY,
consensus_changes.encode().as_slice(),
),
],
&[],
).unwrap();

// importer uses it on start
let data = load_aux_import_data(&aux_store, api).unwrap();
assert_eq!(data.authority_set.authorities(), vec![(Ed25519AuthorityId([42; 32]), 2)]);
assert_eq!(data.consensus_changes.pending_changes(), &[(42, Default::default())]);
}
}
14 changes: 5 additions & 9 deletions core/finality-grandpa/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,14 @@ impl Network<Block> for MessageRouting {
}

#[derive(Default, Clone)]
struct TestApi {
pub(crate) struct TestApi {
genesis_authorities: Vec<(Ed25519AuthorityId, u64)>,
scheduled_changes: Arc<Mutex<HashMap<Hash, ScheduledChange<BlockNumber>>>>,
forced_changes: Arc<Mutex<HashMap<Hash, (BlockNumber, ScheduledChange<BlockNumber>)>>>,
}

impl TestApi {
fn new(genesis_authorities: Vec<(Ed25519AuthorityId, u64)>) -> Self {
pub fn new(genesis_authorities: Vec<(Ed25519AuthorityId, u64)>) -> Self {
TestApi {
genesis_authorities,
scheduled_changes: Arc::new(Mutex::new(HashMap::new())),
Expand All @@ -277,7 +277,7 @@ impl TestApi {
}
}

struct RuntimeApi {
pub(crate) struct RuntimeApi {
inner: TestApi,
}

Expand Down Expand Up @@ -352,11 +352,7 @@ impl GrandpaApi<Block> for RuntimeApi {
_: Option<()>,
_: Vec<u8>,
) -> Result<NativeOrEncoded<Vec<(Ed25519AuthorityId, u64)>>> {
// if at == &BlockId::Number(0) {
Ok(self.inner.genesis_authorities.clone()).map(NativeOrEncoded::Native)
/* } else {
panic!("should generally only request genesis authorities")
}*/
Ok(self.inner.genesis_authorities.clone()).map(NativeOrEncoded::Native)
}

fn grandpa_pending_change_runtime_api_impl(
Expand Down Expand Up @@ -1060,7 +1056,7 @@ fn justification_is_fetched_by_light_client_when_consensus_data_changes() {
let _ = ::env_logger::try_init();

let peers = &[Keyring::Alice];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1);
let net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1);

// import block#1 WITH consensus data change + ensure if is finalized (with justification)
let new_authorities = vec![Ed25519AuthorityId::from([42; 32])];
Expand Down