Skip to content

Optimize fastsync process #2622

@goolAdapter

Description

@goolAdapter

Currently fastsync build block by PeekTwoBlocks,if VerifyCommit fail,It'll disconnect both block's peer (ref #2457 ) and try fetch block from other peers.

first, second := bcR.pool.PeekTwoBlocks()
//bcR.Logger.Info("TrySync peeked", "first", first, "second", second)
if first == nil || second == nil {
// We need both to sync the first block.
continue FOR_LOOP
} else {
// Try again quickly next loop.
didProcessCh <- struct{}{}
}
firstParts := first.MakePartSet(types.BlockPartSizeBytes)
firstPartsHeader := firstParts.Header()
firstID := types.BlockID{first.Hash(), firstPartsHeader}
// Finally, verify the first block using the second's commit
// NOTE: we can probably make this more efficient, but note that calling
// first.Hash() doesn't verify the tx contents, so MakePartSet() is
// currently necessary.
err := state.Validators.VerifyCommit(
chainID, firstID, first.Height, second.LastCommit)
if err != nil {

This is inefficient, and once there is an malicious peer send two block which can pass VerifyCommit,fastsync will panic when ApplyBlock.

// TODO: batch saves so we dont persist to disk every block
bcR.store.SaveBlock(first, firstParts, second.LastCommit)
// TODO: same thing for app - but we would need a way to
// get the hash without persisting the state
var err error
state, err = bcR.blockExec.ApplyBlock(state, firstID, first)
if err != nil {
// TODO This is bad, are we zombie?
cmn.PanicQ(fmt.Sprintf("Failed to process committed block (%d:%X): %v",
first.Height, first.Hash(), err))
}

Was it can just PeekNextBlock,and try verify it with the latest block(for height 1, it was genesis),this could indicate which block is wrong #2489 (comment)

I have write a test case to show the condition:

Running tool: /usr/bin/go test -timeout 30s github.com/tendermint/tendermint/blockchain -run ^TestBadBlockPeer$

panic: Panicked questionably: Failed to process committed block (1:83BDC43F11F110373A4E4494A599F68895B133A3): Wrong Block.Header.ValidatorsHash.  Expected 3286812CA7377B35AF3B52B51E291F6A9D721EEF, got 3D045F7BA9EA70FBF2B0C641876F0CB147923A68

Metadata

Metadata

Assignees

No one assigned

    Labels

    C:syncComponent: Fast Sync, State SyncT:perfType: Performancestalefor use by stalebot

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions