[NOD-1224] Fix duplicate connections and duplicate blocks bugs (#842)

* [NOD-1224] Make block already existing a ruleError

* [NOD-1224] Remove block from pendingBlocks list only after it was processed

* [NOD-1224] AddToPeers should have a Write Lock, not Read Lock

* [NOD-1224] Check for unrequested before processing
This commit is contained in:
Svarog 2020-08-04 11:07:21 +03:00 committed by GitHub
parent 966cba4a4e
commit 473cc37a75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 8 deletions

View File

@ -6,9 +6,10 @@ package blockdag
import ( import (
"fmt" "fmt"
"time"
"github.com/kaspanet/kaspad/dagconfig" "github.com/kaspanet/kaspad/dagconfig"
"github.com/pkg/errors" "github.com/pkg/errors"
"time"
"github.com/kaspanet/kaspad/util" "github.com/kaspanet/kaspad/util"
"github.com/kaspanet/kaspad/util/daghash" "github.com/kaspanet/kaspad/util/daghash"
@ -162,7 +163,8 @@ func (dag *BlockDAG) processBlockNoLock(block *util.Block, flags BehaviorFlags)
// The block must not already exist in the DAG. // The block must not already exist in the DAG.
if dag.IsInDAG(blockHash) && !wasBlockStored { if dag.IsInDAG(blockHash) && !wasBlockStored {
return false, false, errors.Errorf("already have block %s", blockHash) str := fmt.Sprintf("already have block %s", blockHash)
return false, false, ruleError(ErrDuplicateBlock, str)
} }
// The block must not already exist as an orphan. // The block must not already exist as an orphan.

View File

@ -1,8 +1,9 @@
package common package common
import ( import (
"github.com/pkg/errors"
"time" "time"
"github.com/pkg/errors"
) )
// DefaultTimeout is the default duration to wait for enqueuing/dequeuing // DefaultTimeout is the default duration to wait for enqueuing/dequeuing
@ -10,4 +11,4 @@ import (
const DefaultTimeout = 30 * time.Second const DefaultTimeout = 30 * time.Second
// ErrPeerWithSameIDExists signifies that a peer with the same ID already exist. // ErrPeerWithSameIDExists signifies that a peer with the same ID already exist.
var ErrPeerWithSameIDExists = errors.New("ready with the same ID already exists") var ErrPeerWithSameIDExists = errors.New("ready peer with the same ID already exists")

View File

@ -21,8 +21,8 @@ func (f *FlowContext) ConnectionManager() *connmanager.ConnectionManager {
// AddToPeers marks this peer as ready and adds it to the ready peers list. // AddToPeers marks this peer as ready and adds it to the ready peers list.
func (f *FlowContext) AddToPeers(peer *peerpkg.Peer) error { func (f *FlowContext) AddToPeers(peer *peerpkg.Peer) error {
f.peersMutex.RLock() f.peersMutex.Lock()
defer f.peersMutex.RUnlock() defer f.peersMutex.Unlock()
if _, ok := f.peers[peer.ID()]; ok { if _, ok := f.peers[peer.ID()]; ok {
return errors.Wrapf(common.ErrPeerWithSameIDExists, "peer with ID %s already exists", peer.ID()) return errors.Wrapf(common.ErrPeerWithSameIDExists, "peer with ID %s already exists", peer.ID())

View File

@ -141,16 +141,19 @@ func (flow *handleRelayInvsFlow) requestBlocks(requestQueue *hashesQueueSet) err
block := util.NewBlock(msgBlock) block := util.NewBlock(msgBlock)
blockHash := block.Hash() blockHash := block.Hash()
if _, ok := pendingBlocks[*blockHash]; !ok { if _, ok := pendingBlocks[*blockHash]; !ok {
return protocolerrors.Errorf(true, "got unrequested block %s", block.Hash()) return protocolerrors.Errorf(true, "got unrequested block %s", block.Hash())
} }
delete(pendingBlocks, *blockHash)
flow.SharedRequestedBlocks().remove(blockHash)
err = flow.processAndRelayBlock(requestQueue, block) err = flow.processAndRelayBlock(requestQueue, block)
if err != nil { if err != nil {
return err return err
} }
delete(pendingBlocks, *blockHash)
flow.SharedRequestedBlocks().remove(blockHash)
} }
return nil return nil
} }