Cleaner GRANDPA RPC API for proving finality (#7339)

* grandpa: persist block number for last block of authority set

* grandpa: fix authority_set_changes field in tests

* grandpa: fix date on copyright notice

* grandpa-rpc: implement cleaner api for prove finality rpc

* grandpa-rpc: replace the old prove_finality with the new one

* grandpa: undo accidental whitespace change

* grandpa-rpc: start work on redo of the finality_proof RPC API

* grandpa: manual impl of Decode for AuthoritySet

* grandpa: add comment about appending changes for forced changes

* grandpa: flip order in set changes, tidy up some comments

* grandpa: update some of the doc comments

* grandpa: store authority set changes when applying forced changes

* grandpa: simplify finality_proof.rs

* grandpa: move checks and extend tests in finality_proof

* grandpa: address first set of review comments

* grandpa: check that set changes have well-defined start

* grandpa: rework prove_finality and assocated tests

* grandpa: make AuthoritySetChanges tuple struct

* grandpa: add assertions for tracking auth set changes

* grandpa: remove StorageAndProofProvider trait

* grandpa: return more informative results for unexpected input to RPC

* grandpa: tiny tweak to error msg

* grandpa: fix tests

* grandpa: add error specific to finality_proof

* grandpa: fix review comments

* grandpa: proper migration to new AuthoritySet

* grandpa: fix long lines

* grandpa: fix unused warning after merge

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Jon Häggblad
2021-01-21 23:06:40 +01:00
committed by GitHub
parent 87cc216774
commit 20f40fbd12
9 changed files with 855 additions and 925 deletions
+2 -44
View File
@@ -32,25 +32,20 @@ use tokio::runtime::{Runtime, Handle};
use sp_keyring::Ed25519Keyring;
use sc_client_api::backend::TransactionFor;
use sp_blockchain::Result;
use sp_api::{ApiRef, StorageProof, ProvideRuntimeApi};
use sp_api::{ApiRef, ProvideRuntimeApi};
use substrate_test_runtime_client::runtime::BlockNumber;
use sp_consensus::{
BlockOrigin, ForkChoiceStrategy, ImportedAux, BlockImportParams, ImportResult, BlockImport,
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::traits::{Block as BlockT, Header as HeaderT};
use sp_runtime::generic::{BlockId, DigestItem};
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::{
AuthoritySetForFinalityProver, AuthoritySetForFinalityChecker,
};
use sc_block_builder::BlockBuilderProvider;
use sc_consensus::LongestChain;
use sc_keystore::LocalKeystore;
@@ -207,43 +202,6 @@ impl GenesisAuthoritySetProvider<Block> for TestApi {
}
}
impl AuthoritySetForFinalityProver<Block> for TestApi {
fn authorities(&self, _block: &BlockId<Block>) -> Result<AuthorityList> {
Ok(self.genesis_authorities.clone())
}
fn prove_authorities(&self, block: &BlockId<Block>) -> Result<StorageProof> {
let authorities = self.authorities(block)?;
let backend = <InMemoryBackend<HashFor<Block>>>::from(vec![
(None, vec![(b"authorities".to_vec(), Some(authorities.encode()))])
]);
let proof = prove_read(backend, vec![b"authorities"])
.expect("failure proving read from in-memory storage backend");
Ok(proof)
}
}
impl AuthoritySetForFinalityChecker<Block> for TestApi {
fn check_authorities_proof(
&self,
_hash: <Block as BlockT>::Hash,
header: <Block as BlockT>::Header,
proof: StorageProof,
) -> Result<AuthorityList> {
let results = read_proof_check::<HashFor<Block>, _>(
*header.state_root(), proof, vec![b"authorities"]
)
.expect("failure checking read proof for authorities");
let encoded = results.get(&b"authorities"[..])
.expect("returned map must contain all proof keys")
.as_ref()
.expect("authorities in proof is None");
let authorities = Decode::decode(&mut &encoded[..])
.expect("failure decoding authorities read from proof");
Ok(authorities)
}
}
const TEST_GOSSIP_DURATION: Duration = Duration::from_millis(500);
fn make_ids(keys: &[Ed25519Keyring]) -> AuthorityList {