Skip to content

Commit

Permalink
Merge pull request #2008 from ElrondNetwork/peer-honesty-implementation
Browse files Browse the repository at this point in the history
Peer honesty implementation
  • Loading branch information
LucianMincu committed Jun 26, 2020
2 parents 18cff0c + 537553e commit 9bf6294
Show file tree
Hide file tree
Showing 29 changed files with 1,062 additions and 152 deletions.
5 changes: 5 additions & 0 deletions cmd/node/config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@
Capacity = 30000
Type = "LRU"

[PeerHonesty]
Name = "PeerHonesty"
Capacity = 5000
Type = "LRU"

[Antiflood]
Enabled = true
NumConcurrentResolverJobs = 50
Expand Down
6 changes: 3 additions & 3 deletions cmd/node/config/genesisSmartContracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"owner": "erd17326yupjy7cq7qv94n704ttxrh4lrhl7qt7mppdu9evwmj5mwt8s794sua",
"filename": "./config/genesisContracts/delegation.wasm",
"vm-type": "0500",
"init-parameters": "0BB8@%auction_sc_address%@0A61D0",
"init-parameters": "%auction_sc_address%@03E8@03E8@03E8",
"type": "delegation",
"version": "0.2.*"
"version": "0.3.*"
}
]
]
10 changes: 10 additions & 0 deletions cmd/node/config/ratings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@
ProposerDecreaseFactor = -4.0
ValidatorDecreaseFactor = -4.0
ConsecutiveMissedBlocksPenalty = 1.10

