package vm import ( "errors" "math/big" "github.com/tangerine-network/go-tangerine/common" "github.com/tangerine-network/go-tangerine/core/state" "github.com/tangerine-network/go-tangerine/crypto" "github.com/tangerine-network/go-tangerine/log" dexCore "github.com/tangerine-network/tangerine-consensus/core" ) type GovUtilInterface interface { GetHeadGovState() (*GovernanceState, error) StateAt(height uint64) (*state.StateDB, error) } type GovUtil struct { Intf GovUtilInterface } func (g GovUtil) GetRoundHeight(round uint64) uint64 { gs, err := g.Intf.GetHeadGovState() if err != nil { return 0 } return gs.RoundHeight(big.NewInt(int64(round))).Uint64() } func (g GovUtil) GetStateAtRound(round uint64) (*GovernanceState, error) { height := g.GetRoundHeight(round) if round != 0 && height == 0 { log.Error("Governance state incorrect", "round", round, "got height", height) return nil, errors.New("incorrect governance state") } s, err := g.Intf.StateAt(height) if err != nil { return nil, err } return &GovernanceState{StateDB: s}, nil } func (g GovUtil) GetConfigState(round uint64) (*GovernanceState, error) { if round < dexCore.ConfigRoundShift { round = 0 } else { round -= dexCore.ConfigRoundShift } return g.GetStateAtRound(round) } func (g *GovUtil) CRSRound() uint64 { gs, err := g.Intf.GetHeadGovState() if err != nil { return 0 } return gs.CRSRound().Uint64() } func (g GovUtil) CRS(round uint64) common.Hash { if round <= dexCore.DKGDelayRound { s, err := g.GetStateAtRound(0) if err != nil { return common.Hash{} } crs := s.CRS() for i := uint64(0); i < round; i++ { crs = crypto.Keccak256Hash(crs[:]) } return crs } if round > g.CRSRound() { return common.Hash{} } var s *GovernanceState var err error if round == g.CRSRound() { s, err = g.Intf.GetHeadGovState() if err != nil { return common.Hash{} } } else { s, err = g.GetStateAtRound(round) if err != nil { return common.Hash{} } } return s.CRS() }