diff --git a/cmd/sentry/sentry/downloader.go b/cmd/sentry/sentry/downloader.go index cd617ad94098e87148d066ec358b8990c67f86db..77542a5d04144f9a62de73ed6ca7b512bd5dd64c 100644 --- a/cmd/sentry/sentry/downloader.go +++ b/cmd/sentry/sentry/downloader.go @@ -555,7 +555,7 @@ func (cs *ControlServerImpl) newBlock66(ctx context.Context, inreq *proto_sentry return fmt.Errorf("newBlock66: %w", err) } - if segments, penalty, err := cs.Hd.SingleHeaderAsSegment(headerRaw, request.Block.Header()); err == nil { + if segments, penalty, err := cs.Hd.SingleHeaderAsSegment(headerRaw, request.Block.Header(), true /* penalizePoSBlocks */); err == nil { if penalty == headerdownload.NoPenalty { cs.Hd.ProcessSegment(segments[0], true /* newBlock */, ConvertH512ToPeerID(inreq.PeerId)) // There is only one segment in this case } else { diff --git a/turbo/stages/bodydownload/body_algos.go b/turbo/stages/bodydownload/body_algos.go index f8b4cac250f1c86160cb35190ca198123a6d627a..30a1caf523f8fa26924a4794faab66bba921f2c1 100644 --- a/turbo/stages/bodydownload/body_algos.go +++ b/turbo/stages/bodydownload/body_algos.go @@ -133,12 +133,13 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader interfaces.Ful bd.deliveriesB[blockNum-bd.requestedLow] = block.RawBody() // Calculate the TD of the block (it's not imported yet, so block.Td is not valid) - var td *big.Int if parent, err := rawdb.ReadTd(tx, block.ParentHash(), block.NumberU64()-1); err != nil { log.Error("Failed to ReadTd", "err", err, "number", block.NumberU64()-1, "hash", block.ParentHash()) } else if parent != nil { - td = new(big.Int).Add(block.Difficulty(), parent) - go blockPropagator(context.Background(), block, td) + if block.Difficulty().Sign() != 0 { // don't propagate proof-of-stake blocks + td := new(big.Int).Add(block.Difficulty(), parent) + go blockPropagator(context.Background(), block, td) + } } else { log.Error("Propagating dangling block", "number", block.Number(), "hash", hash) } diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 9deab0df1b63629c46a48e23e948714b98bcd388..ec7607b73bbece4d79d84b03cd142e97bad791eb 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -131,7 +131,7 @@ func (hd *HeaderDownload) childParentValid(child, parent *types.Header) (bool, P } // SingleHeaderAsSegment converts message containing 1 header into one singleton chain segment -func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types.Header) ([]ChainSegment, Penalty, error) { +func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types.Header, penalizePoSBlocks bool) ([]ChainSegment, Penalty, error) { hd.lock.RLock() defer hd.lock.RUnlock() @@ -139,6 +139,9 @@ func (hd *HeaderDownload) SingleHeaderAsSegment(headerRaw []byte, header *types. if _, bad := hd.badHeaders[headerHash]; bad { return nil, BadBlockPenalty, nil } + if penalizePoSBlocks && header.Difficulty.Sign() == 0 { + return nil, NewBlockGossipAfterMergePenalty, nil + } h := ChainSegmentHeader{ Header: header, HeaderRaw: headerRaw, @@ -1356,7 +1359,7 @@ func (hd *HeaderDownload) AddMinedHeader(header *types.Header) error { if err := header.EncodeRLP(buf); err != nil { return err } - segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), header) + segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), header, false /* penalizePoSBlocks */) if err != nil { return err } diff --git a/turbo/stages/headerdownload/header_data_struct.go b/turbo/stages/headerdownload/header_data_struct.go index d2da1eebfac6cec4ec0de563ee5b3d30bc0902c6..619d8f42883ffdf7df17854cc0efdcf5485d6873 100644 --- a/turbo/stages/headerdownload/header_data_struct.go +++ b/turbo/stages/headerdownload/header_data_struct.go @@ -180,6 +180,7 @@ const ( TooFarFuturePenalty TooFarPastPenalty AbandonedAnchorPenalty + NewBlockGossipAfterMergePenalty ) type PeerPenalty struct { @@ -355,6 +356,8 @@ func (p Penalty) String() string { return "TooFarFuture" case TooFarPastPenalty: return "TooFarPast" + case NewBlockGossipAfterMergePenalty: + return "NewBlockGossipAfterMerge" default: return fmt.Sprintf("Unknown(%d)", p) } diff --git a/turbo/stages/headerdownload/header_test.go b/turbo/stages/headerdownload/header_test.go index 8c16ebac71afeaa1ec051a258bde9405fcd32731..59aec92e1601115393633e625a5885f415bad85f 100644 --- a/turbo/stages/headerdownload/header_test.go +++ b/turbo/stages/headerdownload/header_test.go @@ -166,7 +166,7 @@ func TestSingleHeaderAsSegment(t *testing.T) { var h types.Header h.Number = big.NewInt(5) headerRaw, _ := rlp.EncodeToBytes(h) - if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h); err == nil { + if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h, false /* penalizePoSBlocks */); err == nil { if penalty != NoPenalty { t.Errorf("unexpected penalty: %s", penalty) } @@ -185,7 +185,7 @@ func TestSingleHeaderAsSegment(t *testing.T) { // Same header with a bad hash hd.ReportBadHeader(h.Hash()) - if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h); err == nil { + if chainSegments, penalty, err := hd.SingleHeaderAsSegment(headerRaw, &h, false /* penalizePoSBlocks */); err == nil { if penalty != BadBlockPenalty { t.Errorf("expected BadBlock penalty, got %s", penalty) }