Skip to content

Commit 8370816

Browse files
committed
dbft: do not relay extensibles if unable to validate sender
It's easy to spam the network via syncing node since it's not able to validate consensus messages. Thus, do not relay dBFT extensible if the node isn't able to properly verify it. Signed-off-by: Anna Shaleva <[email protected]>
1 parent 5019c60 commit 8370816

File tree

6 files changed

+25
-14
lines changed

6 files changed

+25
-14
lines changed

consensus/dbft/dbft.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,19 +1517,21 @@ func (c *DBFT) validatePayload(p *Payload) error {
15171517

15181518
// IsExtensibleAllowed determines if address is allowed to send extensible payloads
15191519
// (only consensus payloads for now) at the specified height.
1520-
func (c *DBFT) IsExtensibleAllowed(h uint64, u common.Address) bool {
1520+
func (c *DBFT) IsExtensibleAllowed(h uint64, u common.Address) error {
15211521
// Can't verify extensible sender if the node has an outdated state.
15221522
if c.syncing.Load() {
1523-
return true
1523+
return dbftproto.ErrSyncing
15241524
}
15251525
// Only validators are included into extensible whitelist for now.
15261526
validators, err := c.getValidators(&h, nil, nil)
15271527
if err != nil {
1528-
return false
1528+
return fmt.Errorf("failed to get validators: %w", err)
15291529
}
15301530
n := sort.Search(len(validators), func(i int) bool { return validators[i].Cmp(u) >= 0 })
1531-
res := n < len(validators)
1532-
return res
1531+
if n >= len(validators) {
1532+
return fmt.Errorf("address is not a validator")
1533+
}
1534+
return nil
15331535
}
15341536

15351537
func (c *DBFT) newPayload(ctx *dbft.Context[common.Hash], t dbft.MessageType, msg any) dbft.ConsensusPayload[common.Hash] {

eth/backend.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
276276
var (
277277
bft *dbft.DBFT
278278
onPayload func(*dbftproto.Message) error
279-
isExtensibleAllowed func(uint64, common.Address) bool
279+
isExtensibleAllowed func(uint64, common.Address) error
280280
)
281281
switch t := eth.engine.(type) {
282282
case *dbft.DBFT:

eth/protocols/dbft/handler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ const (
3434
maxMessageSize = 4 * 1024 * 1024
3535
)
3636

37+
// ErrSyncing is returned when operation can't be performed due to the fact that
38+
// the node is in the process of chain sync.
39+
var ErrSyncing = errors.New("node is syncing")
40+
3741
var (
3842
errMsgTooLarge = errors.New("message too long")
3943
errDecode = errors.New("invalid message")

eth/protocols/dbft/ledger.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import (
1010

1111
type ledger struct {
1212
bc BlockChainAPI
13-
isExtensibleAllowed func(height uint64, addr common.Address) bool
13+
isExtensibleAllowed func(height uint64, addr common.Address) error
1414
}
1515

16-
func newLedger(bc BlockChainAPI, isExtensibleAllowed func(uint64, common.Address) bool) *ledger {
16+
func newLedger(bc BlockChainAPI, isExtensibleAllowed func(uint64, common.Address) error) *ledger {
1717
return &ledger{
1818
bc: bc,
1919
isExtensibleAllowed: isExtensibleAllowed,
@@ -24,6 +24,6 @@ func (l *ledger) BlockHeight() uint64 {
2424
return uint64(l.bc.BlockNumber())
2525
}
2626

27-
func (l *ledger) IsAddressAllowed(addr common.Address) bool {
27+
func (l *ledger) IsAddressAllowed(addr common.Address) error {
2828
return l.isExtensibleAllowed(l.BlockHeight(), addr)
2929
}

eth/protocols/dbft/pool.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
// Ledger is enough of Blockchain to satisfy Pool.
1515
type Ledger interface {
1616
BlockHeight() uint64
17-
IsAddressAllowed(common.Address) bool
17+
IsAddressAllowed(common.Address) error
1818
}
1919

2020
// Pool represents a pool of extensible payloads.
@@ -90,8 +90,13 @@ func (p *Pool) verify(m *Message) (bool, error) {
9090
}
9191
return false, errInvalidHeight
9292
}
93-
if !p.chain.IsAddressAllowed(m.Sender) {
94-
return false, errDisallowedSender
93+
err = p.chain.IsAddressAllowed(m.Sender)
94+
if err != nil {
95+
// There's no reliable way to check sender for syncing node.
96+
if errors.Is(err, ErrSyncing) {
97+
return false, nil
98+
}
99+
return false, err
95100
}
96101
return true, nil
97102
}
@@ -120,7 +125,7 @@ func (p *Pool) RemoveStale(index uint64) {
120125
old := elem
121126
elem = elem.Next()
122127

123-
if m.ValidBlockEnd <= index || !p.chain.IsAddressAllowed(m.Sender) {
128+
if m.ValidBlockEnd <= index || p.chain.IsAddressAllowed(m.Sender) != nil {
124129
delete(p.verified, h)
125130
lst.Remove(old)
126131
continue

eth/protocols/dbft/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ type Service struct {
3636
}
3737

3838
// New creates a new instance of [Service].
39-
func New(bc BlockChainAPI, onPayload func(*Message) error, isExtensibleAllowed func(uint64, common.Address) bool) *Service {
39+
func New(bc BlockChainAPI, onPayload func(*Message) error, isExtensibleAllowed func(uint64, common.Address) error) *Service {
4040
poolLedger := newLedger(bc, isExtensibleAllowed)
4141
return &Service{
4242
bc: bc,

0 commit comments

Comments
 (0)