-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Closed as not planned
Labels
C:syncComponent: Fast Sync, State SyncComponent: Fast Sync, State SyncT:perfType: PerformanceType: Performancestalefor use by stalebotfor use by stalebot
Milestone
Description
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.
tendermint/blockchain/reactor.go
Lines 283 to 302 in 0c9c329
| 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.
tendermint/blockchain/reactor.go
Lines 315 to 326 in 0c9c329
| // 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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
C:syncComponent: Fast Sync, State SyncComponent: Fast Sync, State SyncT:perfType: PerformanceType: Performancestalefor use by stalebotfor use by stalebot