|
|
|
@ -13,11 +13,24 @@ const ( |
|
|
|
|
AttackEnabled = false |
|
|
|
|
HitRate = 10 |
|
|
|
|
DelayResponseDuration = 10 * time.Second |
|
|
|
|
ConsensusIdThresholdMin = 10 |
|
|
|
|
ConsensusIdThresholdMax = 100 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type AttackType byte |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
KilledItself AttackType = iota |
|
|
|
|
DelayResponse |
|
|
|
|
IncorrectTransaction |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// AttackModel contains different models of attacking.
|
|
|
|
|
type Attack struct { |
|
|
|
|
AttackEnabled bool |
|
|
|
|
attackType AttackType |
|
|
|
|
ConsensusIdThreshold int |
|
|
|
|
readyByConsensus bool |
|
|
|
|
log log.Logger // Log utility
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -28,43 +41,51 @@ var once sync.Once |
|
|
|
|
func GetAttackModel() *Attack { |
|
|
|
|
once.Do(func() { |
|
|
|
|
attack = &Attack{} |
|
|
|
|
attack.AttackEnabled = AttackEnabled |
|
|
|
|
attack.Init() |
|
|
|
|
}) |
|
|
|
|
return attack |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (attack *Attack) SetLogger(log log.Logger) { |
|
|
|
|
attack.log = log |
|
|
|
|
func (attack *Attack) Init() { |
|
|
|
|
attack.AttackEnabled = AttackEnabled |
|
|
|
|
attack.readyByConsensus = false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Run runs all attack models in goroutine mode.
|
|
|
|
|
func (attack *Attack) Run() { |
|
|
|
|
if !attack.AttackEnabled { |
|
|
|
|
return |
|
|
|
|
func (attack *Attack) SetAttackEnabled(AttackEnabled bool) { |
|
|
|
|
attack.AttackEnabled = AttackEnabled |
|
|
|
|
if AttackEnabled { |
|
|
|
|
attack.attackType = AttackType(rand.Intn(3)) |
|
|
|
|
attack.ConsensusIdThreshold = ConsensusIdThresholdMin + rand.Intn(ConsensusIdThresholdMax-ConsensusIdThresholdMin) |
|
|
|
|
} |
|
|
|
|
// Adding attack model here.
|
|
|
|
|
go func() { |
|
|
|
|
attack.NodeKilledByItSelf() |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (attack *Attack) SetLogger(log log.Logger) { |
|
|
|
|
attack.log = log |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// NodeKilledByItSelf runs killing itself attack
|
|
|
|
|
func (attack *Attack) NodeKilledByItSelf() { |
|
|
|
|
tick := time.Tick(DroppingTickDuration) |
|
|
|
|
for { |
|
|
|
|
<-tick |
|
|
|
|
if !attack.AttackEnabled || attack.attackType != DelayResponse || !attack.readyByConsensus { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if rand.Intn(HitRate) == 0 { |
|
|
|
|
attack.log.Debug("***********************Killing myself***********************", "PID: ", os.Getpid()) |
|
|
|
|
attack.log.Debug("******Killing myself*******", "PID: ", os.Getpid()) |
|
|
|
|
os.Exit(1) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (attack *Attack) DelayResponse() { |
|
|
|
|
if !attack.AttackEnabled { |
|
|
|
|
if !attack.AttackEnabled || attack.attackType != DelayResponse || !attack.readyByConsensus { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if rand.Intn(HitRate) == 0 { |
|
|
|
|
time.Sleep(DelayResponseDuration) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (attack *Attack) UpdateConsensusReady(consensusId int) { |
|
|
|
|
if consensusId > attack.ConsensusIdThreshold { |
|
|
|
|
attack.readyByConsensus = true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|