pub fn prove_finality<Block: BlockT, B, G>(
	blockchain: &B,
	generate_execution_proof: G,
	block: Block::Hash,
) -> ::client::error::Result<Option<Vec<u8>>>
	where
		B: BlockchainBackend<Block>,
		G: Fn(&BlockId<Block>, &str, &[u8]) -> ClientResult<Vec<Vec<u8>>>,
{
	let block_id = BlockId::Hash(block);
	let mut block_number = blockchain.expect_block_number_from_id(&block_id)?;

	// early-return if we sure that the block isn't finalized yet
	let info = blockchain.info()?;
	if info.finalized_number < block_number {
		return Ok(None);
	}

	// early-return if we sure that the block is NOT a part of canonical chain
	let canonical_block = blockchain.expect_block_hash_from_id(&BlockId::Number(block_number))?;
	if block != canonical_block {
		return Err(ClientErrorKind::Backend(
			"Cannot generate finality proof for non-canonical block".into()
		).into());
	}

	// now that we know that the block is finalized, we can generate finalization proof

	// we need to prove grandpa authorities set that has generated justification
	// BUT since `GrandpaApi::grandpa_authorities` call returns the set that becames actual
	// at the next block, the proof-of execution is generated using parent block' state
	// (this will fail if we're trying to prove genesis finality, but such the call itself is redundant)
	let mut current_header = blockchain.expect_header(BlockId::Hash(block))?;
	let parent_block_id = BlockId::Hash(*current_header.parent_hash());
	let authorities_proof = generate_execution_proof(
		&parent_block_id,
		"GrandpaApi_grandpa_authorities",
		&[],
	)?;

	// search for earliest post-block (inclusive) justification
	let mut finalization_path = Vec::new();
	loop {
		finalization_path.push(current_header);

		match blockchain.justification(BlockId::Number(block_number))? {
			Some(justification) => return Ok(Some(FinalityProof {
				finalization_path,
				justification,
				authorities_proof,
			}.encode())),
			None if block_number == info.finalized_number => break,
			None => {
				block_number = block_number + One::one();
				current_header = blockchain.expect_header(BlockId::Number(block_number))?;
			},
		}
	}

	Err(ClientErrorKind::Backend(
		"cannot find justification for finalized block".into()
	).into())
}
/// Prepare proof-of-finality for the given block.
///
/// The proof is the serialized `FinalityProof` constructed using earliest known
/// justification of the block. None is returned if there's no known justification atm.
Prepare proof-of-finality for the given block.
The proof is the serialized `FinalityProof` constructed using earliest known
justification of the block. None is returned if there's no known justification atm.
Prepare proof - of - finality for the given block . The proof is the serialized ` FinalityProof ` constructed using earliest known justification of the block . None is returned if there ' s no known justification atm .
pub fn prove_finality<Block: BlockT, B, G>(
	blockchain: &B,
	generate_execution_proof: G,
	block: Block::Hash,
) -> ::client::error::Result<Option<Vec<u8>>>
	where
		B: BlockchainBackend<Block>,
		G: Fn(&BlockId<Block>, &str, &[u8]) -> ClientResult<Vec<Vec<u8>>>,
{
	let block_id = BlockId::Hash(block);
	let mut block_number = blockchain.expect_block_number_from_id(&block_id)?;
	// early-return if we sure that the block isn't finalized yet
	let info = blockchain.info()?;
	if info.finalized_number < block_number {
		return Ok(None);
	}
	// early-return if we sure that the block is NOT a part of canonical chain
	let canonical_block = blockchain.expect_block_hash_from_id(&BlockId::Number(block_number))?;
	if block != canonical_block {
		return Err(ClientErrorKind::Backend(
			"Cannot generate finality proof for non-canonical block".into()
		).into());
	}
	// now that we know that the block is finalized, we can generate finalization proof
	// we need to prove grandpa authorities set that has generated justification
	// BUT since `GrandpaApi::grandpa_authorities` call returns the set that becames actual
	// at the next block, the proof-of execution is generated using parent block' state
	// (this will fail if we're trying to prove genesis finality, but such the call itself is redundant)
	let mut current_header = blockchain.expect_header(BlockId::Hash(block))?;
	let parent_block_id = BlockId::Hash(*current_header.parent_hash());
	let authorities_proof = generate_execution_proof(
		&parent_block_id,
		"GrandpaApi_grandpa_authorities",
		&[],
	)?;
	// search for earliest post-block (inclusive) justification
	let mut finalization_path = Vec::new();
	loop {
		finalization_path.push(current_header);
		match blockchain.justification(BlockId::Number(block_number))? {
			Some(justification) => return Ok(Some(FinalityProof {
				finalization_path,
				justification,
				authorities_proof,
			}.encode())),
			None if block_number == info.finalized_number => break,
			None => {
				block_number = block_number + One::one();
				current_header = blockchain.expect_header(BlockId::Number(block_number))?;
			},
		}
	}
	Err(ClientErrorKind::Backend(
		"cannot find justification for finalized block".into()
	).into())
}
pub fn prove_finality < Block : BlockT , B , G > ( blockchain : & B , generate_execution_proof : G , block : Block :: Hash , ) -> :: client :: error :: Result < Option < Vec < u8 > > > where B : BlockchainBackend < Block > , G : Fn ( & BlockId < Block > , & str , & [ u8 ] ) -> ClientResult < Vec < Vec < u8 > > > , { let block_id = BlockId :: Hash ( block ) ; let mut block_number = blockchain . expect_block_number_from_id ( & block_id ) ? ; // early-return if we sure that the block isn't finalized yet let info = blockchain . info ( ) ? ; if info . finalized_number < block_number { return Ok ( None ) ; } // early-return if we sure that the block is NOT a part of canonical chain let canonical_block = blockchain . expect_block_hash_from_id ( & BlockId :: Number ( block_number ) ) ? ; if block != canonical_block { return Err ( ClientErrorKind :: Backend ( " " . into ( ) ) . into ( ) ) ; } // now that we know that the block is finalized, we can generate finalization proof // we need to prove grandpa authorities set that has generated justification // BUT since `GrandpaApi::grandpa_authorities` call returns the set that becames actual // at the next block, the proof-of execution is generated using parent block' state // (this will fail if we're trying to prove genesis finality, but such the call itself is redundant) let mut current_header = blockchain . expect_header ( BlockId :: Hash ( block ) ) ? ; let parent_block_id = BlockId :: Hash ( * current_header . parent_hash ( ) ) ; let authorities_proof = generate_execution_proof ( & parent_block_id , " " , & [ ] , ) ? ; // search for earliest post-block (inclusive) justification let mut finalization_path = Vec :: new ( ) ; loop { finalization_path . push ( current_header ) ; match blockchain . justification ( BlockId :: Number ( block_number ) ) ? { Some ( justification ) => return Ok ( Some ( FinalityProof { finalization_path , justification , authorities_proof , } . encode ( ) ) ) , None if block_number == info . finalized_number => break , None => { block_number = block_number + One :: one ( ) ; current_header = blockchain . expect_header ( BlockId :: Number ( block_number ) ) ? ; } , } } Err ( ClientErrorKind :: Backend ( " " . into ( ) ) . into ( ) ) }
Prepare proof-of-finality for the given block.
Prepare proof - of - finality for the given block .
blockchain
&B
generate_execution_proof
G
block
Block::Hash
blockchain
&B
generate_execution_proof
G
block
Block::Hash