Skip to content

Commit

Permalink
improve: handle double signing and same votes when assemble attestation
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanBSC committed Jul 31, 2023
1 parent 278608a commit 7859a9b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 27 deletions.
9 changes: 9 additions & 0 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,9 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
voteAddrSet := make(map[types.BLSPublicKey]struct{}, len(votes))
signatures := make([][]byte, 0, len(votes))
for _, vote := range votes {
if _, ok := voteAddrSet[vote.VoteAddress]; ok {
return fmt.Errorf("assemble VoteAttestation failed, double sign by %s", common.Bytes2Hex(vote.VoteAddress[:]))
}
voteAddrSet[vote.VoteAddress] = struct{}{}
signatures = append(signatures, vote.Signature[:])
}
Expand All @@ -882,6 +885,12 @@ func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, head
attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1
}
}
// The valid voted validators should be no less than 2/3 validators,
// In some corner case, one vote may be included twice, so here need check again.
validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)})
if validatorsBitSet.Count() < uint(cmath.CeilDiv(len(snap.Validators)*2, 3)) {
return fmt.Errorf("invalid attestation, not enough validators voted")
}

// Append attestation to header extra field.
buf := new(bytes.Buffer)
Expand Down
3 changes: 2 additions & 1 deletion core/monitor/malicious_vote_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendi
if !(blockNumber+maliciousVoteSlashScope > pendingBlockNumber) {
blockNumber = pendingBlockNumber - maliciousVoteSlashScope + 1
}
newVoteHash := newVote.Data.Hash()
for ; blockNumber <= pendingBlockNumber+upperLimitOfVoteBlockNumber; blockNumber++ {
if voteDataBuffer.Contains(blockNumber) {
voteEnvelope, ok := voteDataBuffer.Get(blockNumber)
Expand All @@ -66,7 +67,7 @@ func (m *MaliciousVoteMonitor) ConflictDetect(newVote *types.VoteEnvelope, pendi
continue
}
maliciousVote := false
if blockNumber == targetNumber {
if blockNumber == targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.Hash() != newVoteHash {
violateRule1Counter.Inc(1)
maliciousVote = true
} else if (blockNumber < targetNumber && voteEnvelope.(*types.VoteEnvelope).Data.SourceNumber > sourceNumber) ||
Expand Down
52 changes: 26 additions & 26 deletions core/monitor/malicious_vote_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - maliciousVoteSlashScope - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes(("01"))),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -34,9 +34,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - maliciousVoteSlashScope - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -54,9 +54,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - maliciousVoteSlashScope - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("01")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -65,9 +65,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - maliciousVoteSlashScope - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -85,9 +85,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("01")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -96,9 +96,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: uint64(0),
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, true, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -116,9 +116,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 4,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("01")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -127,9 +127,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 2,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 3,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, true, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -147,9 +147,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 2,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 3,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("01")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -158,9 +158,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 4,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, true, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -178,9 +178,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 4,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 3,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("01")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote1, pendingBlockNumber))
Expand All @@ -189,9 +189,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 3,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 2,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote2, pendingBlockNumber))
Expand All @@ -200,9 +200,9 @@ func TestMaliciousVoteMonitor(t *testing.T) {
Signature: types.BLSSignature{},
Data: &types.VoteData{
SourceNumber: pendingBlockNumber - 2,
SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))),
SourceHash: common.BytesToHash(common.Hex2Bytes("00")),
TargetNumber: pendingBlockNumber - 1,
TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))),
TargetHash: common.BytesToHash(common.Hex2Bytes("02")),
},
}
assert.Equal(t, false, maliciousVoteMonitor.ConflictDetect(vote3, pendingBlockNumber))
Expand Down

0 comments on commit 7859a9b

Please sign in to comment.