aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-04-01 22:03:46 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-15 22:09:55 +0800
commit8012e32fb72dc05cfa995d2934569b9411871395 (patch)
treee68c957e804f6375154be619bf9a6bd855736350
parent982a812904ae3b1ccd99bc82efbd08ac70ec490b (diff)
downloadgo-tangerine-8012e32fb72dc05cfa995d2934569b9411871395.tar.gz
go-tangerine-8012e32fb72dc05cfa995d2934569b9411871395.tar.zst
go-tangerine-8012e32fb72dc05cfa995d2934569b9411871395.zip
dexcon: correctly fine DKGSet for not producing blocks (#325)
-rw-r--r--consensus/dexcon/dexcon.go47
-rw-r--r--consensus/dexcon/dexcon_test.go2
-rw-r--r--core/governance.go46
-rw-r--r--dex/downloader/testchain_test.go2
-rw-r--r--dex/recovery.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go7
-rw-r--r--vendor/vendor.json42
7 files changed, 80 insertions, 68 deletions
diff --git a/consensus/dexcon/dexcon.go b/consensus/dexcon/dexcon.go
index 4e474bfa3..c4f399c43 100644
--- a/consensus/dexcon/dexcon.go
+++ b/consensus/dexcon/dexcon.go
@@ -21,6 +21,7 @@ import (
"fmt"
"math/big"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/consensus"
"github.com/dexon-foundation/dexon/core/state"
@@ -32,7 +33,7 @@ import (
type GovernanceStateFetcher interface {
GetStateForConfigAtRound(round uint64) *vm.GovernanceState
- NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error)
+ DKGSetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error)
}
// Dexcon is a delegated proof-of-stake consensus engine.
@@ -159,31 +160,33 @@ func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, sta
if header.Round > 0 && height.Uint64() == 0 {
gs.PushRoundHeight(header.Number)
- // Check for dead node and disqualify them.
- // A dead node node is defined as: a notary set node that did not propose
- // any block in the past round.
- addrs, err := d.govStateFetcer.NotarySetNodeKeyAddresses(header.Round - 1)
- if err != nil {
- panic(err)
- }
+ if header.Round > dexCore.DKGDelayRound {
+ // Check for dead node and disqualify them.
+ // A dead node node is defined as: a notary set node that did not propose
+ // any block in the past round.
+ addrs, err := d.govStateFetcer.DKGSetNodeKeyAddresses(header.Round - 1)
+ if err != nil {
+ panic(err)
+ }
- gcs := d.govStateFetcer.GetStateForConfigAtRound(header.Round - 1)
+ gcs := d.govStateFetcer.GetStateForConfigAtRound(header.Round - 1)
- for addr := range addrs {
- offset := gcs.NodesOffsetByNodeKeyAddress(addr)
- if offset.Cmp(big.NewInt(0)) < 0 {
- panic(fmt.Errorf("invalid notary set found, addr = %s", addr.String()))
- }
+ for addr := range addrs {
+ offset := gcs.NodesOffsetByNodeKeyAddress(addr)
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ panic(fmt.Errorf("invalid notary set found, addr = %s", addr.String()))
+ }
- node := gcs.Node(offset)
- lastHeight := gs.LastProposedHeight(node.Owner)
- prevRoundHeight := gs.RoundHeight(big.NewInt(int64(header.Round - 1)))
+ node := gcs.Node(offset)
+ lastHeight := gs.LastProposedHeight(node.Owner)
+ prevRoundHeight := gs.RoundHeight(big.NewInt(int64(header.Round - 1)))
- if lastHeight.Uint64() < prevRoundHeight.Uint64() {
- log.Info("Disqualify node", "round", header.Round, "nodePubKey", hex.EncodeToString(node.PublicKey))
- err = gs.Disqualify(node)
- if err != nil {
- log.Error("Failed to disqualify node", "err", err)
+ if lastHeight.Uint64() < prevRoundHeight.Uint64() {
+ log.Info("Disqualify node", "round", header.Round, "nodePubKey", hex.EncodeToString(node.PublicKey))
+ err = gs.Disqualify(node)
+ if err != nil {
+ log.Error("Failed to disqualify node", "err", err)
+ }
}
}
}
diff --git a/consensus/dexcon/dexcon_test.go b/consensus/dexcon/dexcon_test.go
index bfded8db8..af20fbb1e 100644
--- a/consensus/dexcon/dexcon_test.go
+++ b/consensus/dexcon/dexcon_test.go
@@ -39,7 +39,7 @@ func (g *govStateFetcher) GetStateForConfigAtRound(_ uint64) *vm.GovernanceState
return &vm.GovernanceState{g.statedb}
}
-func (g *govStateFetcher) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+func (g *govStateFetcher) DKGSetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
return make(map[common.Address]struct{}), nil
}
diff --git a/core/governance.go b/core/governance.go
index b7dbba722..855c85910 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -12,6 +12,7 @@ import (
coreEcdsa "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+ coreUtils "github.com/dexon-foundation/dexon-consensus/core/utils"
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core/state"
@@ -113,28 +114,28 @@ func (g *Governance) GetStateForDKGAtRound(round uint64) *vm.GovernanceState {
return g.GetStateAtRound(round)
}
-func (d *Governance) CRSRound() uint64 {
- return d.GetHeadState().CRSRound().Uint64()
+func (g *Governance) CRSRound() uint64 {
+ return g.GetHeadState().CRSRound().Uint64()
}
// CRS returns the CRS for a given round.
-func (d *Governance) CRS(round uint64) coreCommon.Hash {
+func (g *Governance) CRS(round uint64) coreCommon.Hash {
if round <= dexCore.DKGDelayRound {
- s := d.GetStateAtRound(0)
+ s := g.GetStateAtRound(0)
crs := s.CRS()
for i := uint64(0); i < round; i++ {
crs = crypto.Keccak256Hash(crs[:])
}
return coreCommon.Hash(crs)
}
- if round > d.CRSRound() {
+ if round > g.CRSRound() {
return coreCommon.Hash{}
}
var s *vm.GovernanceState
- if round == d.CRSRound() {
- s = d.GetHeadState()
+ if round == g.CRSRound() {
+ s = g.GetHeadState()
} else {
- s = d.GetStateAtRound(round)
+ s = g.GetStateAtRound(round)
}
return coreCommon.Hash(s.CRS())
}
@@ -156,8 +157,8 @@ func (g *Governance) GetRoundHeight(round uint64) uint64 {
}
// NodeSet returns the current node set.
-func (d *Governance) NodeSet(round uint64) []coreCrypto.PublicKey {
- s := d.GetStateForConfigAtRound(round)
+func (g *Governance) NodeSet(round uint64) []coreCrypto.PublicKey {
+ s := g.GetStateForConfigAtRound(round)
var pks []coreCrypto.PublicKey
for _, n := range s.QualifiedNodes() {
@@ -170,33 +171,40 @@ func (d *Governance) NodeSet(round uint64) []coreCrypto.PublicKey {
return pks
}
-func (d *Governance) PurgeNotarySet(round uint64) {
- d.nodeSetCache.Purge(round)
+func (g *Governance) PurgeNotarySet(round uint64) {
+ g.nodeSetCache.Purge(round)
}
-func (d *Governance) NotarySet(round uint64) (map[string]struct{}, error) {
- notarySet, err := d.nodeSetCache.GetNotarySet(round)
+func (g *Governance) NotarySet(round uint64) (map[string]struct{}, error) {
+ notarySet, err := g.nodeSetCache.GetNotarySet(round)
if err != nil {
return nil, err
}
r := make(map[string]struct{}, len(notarySet))
for id := range notarySet {
- if key, exists := d.nodeSetCache.GetPublicKey(id); exists {
+ if key, exists := g.nodeSetCache.GetPublicKey(id); exists {
r[hex.EncodeToString(key.Bytes())] = struct{}{}
}
}
return r, nil
}
-func (d *Governance) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
- notarySet, err := d.nodeSetCache.GetNotarySet(round)
+func (g *Governance) DKGSetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+ config := g.Configuration(round)
+
+ mpks := g.DKGMasterPublicKeys(round)
+ complaints := g.DKGComplaints(round)
+ threshold := coreUtils.GetDKGThreshold(&coreTypes.Config{
+ NotarySetSize: config.NotarySetSize})
+
+ _, ids, err := dkgTypes.CalcQualifyNodes(mpks, complaints, threshold)
if err != nil {
return nil, err
}
- r := make(map[common.Address]struct{}, len(notarySet))
- for id := range notarySet {
+ r := make(map[common.Address]struct{})
+ for id := range ids {
r[vm.IdToAddress(id)] = struct{}{}
}
return r, nil
diff --git a/dex/downloader/testchain_test.go b/dex/downloader/testchain_test.go
index b59a83b2c..e5c5e4d23 100644
--- a/dex/downloader/testchain_test.go
+++ b/dex/downloader/testchain_test.go
@@ -343,6 +343,6 @@ func (g *govStateFetcher) GetStateForConfigAtRound(round uint64) *vm.GovernanceS
return nil
}
-func (g *govStateFetcher) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+func (g *govStateFetcher) DKGSetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
return make(map[common.Address]struct{}), nil
}
diff --git a/dex/recovery.go b/dex/recovery.go
index adeb1f612..72d3a5376 100644
--- a/dex/recovery.go
+++ b/dex/recovery.go
@@ -479,7 +479,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) {
return 0, err
}
- notarySet, err := r.gov.NotarySetNodeKeyAddresses(r.gov.Round())
+ notarySet, err := r.gov.DKGSetNodeKeyAddresses(r.gov.Round())
if err != nil {
return 0, err
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
index 6572d1e9d..301cef7da 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
@@ -320,7 +320,8 @@ func (gpk *GroupPublicKey) VerifySignature(
return gpk.GroupPublicKey.VerifySignature(hash, sig)
}
-func calcQualifyNodes(
+// CalcQualifyNodes returns the qualified nodes.
+func CalcQualifyNodes(
mpks []*MasterPublicKey, complaints []*Complaint, threshold int) (
qualifyIDs cryptoDKG.IDs, qualifyNodeIDs map[types.NodeID]struct{}, err error) {
if len(mpks) < threshold {
@@ -371,7 +372,7 @@ func NewGroupPublicKey(
threshold int) (
*GroupPublicKey, error) {
qualifyIDs, qualifyNodeIDs, err :=
- calcQualifyNodes(mpks, complaints, threshold)
+ CalcQualifyNodes(mpks, complaints, threshold)
if err != nil {
return nil, err
}
@@ -417,7 +418,7 @@ func NewNodePublicKeys(
threshold int) (
*NodePublicKeys, error) {
qualifyIDs, qualifyNodeIDs, err :=
- calcQualifyNodes(mpks, complaints, threshold)
+ CalcQualifyNodes(mpks, complaints, threshold)
if err != nil {
return nil, err
}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index a3182f836..4ad0a8c6c 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -141,16 +141,16 @@
{
"checksumSHA1": "In6vBHYUsX7DUIGiFN2hQggBgvI=",
"path": "github.com/dexon-foundation/dexon-consensus/common",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "fE4+Jlw+2y4JJMHtGuHxHWqqPfY=",
"path": "github.com/dexon-foundation/dexon-consensus/core",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
@@ -165,64 +165,64 @@
{
"checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "mMdctxTa/jNwAwZjjYoyEZdLoF8=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "hj/KetWUHp+1CX+50V0QnCthfWc=",
"path": "github.com/dexon-foundation/dexon-consensus/core/db",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "pxAzlI5kjyIAJSX+/aRGjjhR+pw=",
"path": "github.com/dexon-foundation/dexon-consensus/core/syncer",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "TmZF8DyrzGHTTfXXIFnKlzva3mU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "yoVRmvJDCp/1jSfY7wMt2LBQ9e8=",
+ "checksumSHA1": "5BskQaPpK94/ecmvy845hwM6F+8=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "pvJYiUy3EubRjeh5VYpt73Jjg1Q=",
"path": "github.com/dexon-foundation/dexon-consensus/core/utils",
- "revision": "ecc5e12b1ac4826e302607769f5b831ab4c27046",
- "revisionTime": "2019-04-01T04:25:09Z",
+ "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
+ "revisionTime": "2019-04-01T11:36:40Z",
"version": "single-chain",
"versionExact": "single-chain"
},