aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@byzantine-lab.io>2019-08-04 13:39:30 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-09-17 16:57:31 +0800
commit5e30a1686f8a049c27d10d21cca1b7b5aee18f70 (patch)
tree8d687af451cd3f86b865e92814f3e5fd9a65541b
parent174f6bfcdf4e2c7fea3a071653908b477ad9a3b3 (diff)
downloadgo-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar.gz
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar.bz2
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar.lz
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar.xz
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.tar.zst
go-tangerine-5e30a1686f8a049c27d10d21cca1b7b5aee18f70.zip
core: consider reset round when getting config state
Previous config snapshot is determined as follows, for round n: Return the snapshot state of round (n - ConfigRoundShift) However this may cause the system to stuck at a particular round if the DKG for the next round continues to fail (maybe due to node failure). To fix this, instead of using the simple logic above, we consider the reset rounds as a normal round, and use the snapshot of the reset rounds as config. Thus we could gradually push out the broken nodes from nodeset. The snapshot is now determined as follows, for round n: If resetCount < ConfigRoundShift Return the snapshot state of round (n - ConfigRoundShift) Else Reutrn the stateshot state of (n + resetCount - ConfigRoundShift)
-rw-r--r--core/governance.go2
-rw-r--r--core/vm/oracle_contracts.go2
-rw-r--r--core/vm/utils.go40
3 files changed, 35 insertions, 9 deletions
diff --git a/core/governance.go b/core/governance.go
index 8bad0ca98..8cfed5e13 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -110,7 +110,7 @@ func (g *Governance) GetStateForDKGAtRound(round uint64) (*vm.GovernanceState, e
if round == dkgRound {
return gs, nil
}
- return g.util.GetStateAtRound(round)
+ return g.util.GetRoundState(round)
}
func (g *Governance) CRSRound() uint64 {
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index a2c7d7814..e1408d8d2 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -2172,7 +2172,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
g.fineFailStopDKG(tsigThreshold)
// Update CRS.
- state, err := g.util.GetStateAtRound(round.Uint64())
+ state, err := g.util.GetRoundState(round.Uint64())
if err != nil {
return nil, errExecutionReverted
}
diff --git a/core/vm/utils.go b/core/vm/utils.go
index 0cc6343cc..5ccc47867 100644
--- a/core/vm/utils.go
+++ b/core/vm/utils.go
@@ -28,7 +28,7 @@ func (g GovUtil) GetRoundHeight(round uint64) uint64 {
return gs.RoundHeight(big.NewInt(int64(round))).Uint64()
}
-func (g GovUtil) GetStateAtRound(round uint64) (*GovernanceState, error) {
+func (g GovUtil) GetRoundState(round uint64) (*GovernanceState, error) {
height := g.GetRoundHeight(round)
if round != 0 && height == 0 {
@@ -44,12 +44,38 @@ func (g GovUtil) GetStateAtRound(round uint64) (*GovernanceState, error) {
}
func (g GovUtil) GetConfigState(round uint64) (*GovernanceState, error) {
+ headState, err := g.Intf.GetHeadGovState()
+ if err != nil {
+ return nil, err
+ }
+
if round < dexCore.ConfigRoundShift {
- round = 0
- } else {
- round -= dexCore.ConfigRoundShift
+ return g.GetRoundState(0)
}
- return g.GetStateAtRound(round)
+
+ resetCount := headState.DKGResetCount(new(big.Int).SetUint64(round)).Uint64()
+
+ // If we are resetting more round then ConfigRoundShift, we need to get the
+ // state of (resetCount - ConfigRoundShift) instead.
+ if resetCount >= dexCore.ConfigRoundShift {
+ shift := resetCount - dexCore.ConfigRoundShift
+
+ prevConfigState, err := g.GetConfigState(round - 1)
+ if err != nil {
+ log.Error("Failed to get previous round config state", "round", round-1)
+ return nil, err
+ }
+
+ height := g.GetRoundHeight(round-1) + shift*prevConfigState.RoundLength().Uint64()
+ s, err := g.Intf.StateAt(height)
+ if err != nil {
+ log.Error("Failed to get state", "height", height)
+ return nil, err
+ }
+ return &GovernanceState{StateDB: s}, nil
+ }
+
+ return g.GetRoundState(round - dexCore.ConfigRoundShift)
}
func (g *GovUtil) CRSRound() uint64 {
@@ -62,7 +88,7 @@ func (g *GovUtil) CRSRound() uint64 {
func (g GovUtil) CRS(round uint64) common.Hash {
if round <= dexCore.DKGDelayRound {
- s, err := g.GetStateAtRound(0)
+ s, err := g.GetRoundState(0)
if err != nil {
return common.Hash{}
}
@@ -83,7 +109,7 @@ func (g GovUtil) CRS(round uint64) common.Hash {
return common.Hash{}
}
} else {
- s, err = g.GetStateAtRound(round)
+ s, err = g.GetRoundState(round)
if err != nil {
return common.Hash{}
}