Skip to content

Commit

Permalink
Error blocks too far in the future and add new errors to error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
mvandeberg committed Jul 18, 2022
1 parent 78d52b4 commit 989920e
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 46 deletions.
3 changes: 3 additions & 0 deletions internal/options/block_applicator_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package options

const (
maxPendingBlocksDefault = 2500
maxHeightDeltaDefault = 10
)

// BlockApplicatorOptions are options for BlockApplicator
type BlockApplicatorOptions struct {
MaxPendingBlocks uint64
MaxHeightDelta uint64
}

// NewBlockApplicatorOptions returns default initialized BlockApplicatorOptions
func NewBlockApplicatorOptions() *BlockApplicatorOptions {
return &BlockApplicatorOptions{
MaxPendingBlocks: maxPendingBlocksDefault,
MaxHeightDelta: maxHeightDeltaDefault,
}
}
97 changes: 53 additions & 44 deletions internal/options/error_handler_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,70 @@ const (
errorScoreDecayHalflifeDefault = time.Minute * 10
errorScoreThresholdDefault = 100000

deserializationErrorScoreDefault = 5000
serializationErrorScoreDefault = 0
blockIrreversibilityErrorScoreDefault = 100
blockApplicationErrorScoreDefault = 5000
transactionApplicationErrorScoreDefault = 1000
chainIDMismatchErrorScoreDefault = uint64(math.MaxUint32)
chainNotConnectedErrorScoreDefault = uint64(math.MaxUint32)
checkpointMismatchErrorScoreDefault = uint64(math.MaxUint32)
localRPCErrorScoreDefault = 0
peerRPCErrorScoreDefault = 1000
localRPCTimeoutErrorScoreDefault = 0
peerRPCTimeoutErrorScoreDefault = 1000
processRequestTimeoutErrorScoreDefault = 0
unknownErrorScoreDefault = blockApplicationErrorScoreDefault
deserializationErrorScoreDefault = 5000
serializationErrorScoreDefault = 0
blockIrreversibilityErrorScoreDefault = 100
blockApplicationErrorScoreDefault = 5000
unknownPreviousBlockErrorScoreDefault = 5000
blockApplicationTimeoutErrorScoreDefault = 5000
maxPendingBlocksErrorScoreDefault = 1000
transactionApplicationErrorScoreDefault = 1000
chainIDMismatchErrorScoreDefault = uint64(math.MaxUint32)
chainNotConnectedErrorScoreDefault = uint64(math.MaxUint32)
checkpointMismatchErrorScoreDefault = uint64(math.MaxUint32)
localRPCErrorScoreDefault = 0
peerRPCErrorScoreDefault = 1000
localRPCTimeoutErrorScoreDefault = 0
peerRPCTimeoutErrorScoreDefault = 1000
processRequestTimeoutErrorScoreDefault = 0
unknownErrorScoreDefault = blockApplicationErrorScoreDefault
)

// PeerErrorHandlerOptions are options for PeerErrorHandler
type PeerErrorHandlerOptions struct {
ErrorScoreDecayHalflife time.Duration
ErrorScoreThreshold uint64

DeserializationErrorScore uint64
SerializationErrorScore uint64
BlockIrreversibilityErrorScore uint64
BlockApplicationErrorScore uint64
TransactionApplicationErrorScore uint64
ChainIDMismatchErrorScore uint64
ChainNotConnectedErrorScore uint64
CheckpointMismatchErrorScore uint64
LocalRPCErrorScore uint64
PeerRPCErrorScore uint64
LocalRPCTimeoutErrorScore uint64
PeerRPCTimeoutErrorScore uint64
ProcessRequestTimeoutErrorScore uint64
UnknownErrorScore uint64
DeserializationErrorScore uint64
SerializationErrorScore uint64
BlockIrreversibilityErrorScore uint64
BlockApplicationErrorScore uint64
UnknownPreviousBlockErrorScore uint64
BlockApplicationTimeoutErrorScore uint64
MaxPendingBlocksErrorScore uint64
TransactionApplicationErrorScore uint64
ChainIDMismatchErrorScore uint64
ChainNotConnectedErrorScore uint64
CheckpointMismatchErrorScore uint64
LocalRPCErrorScore uint64
PeerRPCErrorScore uint64
LocalRPCTimeoutErrorScore uint64
PeerRPCTimeoutErrorScore uint64
ProcessRequestTimeoutErrorScore uint64
UnknownErrorScore uint64
}