[PeerHonesty]
#this value will be multiplied with the current value for a public key each DecayUpdateIntervalInSeconds seconds
#for the current settings, a pk will reach to value 0 after maximum 2h (if it stopped misbehaving or stopped sending good messages)
DecayCoefficient = 0.9779
DecayUpdateIntervalInSeconds = 10
MaxScore = 100
MinScore = -100
BadPeerThreshold = -80
UnitValue = 1.0
28 changes: 22 additions & 6 deletions cmd/node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import (
"github.com/ElrondNetwork/elrond-go/marshal"
"github.com/ElrondNetwork/elrond-go/node"
"github.com/ElrondNetwork/elrond-go/node/external"
"github.com/ElrondNetwork/elrond-go/node/mock"
"github.com/ElrondNetwork/elrond-go/node/nodeDebugFactory"
"github.com/ElrondNetwork/elrond-go/ntp"
"github.com/ElrondNetwork/elrond-go/process"
Expand All @@ -62,6 +61,7 @@ import (
"github.com/ElrondNetwork/elrond-go/process/factory/shard"
"github.com/ElrondNetwork/elrond-go/process/interceptors"
"github.com/ElrondNetwork/elrond-go/process/rating"
"github.com/ElrondNetwork/elrond-go/process/rating/peerHonesty"
"github.com/ElrondNetwork/elrond-go/process/smartContract"
"github.com/ElrondNetwork/elrond-go/process/smartContract/builtInFunctions"
"github.com/ElrondNetwork/elrond-go/process/smartContract/hooks"
Expand Down Expand Up @@ -1245,12 +1245,10 @@ func startNode(ctx *cli.Context, log logger.Logger, version string) error {
processComponents.TxLogsProcessor.EnableLogToBeSavedInCache()
}

//TODO: This should be set with a real instance which implements PeerHonestyHandler interface
peerHonestyHandler := &mock.PeerHonestyHandlerStub{}

log.Trace("creating node structure")
currentNode, err := createNode(
generalConfig,
ratingsConfig,
preferencesConfig,
genesisNodesConfig,
economicsData,
Expand All @@ -1275,7 +1273,6 @@ func startNode(ctx *cli.Context, log logger.Logger, version string) error {
whiteListerVerifiedTxs,
chanStopNodeProcess,
hardForkTrigger,
peerHonestyHandler,
)
if err != nil {
return err
Expand Down Expand Up @@ -1989,6 +1986,7 @@ func createHardForkTrigger(

func createNode(
config *config.Config,
ratingConfig config.RatingsConfig,
preferencesConfig *config.Preferences,
nodesConfig *sharding.NodesSetup,
economicsData process.FeeHandler,
Expand All @@ -2013,7 +2011,6 @@ func createNode(
whiteListerVerifiedTxs process.WhiteListHandler,
chanStopNodeProcess chan endProcess.ArgEndProcess,
hardForkTrigger node.HardforkTrigger,
peerHonestyHandler consensus.PeerHonestyHandler,
) (*node.Node, error) {
var err error
var consensusGroupSize uint32
Expand Down Expand Up @@ -2069,6 +2066,11 @@ func createNode(
return nil, err
}

peerHonestyHandler, err := createPeerHonestyHandler(config, ratingConfig, network.PkTimeCache)
if err != nil {
return nil, err
}

var nd *node.Node
nd, err = node.NewNode(
node.WithMessenger(network.NetMessenger),
Expand Down Expand Up @@ -2172,6 +2174,20 @@ func createNode(
return nd, nil
}

func createPeerHonestyHandler(
config *config.Config,
ratingConfig config.RatingsConfig,
pkTimeCache process.TimeCacher,
) (consensus.PeerHonestyHandler, error) {

cache, err := storageUnit.NewCache(storageFactory.GetCacherFromConfig(config.PeerHonesty))
if err != nil {
return nil, err
}

return peerHonesty.NewP2pPeerHonesty(ratingConfig.PeerHonesty, pkTimeCache, cache)
}

func initStatsFileMonitor(
config *config.Config,
pubKeyString string,
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ type Config struct {
PublicKeyPeerId CacheConfig
PeerIdShardId CacheConfig
P2PMessageIDAdditionalCache CacheConfig
PeerHonesty CacheConfig

Antiflood AntifloodConfig
ResourceStats ResourceStatsConfig
Expand Down
17 changes: 14 additions & 3 deletions config/ratingsConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ package config

// RatingsConfig will hold the configuration data needed for the ratings
type RatingsConfig struct {
General General
ShardChain ShardChain
MetaChain MetaChain
General General
ShardChain ShardChain
MetaChain MetaChain
PeerHonesty PeerHonestyConfig
}

// General will hold ratings settings both for metachain and shardChain
Expand Down Expand Up @@ -46,3 +47,13 @@ type RatingSteps struct {
ValidatorDecreaseFactor float32
ConsecutiveMissedBlocksPenalty float32
}

// PeerHonestyConfig holds the parameters for the peer honesty handler
type PeerHonestyConfig struct {
DecayCoefficient float64
DecayUpdateIntervalInSeconds uint32
MaxScore float64
MinScore float64
BadPeerThreshold float64
UnitValue float64
}
3 changes: 1 addition & 2 deletions consensus/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ type HeadersPoolSubscriber interface {
// PeerHonestyHandler defines the behaivour of a component able to handle/monitor the peer honesty of nodes which are
// participating in consensus
type PeerHonestyHandler interface {
Increase(pk string, topic string, value float64)
Decrease(pk string, topic string, value float64)
ChangeScore(pk string, topic string, units int)
IsInterfaceNil() bool
}

Expand Down
3 changes: 2 additions & 1 deletion consensus/mock/mockTestInitializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ElrondNetwork/elrond-go/crypto"
"github.com/ElrondNetwork/elrond-go/data"
"github.com/ElrondNetwork/elrond-go/data/block"
"github.com/ElrondNetwork/elrond-go/testscommon"
)

// InitChronologyHandlerMock -
Expand Down Expand Up @@ -130,7 +131,7 @@ func InitConsensusCore() *ConsensusCoreMock {
epochStartSubscriber := &EpochStartNotifierStub{}
antifloodHandler := &P2PAntifloodHandlerStub{}
headerPoolSubscriber := &HeadersCacherStub{}
peerHonestyHandler := &PeerHonestyHandlerStub{}
peerHonestyHandler := &testscommon.PeerHonestyHandlerStub{}

container := &ConsensusCoreMock{
blockChain: blockChain,
Expand Down
28 changes: 0 additions & 28 deletions consensus/mock/peerHonestyHandlerStub.go

This file was deleted.

30 changes: 18 additions & 12 deletions consensus/spos/bls/subroundBlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,10 +318,11 @@ func (sr *subroundBlock) receivedBlockBodyAndHeader(cnsDta *consensus.Message) b
}

if !sr.IsNodeLeaderInCurrentRound(node) { // is NOT this node leader in current round?
sr.PeerHonestyHandler().Decrease(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyDecreaseFactor)
spos.LeaderPeerHonestyDecreaseFactor,
)

return false
}
Expand Down Expand Up @@ -354,10 +355,11 @@ func (sr *subroundBlock) receivedBlockBodyAndHeader(cnsDta *consensus.Message) b
blockProcessedWithSuccess := sr.processReceivedBlock(cnsDta)
sw.Stop("processReceivedBlock")

sr.PeerHonestyHandler().Increase(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyIncreaseFactor)
spos.LeaderPeerHonestyIncreaseFactor,
)

return blockProcessedWithSuccess
}
Expand All @@ -367,10 +369,11 @@ func (sr *subroundBlock) receivedBlockBody(cnsDta *consensus.Message) bool {
node := string(cnsDta.PubKey)

if !sr.IsNodeLeaderInCurrentRound(node) { // is NOT this node leader in current round?
sr.PeerHonestyHandler().Decrease(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyDecreaseFactor)
spos.LeaderPeerHonestyDecreaseFactor,
)

return false
}
Expand All @@ -393,10 +396,11 @@ func (sr *subroundBlock) receivedBlockBody(cnsDta *consensus.Message) bool {

blockProcessedWithSuccess := sr.processReceivedBlock(cnsDta)

sr.PeerHonestyHandler().Increase(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyIncreaseFactor)
spos.LeaderPeerHonestyIncreaseFactor,
)

return blockProcessedWithSuccess
}
Expand All @@ -412,10 +416,11 @@ func (sr *subroundBlock) receivedBlockHeader(cnsDta *consensus.Message) bool {
}

if !sr.IsNodeLeaderInCurrentRound(node) { // is NOT this node leader in current round?
sr.PeerHonestyHandler().Decrease(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyDecreaseFactor)
spos.LeaderPeerHonestyDecreaseFactor,
)

return false
}
Expand All @@ -440,10 +445,11 @@ func (sr *subroundBlock) receivedBlockHeader(cnsDta *consensus.Message) bool {
"hash", cnsDta.BlockHeaderHash)
blockProcessedWithSuccess := sr.processReceivedBlock(cnsDta)

sr.PeerHonestyHandler().Increase(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyIncreaseFactor)
spos.LeaderPeerHonestyIncreaseFactor,
)

return blockProcessedWithSuccess
}
Expand Down
10 changes: 6 additions & 4 deletions consensus/spos/bls/subroundEndRound.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ func (sr *subroundEndRound) receivedBlockHeaderFinalInfo(cnsDta *consensus.Messa
}

if !sr.IsNodeLeaderInCurrentRound(node) { // is NOT this node leader in current round?
sr.PeerHonestyHandler().Decrease(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyDecreaseFactor)
spos.LeaderPeerHonestyDecreaseFactor,
)

return false
}
Expand All @@ -110,10 +111,11 @@ func (sr *subroundEndRound) receivedBlockHeaderFinalInfo(cnsDta *consensus.Messa
"AggregateSignature", cnsDta.AggregateSignature,
"LeaderSignature", cnsDta.LeaderSignature)

sr.PeerHonestyHandler().Increase(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.LeaderPeerHonestyIncreaseFactor)
spos.LeaderPeerHonestyIncreaseFactor,
)

return sr.doEndRoundJobByParticipant(cnsDta)
}
Expand Down
10 changes: 6 additions & 4 deletions consensus/spos/bls/subroundSignature.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@ func (sr *subroundSignature) receivedSignature(cnsDta *consensus.Message) bool {
}

if !sr.IsNodeInConsensusGroup(node) {
sr.PeerHonestyHandler().Decrease(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.ValidatorPeerHonestyDecreaseFactor)
spos.ValidatorPeerHonestyDecreaseFactor,
)

return false
}
Expand Down Expand Up @@ -179,10 +180,11 @@ func (sr *subroundSignature) receivedSignature(cnsDta *consensus.Message) bool {
return false
}

