aboutsummaryrefslogtreecommitdiffstats
path: root/dex
diff options
context:
space:
mode:
authorSonic <sonic@dexon.org>2018-11-22 15:09:49 +0800
committerWei-Ning Huang <w@byzantine-lab.io>2019-06-12 17:27:18 +0800
commitfc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60 (patch)
treeab71c9a0511121f35cce5a666ea7574bf0ab31b0 /dex
parent9d8b455d62d851d265a8383a5d34e9c594ff89c9 (diff)
downloadgo-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar.gz
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar.bz2
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar.lz
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar.xz
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.tar.zst
go-tangerine-fc2df4ef1c189accd7a4c4ed90d8e3562b5d9e60.zip
core, dex, downloader: refactor governance
Diffstat (limited to 'dex')
-rw-r--r--dex/downloader/governance.go142
-rw-r--r--dex/governance.go112
-rw-r--r--dex/handler.go12
-rw-r--r--dex/protocol.go3
4 files changed, 48 insertions, 221 deletions
diff --git a/dex/downloader/governance.go b/dex/downloader/governance.go
index 40233f1a8..38281b4a8 100644
--- a/dex/downloader/governance.go
+++ b/dex/downloader/governance.go
@@ -1,27 +1,22 @@
package downloader
import (
- "math/big"
+ "fmt"
"sync"
- "time"
-
- dexCore "github.com/dexon-foundation/dexon-consensus/core"
- coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
- dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
"github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core"
"github.com/dexon-foundation/dexon/core/state"
"github.com/dexon-foundation/dexon/core/types"
- "github.com/dexon-foundation/dexon/core/vm"
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/log"
- "github.com/dexon-foundation/dexon/rlp"
"github.com/dexon-foundation/dexon/trie"
)
-// This is a goverance for fast sync
-type governance struct {
+// governanceDB is backed by memory db for fast sync.
+// it implements core.GovernanceStateDB
+type governanceStateDB struct {
db ethdb.Database
headRoot common.Hash
headHeight uint64
@@ -29,66 +24,32 @@ type governance struct {
mu sync.Mutex
}
-func newGovernance(headState *types.GovState) *governance {
- db := ethdb.NewMemDatabase()
- g := &governance{
- db: db,
- headRoot: headState.Root,
- headHeight: headState.Number.Uint64(),
- height2Root: make(map[uint64]common.Hash),
- }
- g.StoreState(headState)
-
- statedb, err := state.New(headState.Root, state.NewDatabase(g.db))
- if statedb == nil || err != nil {
- log.Error("New governance fail", "statedb == nil", statedb == nil, "err", err)
- }
- return g
-}
-
-func (g *governance) getHeadHelper() *vm.GovernanceStateHelper {
- return g.getHelper(g.headRoot)
+func (g *governanceStateDB) State() (*state.StateDB, error) {
+ return state.New(g.headRoot, state.NewDatabase(g.db))
}
-func (g *governance) getHelperByRound(round uint64) *vm.GovernanceStateHelper {
- height := g.GetRoundHeight(round)
+func (g *governanceStateDB) StateAt(height uint64) (*state.StateDB, error) {
root, exists := g.height2Root[height]
if !exists {
- log.Debug("Gov get helper by round", "round", round, "exists", exists)
- return nil
+ return nil, fmt.Errorf("Governance state not ready, height: %d", height)
}
- return g.getHelper(root)
+ return state.New(root, state.NewDatabase(g.db))
}
-func (g *governance) getHelper(root common.Hash) *vm.GovernanceStateHelper {
- statedb, err := state.New(root, state.NewDatabase(g.db))
- if statedb == nil || err != nil {
- return nil
- }
- return &vm.GovernanceStateHelper{statedb}
-}
-
-func (g *governance) GetRoundHeight(round uint64) uint64 {
- var h uint64
- if helper := g.getHeadHelper(); helper != nil {
- h = helper.RoundHeight(big.NewInt(int64(round))).Uint64()
- }
- return h
-}
-
-func (g *governance) StoreState(s *types.GovState) {
+func (g *governanceStateDB) StoreState(s *types.GovState) {
g.mu.Lock()
defer g.mu.Unlock()
+ log.Debug("Store state", "height", s.Number.Uint64())
- // store the hight -> root mapping
+ // Store the height -> root mapping.
g.height2Root[s.Number.Uint64()] = s.Root
- // store the account
+ // Store the account.
for _, node := range s.Proof {
g.db.Put(crypto.Keccak256(node), node)
}
- // store the storage
+ // Store the storage.
triedb := trie.NewDatabase(g.db)
t, err := trie.New(common.Hash{}, triedb)
if err != nil {
@@ -101,70 +62,33 @@ func (g *governance) StoreState(s *types.GovState) {
triedb.Commit(t.Hash(), false)
if s.Number.Uint64() > g.headHeight {
- log.Debug("Gov head root changed", "number", s.Number.Uint64())
+ log.Debug("Governance head root changed", "number", s.Number.Uint64())
g.headRoot = s.Root
g.headHeight = s.Number.Uint64()
}
}
-// Return the genesis configuration if round == 0.
-func (g *governance) Configuration(round uint64) *coreTypes.Config {
- if round < dexCore.ConfigRoundShift {
- round = 0
- } else {
- round -= dexCore.ConfigRoundShift
- }
- helper := g.getHelperByRound(round)
- if helper == nil {
- log.Warn("Get config helper fail", "round - round shift", round)
- return nil
- }
- c := helper.Configuration()
- return &coreTypes.Config{
- NumChains: c.NumChains,
- LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
- LambdaDKG: time.Duration(c.LambdaDKG) * time.Millisecond,
- K: int(c.K),
- PhiRatio: c.PhiRatio,
- NotarySetSize: c.NotarySetSize,
- DKGSetSize: c.DKGSetSize,
- RoundInterval: time.Duration(c.RoundInterval) * time.Millisecond,
- MinBlockInterval: time.Duration(c.MinBlockInterval) * time.Millisecond,
- }
+// This is a governance for fast sync
+type governance struct {
+ *core.Governance
+ db *governanceStateDB
}
-// DKGComplaints gets all the DKGComplaints of round.
-func (g *governance) DKGComplaints(round uint64) []*dkgTypes.Complaint {
- helper := g.getHeadHelper()
- var dkgComplaints []*dkgTypes.Complaint
- for _, pk := range helper.DKGComplaints(big.NewInt(int64(round))) {
- x := new(dkgTypes.Complaint)
- if err := rlp.DecodeBytes(pk, x); err != nil {
- panic(err)
- }
- dkgComplaints = append(dkgComplaints, x)
+func newGovernance(headState *types.GovState) *governance {
+ db := ethdb.NewMemDatabase()
+ govStateDB := &governanceStateDB{
+ db: db,
+ headRoot: headState.Root,
+ headHeight: headState.Number.Uint64(),
+ height2Root: make(map[uint64]common.Hash),
}
- return dkgComplaints
-}
-
-// DKGMasterPublicKeys gets all the DKGMasterPublicKey of round.
-func (g *governance) DKGMasterPublicKeys(round uint64) []*dkgTypes.MasterPublicKey {
- helper := g.getHeadHelper()
- var dkgMasterPKs []*dkgTypes.MasterPublicKey
- for _, pk := range helper.DKGMasterPublicKeys(big.NewInt(int64(round))) {
- x := new(dkgTypes.MasterPublicKey)
- if err := rlp.DecodeBytes(pk, x); err != nil {
- panic(err)
- }
- dkgMasterPKs = append(dkgMasterPKs, x)
+ govStateDB.StoreState(headState)
+ return &governance{
+ Governance: core.NewGovernance(govStateDB),
+ db: govStateDB,
}
- return dkgMasterPKs
}
-// IsDKGFinal checks if DKG is final.
-func (g *governance) IsDKGFinal(round uint64) bool {
- helper := g.getHeadHelper()
- threshold := 2*uint64(g.Configuration(round).DKGSetSize)/3 + 1
- count := helper.DKGFinalizedsCount(big.NewInt(int64(round))).Uint64()
- return count >= threshold
+func (g *governance) StoreState(s *types.GovState) {
+ g.db.StoreState(s)
}
diff --git a/dex/governance.go b/dex/governance.go
index 01f39b68c..aeb6d3fb0 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -5,26 +5,26 @@ import (
"crypto/ecdsa"
"encoding/hex"
"math/big"
- "time"
coreCommon "github.com/dexon-foundation/dexon-consensus/common"
dexCore "github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreEcdsa "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
- coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
"github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core"
"github.com/dexon-foundation/dexon/core/types"
"github.com/dexon-foundation/dexon/core/vm"
"github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/log"
"github.com/dexon-foundation/dexon/params"
"github.com/dexon-foundation/dexon/rlp"
- "github.com/dexon-foundation/dexon/rpc"
)
type DexconGovernance struct {
+ *core.Governance
+
b *DexAPIBackend
chainConfig *params.ChainConfig
privateKey *ecdsa.PrivateKey
@@ -32,11 +32,13 @@ type DexconGovernance struct {
nodeSetCache *dexCore.NodeSetCache
}
-// NewDexconGovernance retruns a governance implementation of the DEXON
+// NewDexconGovernance returns a governance implementation of the DEXON
// consensus governance interface.
func NewDexconGovernance(backend *DexAPIBackend, chainConfig *params.ChainConfig,
privKey *ecdsa.PrivateKey) *DexconGovernance {
g := &DexconGovernance{
+ Governance: core.NewGovernance(
+ core.NewGovernanceStateDB(backend.dex.BlockChain())),
b: backend,
chainConfig: chainConfig,
privateKey: privKey,
@@ -46,67 +48,9 @@ func NewDexconGovernance(backend *DexAPIBackend, chainConfig *params.ChainConfig
return g
}
-func (d *DexconGovernance) GetRoundHeight(ctx context.Context, round uint64) (uint64, error) {
- state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
- if state == nil || err != nil {
- return 0, err
- }
- s := vm.GovernanceStateHelper{state}
- return s.RoundHeight(big.NewInt(int64(round))).Uint64(), nil
-}
-
-func (d *DexconGovernance) getGovState() *vm.GovernanceStateHelper {
- ctx := context.Background()
- state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
- if state == nil || err != nil {
- return nil
- }
-
- return &vm.GovernanceStateHelper{state}
-}
-
-func (d *DexconGovernance) getGovStateAtRound(round uint64) *vm.GovernanceStateHelper {
- if round < dexCore.ConfigRoundShift {
- round = 0
- } else {
- round -= dexCore.ConfigRoundShift
- }
- ctx := context.Background()
- blockHeight, err := d.GetRoundHeight(ctx, round)
- if err != nil {
- return nil
- }
-
- state, _, err := d.b.StateAndHeaderByNumber(ctx, rpc.BlockNumber(blockHeight))
- if state == nil || err != nil {
- log.Error("Failed to retrieve governance state", "round", round, "height", blockHeight)
- return nil
- }
- return &vm.GovernanceStateHelper{state}
-}
-
// DexconConfiguration return raw config in state.
func (d *DexconGovernance) DexconConfiguration(round uint64) *params.DexconConfig {
- s := d.getGovStateAtRound(round)
- return s.Configuration()
-}
-
-// Configuration returns the system configuration for consensus core to use.
-func (d *DexconGovernance) Configuration(round uint64) *coreTypes.Config {
- s := d.getGovStateAtRound(round)
- c := s.Configuration()
-
- return &coreTypes.Config{
- NumChains: c.NumChains,
- LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
- LambdaDKG: time.Duration(c.LambdaDKG) * time.Millisecond,
- K: int(c.K),
- PhiRatio: c.PhiRatio,
- NotarySetSize: c.NotarySetSize,
- DKGSetSize: c.DKGSetSize,
- RoundInterval: time.Duration(c.RoundInterval) * time.Millisecond,
- MinBlockInterval: time.Duration(c.MinBlockInterval) * time.Millisecond,
- }
+ return d.GetConfigHelper(round).Configuration()
}
func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
@@ -146,12 +90,12 @@ func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
// CRS returns the CRS for a given round.
func (d *DexconGovernance) CRS(round uint64) coreCommon.Hash {
- s := d.getGovState()
+ s := d.GetHeadHelper()
return coreCommon.Hash(s.CRS(big.NewInt(int64(round))))
}
func (d *DexconGovernance) LenCRS() uint64 {
- s := d.getGovState()
+ s := d.GetHeadHelper()
return s.LenCRS().Uint64()
}
@@ -174,7 +118,7 @@ func (d *DexconGovernance) ProposeCRS(round uint64, signedCRS []byte) {
// NodeSet returns the current node set.
func (d *DexconGovernance) NodeSet(round uint64) []coreCrypto.PublicKey {
- s := d.getGovStateAtRound(round)
+ s := d.GetConfigHelper(round)
var pks []coreCrypto.PublicKey
for _, n := range s.QualifiedNodes() {
@@ -228,20 +172,6 @@ func (d *DexconGovernance) AddDKGComplaint(round uint64, complaint *dkgTypes.Com
}
}
-// DKGComplaints gets all the DKGComplaints of round.
-func (d *DexconGovernance) DKGComplaints(round uint64) []*dkgTypes.Complaint {
- s := d.getGovState()
- var dkgComplaints []*dkgTypes.Complaint
- for _, pk := range s.DKGComplaints(big.NewInt(int64(round))) {
- x := new(dkgTypes.Complaint)
- if err := rlp.DecodeBytes(pk, x); err != nil {
- panic(err)
- }
- dkgComplaints = append(dkgComplaints, x)
- }
- return dkgComplaints
-}
-
// AddDKGMasterPublicKey adds a DKGMasterPublicKey.
func (d *DexconGovernance) AddDKGMasterPublicKey(round uint64, masterPublicKey *dkgTypes.MasterPublicKey) {
method := vm.GovernanceContractName2Method["addDKGMasterPublicKey"]
@@ -265,20 +195,6 @@ func (d *DexconGovernance) AddDKGMasterPublicKey(round uint64, masterPublicKey *
}
}
-// DKGMasterPublicKeys gets all the DKGMasterPublicKey of round.
-func (d *DexconGovernance) DKGMasterPublicKeys(round uint64) []*dkgTypes.MasterPublicKey {
- s := d.getGovState()
- var dkgMasterPKs []*dkgTypes.MasterPublicKey
- for _, pk := range s.DKGMasterPublicKeys(big.NewInt(int64(round))) {
- x := new(dkgTypes.MasterPublicKey)
- if err := rlp.DecodeBytes(pk, x); err != nil {
- panic(err)
- }
- dkgMasterPKs = append(dkgMasterPKs, x)
- }
- return dkgMasterPKs
-}
-
// AddDKGFinalize adds a DKG finalize message.
func (d *DexconGovernance) AddDKGFinalize(round uint64, final *dkgTypes.Finalize) {
method := vm.GovernanceContractName2Method["addDKGFinalize"]
@@ -302,14 +218,6 @@ func (d *DexconGovernance) AddDKGFinalize(round uint64, final *dkgTypes.Finalize
}
}
-// IsDKGFinal checks if DKG is final.
-func (d *DexconGovernance) IsDKGFinal(round uint64) bool {
- s := d.getGovState()
- threshold := 2*s.DKGSetSize().Uint64()/3 + 1
- count := s.DKGFinalizedsCount(big.NewInt(int64(round))).Uint64()
- return count >= threshold
-}
-
func (d *DexconGovernance) GetNumChains(round uint64) uint32 {
return d.Configuration(round).NumChains
}
diff --git a/dex/handler.go b/dex/handler.go
index a86a68329..b4499ae5a 100644
--- a/dex/handler.go
+++ b/dex/handler.go
@@ -34,7 +34,6 @@
package dex
import (
- "context"
"encoding/json"
"errors"
"fmt"
@@ -495,7 +494,6 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
}
- ctx := context.Background()
if query.WithGov && len(headers) > 0 {
last := headers[len(headers)-1]
currentBlock := pm.blockchain.CurrentBlock()
@@ -513,11 +511,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if r == 0 {
continue
}
- h, err := pm.gov.GetRoundHeight(ctx, r)
- if err != nil {
- log.Warn("Get round height fail", "err", err)
- return p.SendBlockHeaders([]*types.HeaderWithGovState{})
- }
+ h := pm.gov.GetRoundHeight(r)
log.Trace("#Snapshot height", "height", h)
if h == 0 {
h = height
@@ -1181,7 +1175,9 @@ func (pm *ProtocolManager) peerSetLoop() {
}
if newRound == round+1 {
pm.peers.BuildConnection(newRound)
- pm.peers.ForgetConnection(round - 1)
+ if round >= 1 {
+ pm.peers.ForgetConnection(round - 1)
+ }
} else {
// just forget all network connection and rebuild.
pm.peers.ForgetConnection(round)
diff --git a/dex/protocol.go b/dex/protocol.go
index 0c271248e..21168e917 100644
--- a/dex/protocol.go
+++ b/dex/protocol.go
@@ -34,7 +34,6 @@
package dex
import (
- "context"
"crypto/ecdsa"
"fmt"
"io"
@@ -144,7 +143,7 @@ type txPool interface {
}
type governance interface {
- GetRoundHeight(context.Context, uint64) (uint64, error)
+ GetRoundHeight(uint64) uint64
GetNumChains(uint64) uint32