The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
woop/consensus/double_sign.go

152 lines
5.3 KiB

package consensus
import (
"bytes"
"sort"
"github.com/ethereum/go-ethereum/common"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/staking/slash"
)
// Check for double sign and if any, send it out to beacon chain for slashing.
// Returns true when it is a double-sign or there is error, otherwise, false.
func (consensus *Consensus) checkDoubleSign(recvMsg *FBFTMessage) bool {
if consensus.couldThisBeADoubleSigner(recvMsg) {
addrSet := map[common.Address]struct{}{}
for _, pubKey2 := range recvMsg.SenderPubkeys {
if alreadyCastBallot := consensus.decider.ReadBallot(
quorum.Commit, pubKey2.Bytes,
); alreadyCastBallot != nil {
for _, pubKey1 := range alreadyCastBallot.SignerPubKeys {
if bytes.Compare(pubKey2.Bytes[:], pubKey1[:]) == 0 {
for _, blk := range consensus.fBFTLog.GetBlocksByNumber(recvMsg.BlockNum) {
firstSignedHeader := blk.Header()
areHeightsEqual := firstSignedHeader.Number().Uint64() == recvMsg.BlockNum
areViewIDsEqual := firstSignedHeader.ViewID().Uint64() == recvMsg.ViewID
areHeadersEqual := firstSignedHeader.Hash() == recvMsg.BlockHash
// If signer already firstSignedHeader, and the block height is the same
// and the viewID is the same, then we need to verify the block
// hash, and if block hash is different, then that is a clear
// case of double signing
if areHeightsEqual && areViewIDsEqual && !areHeadersEqual {
var doubleSign bls_core.Sign
if err := doubleSign.Deserialize(recvMsg.Payload); err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not deserialize potential double signer")
return true
}
Release Candidate: dev -> main (#4319) * Rebase dev branch to current main branch (#4318) * add openssl compatibility on m2 chips using darwin (#4302) Adds support for OpenSSL on MacOS Ventura using m2 chips. * [dumpdb] ensure each cross link is dumped (#4311) * bump libp2p to version 0.24.0 and update its dependencies and relevant tests (#4315) * Removed legacy syncing peer provider. (#4260) * Removed legacy syncing peer provider. * Fix localnet. * Fix migrate version. * Rebased on main. * Fix formatting. * Remove blockchain dependency from engine. (#4310) * Consensus doesn't require anymore `Node` as a circular dependency. * Rebased upon main. * Removed engine beacon chain dependency. * Fixed nil error. * Fixed error. * bump libp2p to version 0.24.0 and update its dependencies and relevant tests * fix format, remove wrongly added configs * add back wrongly deleted comment * fix travis go checker Co-authored-by: Konstantin <355847+Frozen@users.noreply.github.com> Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> * bump libp2p to version 0.24.0 and update its dependencies and relevant tests (#4315) * Removed legacy syncing peer provider. (#4260) * Removed legacy syncing peer provider. * Fix localnet. * Fix migrate version. * Rebased on main. * Fix formatting. * Remove blockchain dependency from engine. (#4310) * Consensus doesn't require anymore `Node` as a circular dependency. * Rebased upon main. * Removed engine beacon chain dependency. * Fixed nil error. * Fixed error. * bump libp2p to version 0.24.0 and update its dependencies and relevant tests * fix format, remove wrongly added configs * add back wrongly deleted comment * fix travis go checker Co-authored-by: Konstantin <355847+Frozen@users.noreply.github.com> Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> * Fix for consensus stuck. (#4307) * Added check for block validity. * Starts new view change if block invalid. * Revert "Starts new view change if block invalid." This reverts commit e889fa5da2e0780f087ab7dae5106b96287706db. * staged dns sync v1.0 (#4316) * staged dns sync v1.0 * enabled stream downloader for localnet * fix code review issues * remove extra lock Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> * add description for closing client and change randomize process to ma… (#4276) * add description for closing client and change randomize process to make sure only online nodes are added to sync config * fix sync test * fix legacy limitNumPeers test * add WaitForEachPeerToConnect to node configs to make parallel peer connection optional Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> * Small fixes and code cleanup for network stack. (#4320) * staged dns sync v1.0 * enabled stream downloader for localnet * fix code review issues * remove extra lock * staged dns sync v1.0 * Fixed, code clean up and other. * Fixed, code clean up and other. * Fixed, code clean up and other. * Fix config. Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> * Fix not disable cache in archival mode (#4322) * Feature registry (#4324) * Registry for services. * Test. * Reverted comment. * Fix. * Slash fix (#4284) * Implementation of new slashing rate calculation * Write tests for then new slashing rate calculation * Add engine.applySlashing tests * fix #4059 Co-authored-by: Alex Brezas <abresas@gmail.com> Co-authored-by: Dimitris Lamprinos <pkakelas@gmail.com> * Bump github.com/aws/aws-sdk-go from 1.30.1 to 1.33.0 (#4325) (#4328) Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.30.1 to 1.33.0. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Changelog](https://github.com/aws/aws-sdk-go/blob/v1.33.0/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.30.1...v1.33.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/btcsuite/btcd from 0.21.0-beta to 0.23.2 (#4327) (#4329) Bumps [github.com/btcsuite/btcd](https://github.com/btcsuite/btcd) from 0.21.0-beta to 0.23.2. - [Release notes](https://github.com/btcsuite/btcd/releases) - [Changelog](https://github.com/btcsuite/btcd/blob/master/CHANGES) - [Commits](https://github.com/btcsuite/btcd/compare/v0.21.0-beta...v0.23.2) --- updated-dependencies: - dependency-name: github.com/btcsuite/btcd dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max <82761650+MaxMustermann2@users.noreply.github.com> Co-authored-by: Gheis <36589218+GheisMohammadi@users.noreply.github.com> Co-authored-by: Konstantin <355847+Frozen@users.noreply.github.com> Co-authored-by: “GheisMohammadi” <“Gheis.Mohammadi@gmail.com”> Co-authored-by: Danny Willis <102543677+dannyposi@users.noreply.github.com> Co-authored-by: PeekPI <894646171@QQ.COM> Co-authored-by: Alex Brezas <abresas@gmail.com> Co-authored-by: Dimitris Lamprinos <pkakelas@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2 years ago
curHeader := consensus.Blockchain().CurrentHeader()
committee, err := consensus.Blockchain().ReadShardState(curHeader.Epoch())
if err != nil {
consensus.getLogger().Err(err).
Uint32("shard", consensus.ShardID).
Uint64("epoch", curHeader.Epoch().Uint64()).
Msg("could not read shard state")
return true
}
subComm, err := committee.FindCommitteeByID(
consensus.ShardID,
)
if err != nil {
consensus.getLogger().Err(err).
Str("msg", recvMsg.String()).
Msg("could not find subcommittee for bls key")
return true
}
addr, err := subComm.AddressForBLSKey(pubKey2.Bytes)
if err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not find address for bls key")
return true
}
if _, ok := addrSet[*addr]; ok {
// Address already slashed
break
}
leaderAddr, err := subComm.AddressForBLSKey(consensus.LeaderPubKey.Bytes)
if err != nil {
consensus.getLogger().Err(err).Str("msg", recvMsg.String()).
Msg("could not find address for leader bls key")
return true
}
go func(reporter common.Address) {
secondKeys := make([]bls.SerializedPublicKey, len(recvMsg.SenderPubkeys))
for i, pubKey := range recvMsg.SenderPubkeys {
secondKeys[i] = pubKey.Bytes
}
evid := slash.Evidence{
ConflictingVotes: slash.ConflictingVotes{
FirstVote: slash.Vote{
3 years ago
SignerPubKeys: alreadyCastBallot.SignerPubKeys,
BlockHeaderHash: alreadyCastBallot.BlockHeaderHash,
Signature: alreadyCastBallot.Signature,
},
SecondVote: slash.Vote{
3 years ago
SignerPubKeys: secondKeys,
BlockHeaderHash: recvMsg.BlockHash,
Signature: common.Hex2Bytes(doubleSign.SerializeToHexStr()),
}},
Moment: slash.Moment{
Epoch: curHeader.Epoch(),
ShardID: consensus.ShardID,
Height: recvMsg.BlockNum,
ViewID: recvMsg.ViewID,
},
Offender: *addr,
}
sort.SliceStable(evid.ConflictingVotes.FirstVote.SignerPubKeys, func(i, j int) bool {
return bytes.Compare(
evid.ConflictingVotes.FirstVote.SignerPubKeys[i][:],
evid.ConflictingVotes.FirstVote.SignerPubKeys[j][:]) < 0
})
sort.SliceStable(evid.ConflictingVotes.SecondVote.SignerPubKeys, func(i, j int) bool {
return bytes.Compare(
evid.ConflictingVotes.SecondVote.SignerPubKeys[i][:],
evid.ConflictingVotes.SecondVote.SignerPubKeys[j][:]) < 0
})
proof := slash.Record{
Evidence: evid,
Reporter: reporter,
}
consensus.SlashChan <- proof
}(*leaderAddr)
addrSet[*addr] = struct{}{}
break
}
}
}
}
}
}
return true
}
return false
}
func (consensus *Consensus) couldThisBeADoubleSigner(
recvMsg *FBFTMessage,
) bool {
num, hash := consensus.BlockNum(), recvMsg.BlockHash
suspicious := !consensus.fBFTLog.HasMatchingAnnounce(num, hash) ||
!consensus.fBFTLog.HasMatchingPrepared(num, hash)
if suspicious {
consensus.getLogger().Debug().
Str("message", recvMsg.String()).
Uint64("block-on-consensus", num).
Msg("possible double signer")
return true
}
return false
}