sr.PeerHonestyHandler().Increase(
sr.PeerHonestyHandler().ChangeScore(
node,
spos.GetConsensusTopicID(sr.ShardCoordinator()),
spos.ValidatorPeerHonestyIncreaseFactor)
spos.ValidatorPeerHonestyIncreaseFactor,
)

sr.appStatusHandler.SetStringValue(core.MetricConsensusRoundState, "signed")
return true
Expand Down
10 changes: 6 additions & 4 deletions consensus/spos/constants.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package spos

//TODO consider moving these constants in config file

// MaxThresholdPercent specifies the max allocated time percent for doing Job as a percentage of the total time of one round
const MaxThresholdPercent = 95

// LeaderPeerHonestyIncreaseFactor specifies the factor with which the honesty of the leader should be increased
// if it proposed a block or sent the final info, in its correct allocated slot/time-frame/round
const LeaderPeerHonestyIncreaseFactor = 2.0
const LeaderPeerHonestyIncreaseFactor = 2

// ValidatorPeerHonestyIncreaseFactor specifies the factor with which the honesty of the validator should be increased
// if it sent the signature, in its correct allocated slot/time-frame/round
const ValidatorPeerHonestyIncreaseFactor = 1.0
const ValidatorPeerHonestyIncreaseFactor = 1

// LeaderPeerHonestyDecreaseFactor specifies the factor with which the honesty of the leader should be decreased
// if it proposed a block or sent the final info, in an incorrect allocated slot/time-frame/round
const LeaderPeerHonestyDecreaseFactor = -4.0
const LeaderPeerHonestyDecreaseFactor = -4

// ValidatorPeerHonestyDecreaseFactor specifies the factor with which the honesty of the validator should be decreased
// if it sent the signature, in an incorrect allocated slot/time-frame/round
const ValidatorPeerHonestyDecreaseFactor = -2.0
const ValidatorPeerHonestyDecreaseFactor = -2
7 changes: 1 addition & 6 deletions consensus/spos/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,8 @@ func (wrk *Worker) ProcessReceivedMessage(message p2p.MessageP2P, fromConnectedP
return ErrNilDataToProcess
}

err := wrk.antifloodHandler.CanProcessMessage(message, fromConnectedPeer)
if err != nil {
return err
}

topic := GetConsensusTopicID(wrk.shardCoordinator)
err = wrk.antifloodHandler.CanProcessMessagesOnTopic(message.Peer(), topic, 1, uint64(len(message.Data())), message.SeqNo())
err := wrk.antifloodHandler.CanProcessMessagesOnTopic(message.Peer(), topic, 1, uint64(len(message.Data())), message.SeqNo())
if err != nil {
return err
}
Expand Down

0 comments on commit 9bf6294

Please sign in to comment.