5

I have written a simple block import that wraps grandpa block import, it does tiny verification and calls grandpa block import after that, it looks like this:

pub struct CustomBlockImport<I> {
    grandpa_block_import: I,
}
#[async_trait::async_trait]
impl<I: sc_consensus::BlockImport<Block>> sc_consensus::BlockImport<Block> for WitnessBlockImport<I>
where
    I: Send,
{
    type Error = ConsensusError;
    type Transaction = I::Transaction;

    async fn check_block(
        &mut self,
        block: BlockCheckParams<Block>,
    ) -> Result<ImportResult, Self::Error> {
return self
                .grandpa_block_import
                .import_block(block, cache)
                .await
                .map_err(|e| ConsensusError::ClientImport(format!("{}", e)))
    }

    async fn import_block(
        &mut self,
        block: BlockImportParams<Block, Self::Transaction>,
        cache: HashMap<well_known_cache_keys::Id, Vec<u8>>,
    ) -> Result<ImportResult, Self::Error> {
// if block is already finalized no need for my custom verification, just run grandpa block import      
if block.finalized {
            log::info!("block already finalized");
return self
                .grandpa_block_import
                .import_block(block, cache)
                .await
                .map_err(|e| ConsensusError::ClientImport(format!("{}", e)))
        }
        // do some verification
        return self
            .grandpa_block_import
            .import_block(block, cache)
            .await
            .map_err(|e| ConsensusError::ClientImport(format!("{}", e)))
    }
}

I tried using block.finalized field to detect whether its already finalized or not however in my simple network, I start three authorities (Alice, Bob, Charlie) and delay running the final authority (Dave) after quite some time (so that the first three get to finalize some blocks); when I start the Dave node, it does not log block already finalized as it should, instead it goes and do my custom verification logic.

why is this happening and how to solve this?

1
  • Removing my comment as @bkchr's answer is correct
    – Bruno
    Apr 4 at 21:14

1 Answer 1

2

block.finalized is only set by manual-seal to instant finalize a block.

There is no definitive way to check if a block is already finalized on block import. You could check if justifications is Some(_), but even that would only be the case for the blocks where the authority set changed and thus, we have a justification.

When importing blocks at the tip of the chain, they will also not be directly finalized. It takes some time until blocks are finalized.

You could check after calling grandpa.block_import, if the block is finalized. However, as I said above only every Xth block that enacts an authority set would be finalized.

6
  • Are justifications only to be found in blocks with authority set changes? Apr 5 at 7:33
  • When doing a full sync yes. At the tip of the chain we always keep the justification of the latest finalized block as well.
    – bkchr
    Apr 5 at 8:13
  • Apologies, I missed the context of the question. But to clarify; when a node has to sync with the network it can determine the finality of a block instantly if there were authority set changes in that particular block. Otherwise it will find the justification, that finalizes the block, at a later block (doesn't have to be a block with authority set changes), correct? Apr 5 at 9:05
  • 1
    When you finalize block X later and Y is an ancestor of it, Y will be finalized as well. > Otherwise it will find the justification, that finalizes the block, at a later block (doesn't have to be a block with authority set changes), correct? So, yes!
    – bkchr
    Apr 5 at 14:09
  • so basically the information that a block is finalized is most of the time off-chain and sometimes on-chain with the justification field, so my question is, how would clients (simple users) would know whether a block is finalized or not since they can't rely on justifications
    – dadzerlaze
    Apr 6 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.