mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Fix invalid pre-fetched header broadcast (#8442)
Fixes and issue with Polygon validators where locally mined blocks are broadcast with invalid header hashes because the NewBlock message constructor was removing the ReceiptHash which contributed to the header hash. The results in the bor header validation code not being able to correctly identify the signer of the header - so header validation fails. This also likely fixes part of the bogon-block issue which was identified by the polygon team.
This commit is contained in:
parent
02032ada42
commit
6f7186e0f4
@ -399,6 +399,14 @@ func initDevnet(ctx *cli.Context, logger log.Logger) (devnet.Devnet, error) {
|
||||
},
|
||||
AccountSlots: 200,
|
||||
},
|
||||
/*args.BlockProducer{
|
||||
Node: args.Node{
|
||||
ConsoleVerbosity: "0",
|
||||
DirVerbosity: "5",
|
||||
HeimdallGRpc: heimdallGrpc,
|
||||
},
|
||||
AccountSlots: 200,
|
||||
},*/
|
||||
args.NonBlockProducer{
|
||||
Node: args.Node{
|
||||
ConsoleVerbosity: "0",
|
||||
|
@ -55,21 +55,20 @@ func (cs *MultiClient) BroadcastNewBlock(ctx context.Context, header *types.Head
|
||||
cs.lock.RLock()
|
||||
defer cs.lock.RUnlock()
|
||||
|
||||
txs := make([]types.Transaction, len(body.Transactions))
|
||||
for i, tx := range body.Transactions {
|
||||
var err error
|
||||
if txs[i], err = types.DecodeTransaction(tx); err != nil {
|
||||
log.Error("broadcastNewBlock", "err", err)
|
||||
return
|
||||
}
|
||||
block, err := types.RawBlock{Header: header, Body: body}.AsBlock()
|
||||
|
||||
if err != nil {
|
||||
log.Error("broadcastNewBlock", "err", err)
|
||||
}
|
||||
|
||||
data, err := rlp.EncodeToBytes(ð.NewBlockPacket{
|
||||
Block: types.NewBlock(header, txs, body.Uncles, nil, body.Withdrawals),
|
||||
Block: block,
|
||||
TD: td,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Error("broadcastNewBlock", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
req66 := proto_sentry.SendMessageToRandomPeersRequest{
|
||||
|
@ -306,7 +306,7 @@ func NewMultiClient(
|
||||
if err := hd.RecoverFromDb(db); err != nil {
|
||||
return nil, fmt.Errorf("recovery from DB failed: %w", err)
|
||||
}
|
||||
bd := bodydownload.NewBodyDownload(engine, blockBufferSize, int(syncCfg.BodyCacheLimit), blockReader)
|
||||
bd := bodydownload.NewBodyDownload(engine, blockBufferSize, int(syncCfg.BodyCacheLimit), blockReader, logger)
|
||||
|
||||
cs := &MultiClient{
|
||||
nodeName: nodeName,
|
||||
|
@ -261,6 +261,11 @@ func newValidator(t *testing.T, heimdall *test_heimdall, blocks map[uint64]*type
|
||||
validatorKey, _ := crypto.GenerateKey()
|
||||
validatorAddress := crypto.PubkeyToAddress(validatorKey.PublicKey)
|
||||
|
||||
/*fmt.Printf("Private: 0x%s\nPublic: 0x%s\nAddress: %s\n",
|
||||
hex.EncodeToString(crypto.FromECDSA(validatorKey)),
|
||||
hex.EncodeToString(crypto.MarshalPubkey(&validatorKey.PublicKey)),
|
||||
strings.ToLower(validatorAddress.Hex()))*/
|
||||
|
||||
if heimdall.validatorSet == nil {
|
||||
heimdall.validatorSet = valset.NewValidatorSet([]*valset.Validator{
|
||||
{
|
||||
|
@ -641,6 +641,22 @@ type RawBlock struct {
|
||||
Body *RawBody
|
||||
}
|
||||
|
||||
func (r RawBlock) AsBlock() (*Block, error) {
|
||||
b := &Block{header: r.Header}
|
||||
b.uncles = r.Body.Uncles
|
||||
b.withdrawals = r.Body.Withdrawals
|
||||
txs := make([]Transaction, len(r.Body.Transactions))
|
||||
|
||||
for i, tx := range r.Body.Transactions {
|
||||
var err error
|
||||
if txs[i], err = DecodeTransaction(tx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// Block represents an entire block in the Ethereum blockchain.
|
||||
type Block struct {
|
||||
header *Header
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/common/dbg"
|
||||
"github.com/ledgerwatch/erigon-lib/common/length"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/ledgerwatch/erigon/core/rawdb"
|
||||
@ -203,12 +202,12 @@ func (bd *BodyDownload) checkPrefetchedBlock(hash libcommon.Hash, tx kv.RwTx, bl
|
||||
// Calculate the TD of the block (it's not imported yet, so block.Td is not valid)
|
||||
if header.Difficulty.Sign() != 0 { // don't propagate proof-of-stake blocks
|
||||
if parent, err := rawdb.ReadTd(tx, header.ParentHash, header.Number.Uint64()-1); err != nil {
|
||||
log.Error("Failed to ReadTd", "err", err, "number", header.Number.Uint64()-1, "hash", header.ParentHash)
|
||||
bd.logger.Error("Failed to ReadTd", "err", err, "number", header.Number.Uint64()-1, "hash", header.ParentHash)
|
||||
} else if parent != nil {
|
||||
td := new(big.Int).Add(header.Difficulty, parent)
|
||||
go blockPropagator(context.Background(), header, body, td)
|
||||
} else {
|
||||
log.Error("Propagating dangling block", "number", header.Number.Uint64(), "hash", hash)
|
||||
bd.logger.Error("Propagating dangling block", "number", header.Number.Uint64(), "hash", hash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,16 +279,16 @@ Loop:
|
||||
}
|
||||
|
||||
if delivery.txs == nil {
|
||||
log.Warn("nil transactions delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
bd.logger.Warn("nil transactions delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
}
|
||||
if delivery.uncles == nil {
|
||||
log.Warn("nil uncles delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
bd.logger.Warn("nil uncles delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
}
|
||||
if delivery.withdrawals == nil {
|
||||
log.Warn("nil withdrawals delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
bd.logger.Warn("nil withdrawals delivered", "peer_id", delivery.peerID, "p2p_msg_len", delivery.lenOfP2PMessage)
|
||||
}
|
||||
if delivery.txs == nil || delivery.uncles == nil || delivery.withdrawals == nil {
|
||||
log.Debug("delivery body processing has been skipped due to nil tx|data")
|
||||
bd.logger.Debug("delivery body processing has been skipped due to nil tx|data")
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/length"
|
||||
"github.com/ledgerwatch/erigon/turbo/services"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
|
||||
"github.com/ledgerwatch/erigon/consensus"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
@ -51,6 +52,7 @@ type BodyDownload struct {
|
||||
bodyCacheLimit int // Limit of body Cache size
|
||||
blockBufferSize int
|
||||
br services.FullBlockReader
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// BodyRequest is a sketch of the request for block bodies, meaning that access to the database is required to convert it to the actual BlockBodies request (look up hashes of canonical blocks)
|
||||
@ -62,7 +64,7 @@ type BodyRequest struct {
|
||||
}
|
||||
|
||||
// NewBodyDownload create a new body download state object
|
||||
func NewBodyDownload(engine consensus.Engine, blockBufferSize, bodyCacheLimit int, br services.FullBlockReader) *BodyDownload {
|
||||
func NewBodyDownload(engine consensus.Engine, blockBufferSize, bodyCacheLimit int, br services.FullBlockReader, logger log.Logger) *BodyDownload {
|
||||
bd := &BodyDownload{
|
||||
requestedMap: make(map[TripleHash]uint64),
|
||||
bodyCacheLimit: bodyCacheLimit,
|
||||
@ -82,6 +84,7 @@ func NewBodyDownload(engine consensus.Engine, blockBufferSize, bodyCacheLimit in
|
||||
bodyCache: btree.NewG[BodyTreeItem](32, func(a, b BodyTreeItem) bool { return a.blockNum < b.blockNum }),
|
||||
br: br,
|
||||
blockBufferSize: blockBufferSize,
|
||||
logger: logger,
|
||||
}
|
||||
return bd
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ func TestCreateBodyDownload(t *testing.T) {
|
||||
tx, err := m.DB.BeginRo(m.Ctx)
|
||||
require.NoError(t, err)
|
||||
defer tx.Rollback()
|
||||
bd := bodydownload.NewBodyDownload(ethash.NewFaker(), 128, 100, m.BlockReader)
|
||||
bd := bodydownload.NewBodyDownload(ethash.NewFaker(), 128, 100, m.BlockReader, m.Log)
|
||||
if _, _, _, _, err := bd.UpdateFromDb(tx); err != nil {
|
||||
t.Fatalf("update from db: %v", err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user