aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm/utils.go
blob: 0cc6343cce8f45211f1fb56c9f7346d2542a18f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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()
}