diff options
author | Wei-Ning Huang <w@byzantine-lab.io> | 2019-08-04 13:39:30 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-09-17 16:57:31 +0800 |
commit | 5e30a1686f8a049c27d10d21cca1b7b5aee18f70 (patch) | |
tree | 8d687af451cd3f86b865e92814f3e5fd9a65541b /core | |
parent | 174f6bfcdf4e2c7fea3a071653908b477ad9a3b3 (diff) | |
download | go-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)
Diffstat (limited to 'core')
-rw-r--r-- | core/governance.go | 2 | ||||
-rw-r--r-- | core/vm/oracle_contracts.go | 2 | ||||
-rw-r--r-- | core/vm/utils.go | 40 |
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{} } |