grandpa: remove light-client specific block import pipeline (#7546)

* grandpa: remove light-client specific block import

* consensus, network: remove finality proofs
This commit is contained in:
André Silva
2020-11-23 14:28:55 +00:00
committed by GitHub
parent cd2490f56d
commit 1871a95088
44 changed files with 96 additions and 2512 deletions
+8 -178
View File
@@ -25,7 +25,7 @@ use sc_network_test::{
Block, BlockImportAdapter, Hash, PassThroughVerifier, Peer, PeersClient, PeersFullClient,
TestClient, TestNetFactory, FullPeerConfig,
};
use sc_network::config::{ProtocolConfig, BoxFinalityProofRequestBuilder};
use sc_network::config::ProtocolConfig;
use parking_lot::{RwLock, Mutex};
use futures_timer::Delay;
use tokio::runtime::{Runtime, Handle};
@@ -36,22 +36,21 @@ use sp_api::{ApiRef, StorageProof, ProvideRuntimeApi};
use substrate_test_runtime_client::runtime::BlockNumber;
use sp_consensus::{
BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport,
import_queue::{BoxJustificationImport, BoxFinalityProofImport},
import_queue::BoxJustificationImport,
};
use std::{collections::{HashMap, HashSet}, pin::Pin};
use parity_scale_codec::Decode;
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, HashFor};
use sp_runtime::generic::{BlockId, DigestItem};
use sp_core::{H256, crypto::Public};
use sp_core::H256;
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
use sp_finality_grandpa::{GRANDPA_ENGINE_ID, AuthorityList, EquivocationProof, GrandpaApi, OpaqueKeyOwnershipProof};
use sp_state_machine::{InMemoryBackend, prove_read, read_proof_check};
use authorities::AuthoritySet;
use finality_proof::{
FinalityProofProvider, AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker,
AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker,
};
use consensus_changes::ConsensusChanges;
use sc_block_builder::BlockBuilderProvider;
use sc_consensus::LongestChain;
use sc_keystore::LocalKeystore;
@@ -117,8 +116,6 @@ impl TestNetFactory for GrandpaTestNet {
-> (
BlockImportAdapter<Transaction>,
Option<BoxJustificationImport<Block>>,
Option<BoxFinalityProofImport<Block>>,
Option<BoxFinalityProofRequestBuilder<Block>>,
PeerData,
)
{
@@ -133,48 +130,15 @@ impl TestNetFactory for GrandpaTestNet {
(
BlockImportAdapter::new_full(import),
Some(justification_import),
None,
None,
Mutex::new(Some(link)),
)
},
PeersClient::Light(ref client, ref backend) => {
use crate::light_import::tests::light_block_import_without_justifications;
let authorities_provider = Arc::new(self.test_config.clone());
// forbid direct finalization using justification that came with the block
// => light clients will try to fetch finality proofs
let import = light_block_import_without_justifications(
client.clone(),
backend.clone(),
&self.test_config,
authorities_provider,
).expect("Could not create block import for fresh peer.");
let finality_proof_req_builder = import.0.create_finality_proof_request_builder();
let proof_import = Box::new(import.clone());
(
BlockImportAdapter::new_light(import),
None,
Some(proof_import),
Some(finality_proof_req_builder),
Mutex::new(None),
)
PeersClient::Light(..) => {
panic!("Light client is not used in tests.");
},
}
}
fn make_finality_proof_provider(
&self,
client: PeersClient
) -> Option<Arc<dyn sc_network::config::FinalityProofProvider<Block>>> {
match client {
PeersClient::Full(_, ref backend) => {
Some(Arc::new(FinalityProofProvider::new(backend.clone(), self.test_config.clone())))
},
PeersClient::Light(_, _) => None,
}
}
fn peer(&mut self, i: usize) -> &mut GrandpaPeer {
&mut self.peers[i]
}
@@ -679,24 +643,6 @@ fn transition_3_voters_twice_1_full_observer() {
block_until_complete(wait_for, &net, &mut runtime);
}
#[test]
fn justification_is_emitted_when_consensus_data_changes() {
let mut runtime = Runtime::new().unwrap();
let peers = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 3);
// import block#1 WITH consensus data change
let new_authorities = vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])];
net.peer(0).push_authorities_change_block(new_authorities);
net.block_until_sync();
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, 1, net.clone(), peers);
// ... and check that there's justification for block#1
assert!(net.lock().peer(0).client().justification(&BlockId::Number(1)).unwrap().is_some(),
"Missing justification for block#1");
}
#[test]
fn justification_is_generated_periodically() {
let mut runtime = Runtime::new().unwrap();
@@ -717,25 +663,6 @@ fn justification_is_generated_periodically() {
}
}
#[test]
fn consensus_changes_works() {
let mut changes = ConsensusChanges::<H256, u64>::empty();
// pending changes are not finalized
changes.note_change((10, H256::from_low_u64_be(1)));
assert_eq!(changes.finalize((5, H256::from_low_u64_be(5)), |_| Ok(None)).unwrap(), (false, false));
// no change is selected from competing pending changes
changes.note_change((1, H256::from_low_u64_be(1)));
changes.note_change((1, H256::from_low_u64_be(101)));
assert_eq!(changes.finalize((10, H256::from_low_u64_be(10)), |_| Ok(Some(H256::from_low_u64_be(1001)))).unwrap(), (true, false));
// change is selected from competing pending changes
changes.note_change((1, H256::from_low_u64_be(1)));
changes.note_change((1, H256::from_low_u64_be(101)));
assert_eq!(changes.finalize((10, H256::from_low_u64_be(10)), |_| Ok(Some(H256::from_low_u64_be(1)))).unwrap(), (true, true));
}
#[test]
fn sync_justifications_on_change_blocks() {
let mut runtime = Runtime::new().unwrap();
@@ -944,7 +871,6 @@ fn allows_reimporting_change_blocks() {
needs_justification: true,
clear_justification_requests: false,
bad_justification: false,
needs_finality_proof: false,
is_new_best: true,
header_only: false,
}),
@@ -1069,7 +995,7 @@ fn voter_persists_its_votes() {
Poll::Pending => return Poll::Pending,
Poll::Ready(None) => return Poll::Ready(()),
Poll::Ready(Some(())) => {
let (_block_import, _, _, _, link) =
let (_block_import, _, link) =
this.net.lock()
.make_block_import::<
TransactionFor<substrate_test_runtime_client::Backend, Block>
@@ -1144,7 +1070,7 @@ fn voter_persists_its_votes() {
};
let set_state = {
let (_, _, _, _, link) = net.lock()
let (_, _, link) = net.lock()
.make_block_import::<
TransactionFor<substrate_test_runtime_client::Backend, Block>
>(client);
@@ -1311,100 +1237,6 @@ fn finalize_3_voters_1_light_observer() {
});
}
#[test]
fn finality_proof_is_fetched_by_light_client_when_consensus_data_changes() {
sp_tracing::try_init_simple();
let mut runtime = Runtime::new().unwrap();
let peers = &[Ed25519Keyring::Alice];
let mut net = GrandpaTestNet::new(TestApi::new(make_ids(peers)), 1);
net.add_light_peer();
// import block#1 WITH consensus data change. Light client ignores justification
// && instead fetches finality proof for block #1
net.peer(0).push_authorities_change_block(vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]);
let net = Arc::new(Mutex::new(net));
run_to_completion(&mut runtime, 1, net.clone(), peers);
net.lock().block_until_sync();
// check that the block#1 is finalized on light client
runtime.block_on(futures::future::poll_fn(move |cx| {
if net.lock().peer(1).client().info().finalized_number == 1 {
Poll::Ready(())
} else {
net.lock().poll(cx);
Poll::Pending
}
}));
}
#[test]
fn empty_finality_proof_is_returned_to_light_client_when_authority_set_is_different() {
// for debug: to ensure that without forced change light client will sync finality proof
const FORCE_CHANGE: bool = true;
sp_tracing::try_init_simple();
let mut runtime = Runtime::new().unwrap();
// two of these guys are offline.
let genesis_authorities = if FORCE_CHANGE {
vec![
Ed25519Keyring::Alice,
Ed25519Keyring::Bob,
Ed25519Keyring::Charlie,
Ed25519Keyring::One,
Ed25519Keyring::Two,
]
} else {
vec![
Ed25519Keyring::Alice,
Ed25519Keyring::Bob,
Ed25519Keyring::Charlie,
]
};
let peers_a = &[Ed25519Keyring::Alice, Ed25519Keyring::Bob, Ed25519Keyring::Charlie];
let api = TestApi::new(make_ids(&genesis_authorities));
let voters = make_ids(peers_a);
let net = GrandpaTestNet::new(api, 3);
let net = Arc::new(Mutex::new(net));
// best is #1
net.lock().peer(0).generate_blocks(1, BlockOrigin::File, |builder| {
// add a forced transition at block 5.
let mut block = builder.build().unwrap().block;
if FORCE_CHANGE {
add_forced_change(&mut block, 0, ScheduledChange {
next_authorities: voters.clone(),
delay: 3,
});
}
block
});
// ensure block#10 enacts authorities set change => justification is generated
// normally it will reach light client, but because of the forced change, it will not
net.lock().peer(0).push_blocks(8, false); // best is #9
net.lock().peer(0).push_authorities_change_block(
vec![sp_consensus_babe::AuthorityId::from_slice(&[42; 32])]
); // #10
net.lock().peer(0).push_blocks(1, false); // best is #11
net.lock().block_until_sync();
// finalize block #11 on full clients
run_to_completion(&mut runtime, 11, net.clone(), peers_a);
// request finalization by light client
net.lock().add_light_peer();
net.lock().block_until_sync();
// check block, finalized on light client
assert_eq!(
net.lock().peer(3).client().info().finalized_number,
if FORCE_CHANGE { 0 } else { 10 },
);
}
#[test]
fn voter_catches_up_to_latest_round_when_behind() {
sp_tracing::try_init_simple();
@@ -1540,7 +1372,6 @@ where
{
let PersistentData {
ref authority_set,
ref consensus_changes,
ref set_state,
..
} = link.persistent_data;
@@ -1564,7 +1395,6 @@ where
Environment {
authority_set: authority_set.clone(),
config: config.clone(),
consensus_changes: consensus_changes.clone(),
client: link.client.clone(),
select_chain: link.select_chain.clone(),
set_id: authority_set.set_id(),