aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
Diffstat (limited to 'core/vm')
-rw-r--r--core/vm/oracle.go2
-rw-r--r--core/vm/oracle_contracts.go102
-rw-r--r--core/vm/oracle_contracts_test.go4
-rw-r--r--core/vm/utils.go92
4 files changed, 137 insertions, 63 deletions
diff --git a/core/vm/oracle.go b/core/vm/oracle.go
index ee28343ae..8c8a3006c 100644
--- a/core/vm/oracle.go
+++ b/core/vm/oracle.go
@@ -45,7 +45,7 @@ type OracleContract interface {
var OracleContracts = map[common.Address]func() OracleContract{
GovernanceContractAddress: func() OracleContract {
return &GovernanceContract{
- coreDKGUtils: &defaultCoreDKGUtils{},
+ coreDKGUtil: &defaultCoreDKGUtil{},
}
},
RandomContractAddress: func() OracleContract {
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index e850811ff..a2c7d7814 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -29,6 +29,7 @@ import (
"github.com/tangerine-network/go-tangerine/accounts/abi"
"github.com/tangerine-network/go-tangerine/common"
+ "github.com/tangerine-network/go-tangerine/core/state"
"github.com/tangerine-network/go-tangerine/core/types"
"github.com/tangerine-network/go-tangerine/crypto"
"github.com/tangerine-network/go-tangerine/params"
@@ -529,6 +530,16 @@ func (s *GovernanceState) QualifiedNodes() []*nodeInfo {
}
return nodes
}
+func (s *GovernanceState) FinedNodes() []*nodeInfo {
+ var nodes []*nodeInfo
+ for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
+ node := s.Node(big.NewInt(i))
+ if node.Fined.Cmp(big.NewInt(0)) > 0 {
+ nodes = append(nodes, node)
+ }
+ }
+ return nodes
+}
// mapping(address => uint256) public nodesOffsetByAddress;
func (s *GovernanceState) NodesOffsetByAddress(addr common.Address) *big.Int {
@@ -1274,47 +1285,19 @@ func (s *GovernanceState) emitDKGReset(round *big.Int, blockHeight *big.Int) {
})
}
-func getRoundState(evm *EVM, round *big.Int) (*GovernanceState, error) {
- gs := &GovernanceState{evm.StateDB}
- height := gs.RoundHeight(round).Uint64()
- if round.Uint64() > dexCore.ConfigRoundShift {
- if height == 0 {
- return nil, errExecutionReverted
- }
- }
- statedb, err := evm.StateAtNumber(height)
- return &GovernanceState{statedb}, err
-}
-
-func getConfigState(evm *EVM, round *big.Int) (*GovernanceState, error) {
- configRound := big.NewInt(0)
- if round.Uint64() > dexCore.ConfigRoundShift {
- configRound = new(big.Int).Sub(round, big.NewInt(int64(dexCore.ConfigRoundShift)))
- }
- return getRoundState(evm, configRound)
-}
-
-type coreDKGUtils interface {
+type coreDKGUtil interface {
NewGroupPublicKey(*GovernanceState, *big.Int, int) (tsigVerifierIntf, error)
}
type tsigVerifierIntf interface {
VerifySignature(coreCommon.Hash, coreCrypto.Signature) bool
}
-// GovernanceContract represents the governance contract of DEXCON.
-type GovernanceContract struct {
- evm *EVM
- state GovernanceState
- contract *Contract
- coreDKGUtils coreDKGUtils
-}
-
-// defaultCoreDKGUtils implements coreDKGUtils.
-type defaultCoreDKGUtils struct {
+// defaultCoreDKGUtil implements coreDKGUtil.
+type defaultCoreDKGUtil struct {
gpk atomic.Value
}
-func (c *defaultCoreDKGUtils) NewGroupPublicKey(
+func (c *defaultCoreDKGUtil) NewGroupPublicKey(
state *GovernanceState, round *big.Int, threshold int) (tsigVerifierIntf, error) {
var gpk *dkgTypes.GroupPublicKey
var err error
@@ -1337,6 +1320,23 @@ func (c *defaultCoreDKGUtils) NewGroupPublicKey(
return gpk, nil
}
+// GovernanceContract represents the governance contract of DEXCON.
+type GovernanceContract struct {
+ evm *EVM
+ state GovernanceState
+ contract *Contract
+ coreDKGUtil coreDKGUtil
+ util GovUtil
+}
+
+func (g *GovernanceContract) StateAt(height uint64) (*state.StateDB, error) {
+ return g.evm.StateAtNumber(height)
+}
+
+func (g *GovernanceContract) GetHeadGovState() (*GovernanceState, error) {
+ return &g.state, nil
+}
+
func (g *GovernanceContract) Address() common.Address {
return GovernanceContractAddress
}
@@ -1358,7 +1358,7 @@ func (g *GovernanceContract) useGas(gas uint64) ([]byte, error) {
}
func (g *GovernanceContract) configNotarySetSize(round *big.Int) *big.Int {
- s, err := getConfigState(g.evm, round)
+ s, err := g.util.GetConfigState(round.Uint64())
if err != nil {
return big.NewInt(0)
}
@@ -1366,34 +1366,15 @@ func (g *GovernanceContract) configNotarySetSize(round *big.Int) *big.Int {
}
func (g *GovernanceContract) getNotarySet(round *big.Int) map[coreTypes.NodeID]struct{} {
- crsRound := g.state.CRSRound()
- var crs common.Hash
- cmp := round.Cmp(crsRound)
- if round.Cmp(big.NewInt(int64(dexCore.DKGDelayRound))) <= 0 {
- state, err := getRoundState(g.evm, big.NewInt(0))
- if err != nil {
- return map[coreTypes.NodeID]struct{}{}
- }
- crs = state.CRS()
- for i := uint64(0); i < round.Uint64(); i++ {
- crs = crypto.Keccak256Hash(crs[:])
- }
- } else if cmp > 0 {
+ crs := g.util.CRS(round.Uint64())
+ if crs == (common.Hash{}) {
return map[coreTypes.NodeID]struct{}{}
- } else if cmp == 0 {
- crs = g.state.CRS()
- } else {
- state, err := getRoundState(g.evm, round)
- if err != nil {
- return map[coreTypes.NodeID]struct{}{}
- }
- crs = state.CRS()
}
target := coreTypes.NewNotarySetTarget(coreCommon.Hash(crs))
ns := coreTypes.NewNodeSet()
- state, err := getConfigState(g.evm, round)
+ state, err := g.util.GetConfigState(round.Uint64())
if err != nil {
return map[coreTypes.NodeID]struct{}{}
}
@@ -2000,7 +1981,7 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
threshold := coreUtils.GetDKGThreshold(&coreTypes.Config{
NotarySetSize: uint32(g.state.NotarySetSize().Uint64())})
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(&g.state, nextRound, threshold)
+ dkgGPK, err := g.coreDKGUtil.NewGroupPublicKey(&g.state, nextRound, threshold)
if err != nil {
return nil, errExecutionReverted
}
@@ -2137,7 +2118,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
new(big.Int).Mul(big.NewInt(100), resetCount))
roundHeight := g.state.RoundHeight(round)
- gs, err := getConfigState(g.evm, round)
+ gs, err := g.util.GetConfigState(round.Uint64())
if err != nil {
return nil, err
}
@@ -2167,7 +2148,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
// If 2f + 1 of DKG set is finalized, check if DKG succeeded.
if g.state.DKGFinalizedsCount().Uint64() >= threshold {
- gpk, err := g.coreDKGUtils.NewGroupPublicKey(&g.state, nextRound, tsigThreshold)
+ gpk, err := g.coreDKGUtil.NewGroupPublicKey(&g.state, nextRound, tsigThreshold)
if gpk, ok := gpk.(*dkgTypes.GroupPublicKey); ok {
if len(gpk.QualifyNodeIDs) < coreUtils.GetDKGValidThreshold(&coreTypes.Config{
NotarySetSize: uint32(g.configNotarySetSize(nextRound).Uint64())}) {
@@ -2191,7 +2172,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
g.fineFailStopDKG(tsigThreshold)
// Update CRS.
- state, err := getRoundState(g.evm, round)
+ state, err := g.util.GetStateAtRound(round.Uint64())
if err != nil {
return nil, errExecutionReverted
}
@@ -2208,7 +2189,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
prevCRS = crypto.Keccak256Hash(prevCRS[:])
}
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(state, round,
+ dkgGPK, err := g.coreDKGUtil.NewGroupPublicKey(state, round,
coreUtils.GetDKGThreshold(&coreTypes.Config{
NotarySetSize: uint32(g.configNotarySetSize(round).Uint64())}))
if err != nil {
@@ -2251,6 +2232,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
g.evm = evm
g.state = GovernanceState{evm.StateDB}
g.contract = contract
+ g.util = GovUtil{g}
// Parse input.
method, exists := GovernanceABI.Sig2Method[string(input[:4])]
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index ef6b9bde8..f0b045ac8 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -237,7 +237,7 @@ func (g *GovernanceContractTestSuite) SetupTest() {
func (g *GovernanceContractTestSuite) TearDownTest() {
OracleContracts[GovernanceContractAddress] = func() OracleContract {
return &GovernanceContract{
- coreDKGUtils: &defaultCoreDKGUtils{},
+ coreDKGUtil: &defaultCoreDKGUtil{},
}
}
}
@@ -1176,7 +1176,7 @@ func (g *GovernanceContractTestSuite) TestResetDKG() {
}
OracleContracts[GovernanceContractAddress] = func() OracleContract {
return &GovernanceContract{
- coreDKGUtils: mock,
+ coreDKGUtil: mock,
}
}
diff --git a/core/vm/utils.go b/core/vm/utils.go
new file mode 100644
index 000000000..0cc6343cc
--- /dev/null
+++ b/core/vm/utils.go
@@ -0,0 +1,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()
+}