// NewPeerErrorHandlerOptions returns default initialized PeerErrorHandlerOptions
func NewPeerErrorHandlerOptions() *PeerErrorHandlerOptions {
return &PeerErrorHandlerOptions{
ErrorScoreDecayHalflife: errorScoreDecayHalflifeDefault,
ErrorScoreThreshold: errorScoreThresholdDefault,
DeserializationErrorScore: deserializationErrorScoreDefault,
SerializationErrorScore: serializationErrorScoreDefault,
BlockIrreversibilityErrorScore: blockIrreversibilityErrorScoreDefault,
BlockApplicationErrorScore: blockApplicationErrorScoreDefault,
TransactionApplicationErrorScore: transactionApplicationErrorScoreDefault,
ChainIDMismatchErrorScore: chainIDMismatchErrorScoreDefault,
ChainNotConnectedErrorScore: chainNotConnectedErrorScoreDefault,
CheckpointMismatchErrorScore: checkpointMismatchErrorScoreDefault,
LocalRPCErrorScore: localRPCErrorScoreDefault,
PeerRPCErrorScore: peerRPCErrorScoreDefault,
LocalRPCTimeoutErrorScore: localRPCTimeoutErrorScoreDefault,
PeerRPCTimeoutErrorScore: peerRPCTimeoutErrorScoreDefault,
ProcessRequestTimeoutErrorScore: processRequestTimeoutErrorScoreDefault,
UnknownErrorScore: unknownErrorScoreDefault,
ErrorScoreDecayHalflife: errorScoreDecayHalflifeDefault,
ErrorScoreThreshold: errorScoreThresholdDefault,
DeserializationErrorScore: deserializationErrorScoreDefault,
SerializationErrorScore: serializationErrorScoreDefault,
BlockIrreversibilityErrorScore: blockIrreversibilityErrorScoreDefault,
BlockApplicationErrorScore: blockApplicationErrorScoreDefault,
UnknownPreviousBlockErrorScore: unknownPreviousBlockErrorScoreDefault,
BlockApplicationTimeoutErrorScore: blockApplicationTimeoutErrorScoreDefault,
MaxPendingBlocksErrorScore: maxPendingBlocksErrorScoreDefault,
TransactionApplicationErrorScore: transactionApplicationErrorScoreDefault,
ChainIDMismatchErrorScore: chainIDMismatchErrorScoreDefault,
ChainNotConnectedErrorScore: chainNotConnectedErrorScoreDefault,
CheckpointMismatchErrorScore: checkpointMismatchErrorScoreDefault,
LocalRPCErrorScore: localRPCErrorScoreDefault,
PeerRPCErrorScore: peerRPCErrorScoreDefault,
LocalRPCTimeoutErrorScore: localRPCTimeoutErrorScoreDefault,
PeerRPCTimeoutErrorScore: peerRPCTimeoutErrorScoreDefault,
ProcessRequestTimeoutErrorScore: processRequestTimeoutErrorScoreDefault,
UnknownErrorScore: unknownErrorScoreDefault,
}
}
4 changes: 3 additions & 1 deletion internal/p2p/block_applicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ func (b *BlockApplicator) applyBlock(ctx context.Context, id string) {
func (b *BlockApplicator) handleNewBlock(ctx context.Context, entry *blockEntry) {
var err error

if len(b.blocksById) >= int(b.opts.MaxPendingBlocks) {
if entry.block.Header.Height > b.head.Height+b.opts.MaxHeightDelta {
err = p2perrors.ErrBlockApplication
} else if len(b.blocksById) >= int(b.opts.MaxPendingBlocks) {
err = p2perrors.ErrMaxPendingBlocks
} else if entry.block.Header.Height > b.head.Height+1 {
err = b.addEntry(entry)
Expand Down
15 changes: 14 additions & 1 deletion internal/p2p/block_applicator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ func TestBlockApplicatorLimits(t *testing.T) {
head: []byte{0x00},
}

blockApplicator, err := NewBlockApplicator(ctx, &rpc, options.BlockApplicatorOptions{MaxPendingBlocks: 5})
blockApplicator, err := NewBlockApplicator(ctx, &rpc, options.BlockApplicatorOptions{MaxPendingBlocks: 5, MaxHeightDelta: 5})
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -273,4 +273,17 @@ func TestBlockApplicatorLimits(t *testing.T) {
},
},
)

futureBlock := &protocol.Block{
Id: []byte{0x08},
Header: &protocol.BlockHeader{
Height: 8,
Previous: []byte{0},
},
}

err = blockApplicator.ApplyBlock(ctx, futureBlock)
if err != p2perrors.ErrBlockApplication {
t.Errorf("block2b - ErrBlockApplication expected but not returned, was: %v", err)
}
}
6 changes: 6 additions & 0 deletions internal/p2p/error_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ func (p *PeerErrorHandler) getScoreForError(err error) uint64 {
return p.opts.TransactionApplicationErrorScore
case errors.Is(err, p2perrors.ErrBlockApplication):
return p.opts.BlockApplicationErrorScore
case errors.Is(err, p2perrors.ErrUnknownPreviousBlock):
return p.opts.UnknownPreviousBlockErrorScore
case errors.Is(err, p2perrors.ErrBlockApplicationTimeout):
return p.opts.BlockApplicationTimeoutErrorScore
case errors.Is(err, p2perrors.ErrMaxPendingBlocks):
return p.opts.MaxPendingBlocksErrorScore
case errors.Is(err, p2perrors.ErrDeserialization):
return p.opts.DeserializationErrorScore
case errors.Is(err, p2perrors.ErrBlockIrreversibility):
Expand Down

0 comments on commit 989920e

Please sign in to comment.