aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--consensus/dexcon/dexcon.go42
-rw-r--r--consensus/dexcon/dexcon_test.go10
-rw-r--r--core/governance.go111
-rw-r--r--core/vm/oracle_contract_abi.go21
-rw-r--r--core/vm/oracle_contracts.go49
-rw-r--r--core/vm/oracle_contracts_test.go88
-rw-r--r--dex/app_test.go12
-rw-r--r--dex/downloader/testchain_test.go4
-rw-r--r--dex/governance.go99
-rw-r--r--dex/recovery.go2
-rw-r--r--params/config.go8
11 files changed, 294 insertions, 152 deletions
diff --git a/consensus/dexcon/dexcon.go b/consensus/dexcon/dexcon.go
index c837e3a43..3e520438b 100644
--- a/consensus/dexcon/dexcon.go
+++ b/consensus/dexcon/dexcon.go
@@ -17,6 +17,8 @@
package dexcon
import (
+ "encoding/hex"
+ "fmt"
"math/big"
"github.com/dexon-foundation/dexon/common"
@@ -24,11 +26,13 @@ import (
"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/log"
"github.com/dexon-foundation/dexon/rpc"
)
type GovernanceStateFetcher interface {
GetStateForConfigAtRound(round uint64) *vm.GovernanceState
+ NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error)
}
// Dexcon is a delegated proof-of-stake consensus engine.
@@ -137,8 +141,39 @@ func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, sta
gs := vm.GovernanceState{state}
height := gs.RoundHeight(new(big.Int).SetUint64(header.Round))
+
+ // The first block of a round is found.
if header.Round > 0 && height.Uint64() == 0 {
gs.PushRoundHeight(header.Number)
+
+ // Check for dead node and disqualify them.
+ // A dead node node is defined as: a notary set node that did not propose
+ // any block in the past round.
+ addrs, err := d.govStateFetcer.NotarySetNodeKeyAddresses(header.Round - 1)
+ if err != nil {
+ panic(err)
+ }
+
+ gcs := d.govStateFetcer.GetStateForConfigAtRound(header.Round - 1)
+
+ for addr := range addrs {
+ offset := gcs.NodesOffsetByNodeKeyAddress(addr)
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ panic(fmt.Errorf("invalid notary set found, addr = %s", addr.String()))
+ }
+
+ node := gcs.Node(offset)
+ lastHeight := gs.LastProposedHeight(node.Owner)
+ prevRoundHeight := gs.RoundHeight(big.NewInt(int64(header.Round - 1)))
+
+ if lastHeight.Uint64() < prevRoundHeight.Uint64() {
+ log.Info("Disqualify node", "round", header.Round, "nodePubKey", hex.EncodeToString(node.PublicKey))
+ err = gs.Disqualify(node)
+ if err != nil {
+ log.Error("Failed to disqualify node", "err", err)
+ }
+ }
+ }
}
// Distribute block reward and halving condition.
@@ -147,16 +182,17 @@ func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, sta
} else {
reward := d.calculateBlockReward(int64(header.Round), state)
state.AddBalance(header.Coinbase, reward)
-
+ header.Reward = reward
gs.IncTotalSupply(reward)
- config := gs.Configuration()
+ // Record last proposed height.
+ gs.PutLastProposedHeight(header.Coinbase, header.Number)
// Check if halving checkpoint reached.
+ config := gs.Configuration()
if gs.TotalSupply().Cmp(config.NextHalvingSupply) >= 0 {
gs.MiningHalved()
}
- header.Reward = reward
}
header.Root = state.IntermediateRoot(true)
diff --git a/consensus/dexcon/dexcon_test.go b/consensus/dexcon/dexcon_test.go
index f34823570..0181a80f3 100644
--- a/consensus/dexcon/dexcon_test.go
+++ b/consensus/dexcon/dexcon_test.go
@@ -31,14 +31,18 @@ import (
"github.com/dexon-foundation/dexon/params"
)
-type GovStateFetcher struct {
+type govStateFetcher struct {
statedb *state.StateDB
}
-func (g *GovStateFetcher) GetStateForConfigAtRound(_ uint64) *vm.GovernanceState {
+func (g *govStateFetcher) GetStateForConfigAtRound(_ uint64) *vm.GovernanceState {
return &vm.GovernanceState{g.statedb}
}
+func (g *govStateFetcher) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+ return make(map[common.Address]struct{}), nil
+}
+
type DexconTestSuite struct {
suite.Suite
@@ -86,7 +90,7 @@ func (d *DexconTestSuite) SetupTest() {
func (d *DexconTestSuite) TestBlockRewardCalculation() {
consensus := New()
- consensus.SetGovStateFetcher(&GovStateFetcher{d.stateDB})
+ consensus.SetGovStateFetcher(&govStateFetcher{d.stateDB})
d.s.IncTotalStaked(big.NewInt(1e18))
diff --git a/core/governance.go b/core/governance.go
index da310a1cd..bb49efb53 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -1,16 +1,22 @@
package core
import (
+ "encoding/hex"
"fmt"
"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/state"
"github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/log"
"github.com/dexon-foundation/dexon/rlp"
)
@@ -41,11 +47,14 @@ func (g *governanceStateDB) StateAt(height uint64) (*state.StateDB, error) {
}
type Governance struct {
- db GovernanceStateDB
+ db GovernanceStateDB
+ nodeSetCache *dexCore.NodeSetCache
}
func NewGovernance(db GovernanceStateDB) *Governance {
- return &Governance{db: db}
+ g := &Governance{db: db}
+ g.nodeSetCache = dexCore.NewNodeSetCache(g)
+ return g
}
func (g *Governance) GetHeadState() *vm.GovernanceState {
@@ -93,6 +102,43 @@ func (g *Governance) GetStateAtRound(round uint64) *vm.GovernanceState {
return &vm.GovernanceState{StateDB: s}
}
+func (g *Governance) GetStateForDKGAtRound(round uint64) *vm.GovernanceState {
+ dkgRound := g.GetHeadState().DKGRound().Uint64()
+ if round > dkgRound {
+ return nil
+ }
+ if round == dkgRound {
+ return g.GetHeadState()
+ }
+ return g.GetStateAtRound(round)
+}
+
+func (d *Governance) CRSRound() uint64 {
+ return d.GetHeadState().CRSRound().Uint64()
+}
+
+// CRS returns the CRS for a given round.
+func (d *Governance) CRS(round uint64) coreCommon.Hash {
+ if round <= dexCore.DKGDelayRound {
+ s := d.GetStateAtRound(0)
+ crs := s.CRS()
+ for i := uint64(0); i < round; i++ {
+ crs = crypto.Keccak256Hash(crs[:])
+ }
+ return coreCommon.Hash(crs)
+ }
+ if round > d.CRSRound() {
+ return coreCommon.Hash{}
+ }
+ var s *vm.GovernanceState
+ if round == d.CRSRound() {
+ s = d.GetHeadState()
+ } else {
+ s = d.GetStateAtRound(round)
+ }
+ return coreCommon.Hash(s.CRS())
+}
+
func (g *Governance) Configuration(round uint64) *coreTypes.Config {
configHelper := g.GetStateForConfigAtRound(round)
c := configHelper.Configuration()
@@ -110,15 +156,62 @@ func (g *Governance) GetRoundHeight(round uint64) uint64 {
return g.GetHeadState().RoundHeight(big.NewInt(int64(round))).Uint64()
}
-func (g *Governance) GetStateForDKGAtRound(round uint64) *vm.GovernanceState {
- dkgRound := g.GetHeadState().DKGRound().Uint64()
- if round > dkgRound {
- return nil
+// NodeSet returns the current node set.
+func (d *Governance) NodeSet(round uint64) []coreCrypto.PublicKey {
+ s := d.GetStateForConfigAtRound(round)
+ var pks []coreCrypto.PublicKey
+
+ for _, n := range s.QualifiedNodes() {
+ pk, err := coreEcdsa.NewPublicKeyFromByteSlice(n.PublicKey)
+ if err != nil {
+ panic(err)
+ }
+ pks = append(pks, pk)
}
- if round == dkgRound {
- return g.GetHeadState()
+ return pks
+}
+
+func (d *Governance) NotarySet(round uint64) (map[string]struct{}, error) {
+ notarySet, err := d.nodeSetCache.GetNotarySet(round)
+ if err != nil {
+ return nil, err
}
- return g.GetStateAtRound(round)
+
+ r := make(map[string]struct{}, len(notarySet))
+ for id := range notarySet {
+ if key, exists := d.nodeSetCache.GetPublicKey(id); exists {
+ r[hex.EncodeToString(key.Bytes())] = struct{}{}
+ }
+ }
+ return r, nil
+}
+
+func (d *Governance) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+ notarySet, err := d.nodeSetCache.GetNotarySet(round)
+ if err != nil {
+ return nil, err
+ }
+
+ r := make(map[common.Address]struct{}, len(notarySet))
+ for id := range notarySet {
+ r[vm.IdToAddress(id)] = struct{}{}
+ }
+ return r, nil
+}
+
+func (d *Governance) DKGSet(round uint64) (map[string]struct{}, error) {
+ dkgSet, err := d.nodeSetCache.GetDKGSet(round)
+ if err != nil {
+ return nil, err
+ }
+
+ r := make(map[string]struct{}, len(dkgSet))
+ for id := range dkgSet {
+ if key, exists := d.nodeSetCache.GetPublicKey(id); exists {
+ r[hex.EncodeToString(key.Bytes())] = struct{}{}
+ }
+ }
+ return r, nil
}
func (g *Governance) DKGComplaints(round uint64) []*dkgTypes.Complaint {
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index f0845eb7b..cd037b068 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -130,7 +130,7 @@ const GovernanceABIJSON = `
"type": "uint256"
},
{
- "name": "unstaked_at",
+ "name": "unstakedAt",
"type": "uint256"
}
],
@@ -530,6 +530,25 @@ const GovernanceABIJSON = `
},
{
"constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "lastProposedHeight",
+ "outputs": [
+ {
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [],
"name": "minGasPrice",
"outputs": [
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index c138a6b4a..ac6d7315c 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -62,6 +62,7 @@ const (
nodesLoc
nodesOffsetByAddressLoc
nodesOffsetByNodeKeyAddressLoc
+ lastProposedHeightLoc
crsRoundLoc
crsLoc
dkgRoundLoc
@@ -332,7 +333,8 @@ func (s *GovernanceState) DecTotalStaked(amount *big.Int) {
// string location;
// string url;
// uint256 unstaked;
-// uint256 unstaked_at;
+// uint256 unstakedAt;
+// uint256 lastProposedHeight;
// }
//
// Node[] nodes;
@@ -543,6 +545,16 @@ func (s *GovernanceState) GetNodeByID(id coreTypes.NodeID) (*nodeInfo, error) {
return node, nil
}
+// mapping(address => uint256) public lastProposedHeight;
+func (s *GovernanceState) LastProposedHeight(addr common.Address) *big.Int {
+ loc := s.getMapLoc(big.NewInt(lastProposedHeightLoc), addr.Bytes())
+ return s.getStateBigInt(loc)
+}
+func (s *GovernanceState) PutLastProposedHeight(addr common.Address, height *big.Int) {
+ loc := s.getMapLoc(big.NewInt(lastProposedHeightLoc), addr.Bytes())
+ s.setStateBigInt(loc, height)
+}
+
// uint256 public crsRound;
func (s *GovernanceState) CRSRound() *big.Int {
return s.getStateBigInt(big.NewInt(crsRoundLoc))
@@ -960,6 +972,31 @@ func (s *GovernanceState) Register(
s.IncTotalStaked(staked)
}
+func (s *GovernanceState) Disqualify(n *nodeInfo) error {
+ nodeAddr, err := publicKeyToNodeKeyAddress(n.PublicKey)
+ if err != nil {
+ return err
+ }
+
+ // Node might already been unstaked in the latest state.
+ offset := s.NodesOffsetByNodeKeyAddress(nodeAddr)
+ if offset.Cmp(big.NewInt(0)) < 0 {
+ return errors.New("node does not exist")
+ }
+
+ // Fine the node so it's staked value is 1 wei under minStake.
+ node := s.Node(offset)
+ extra := new(big.Int).Sub(new(big.Int).Sub(node.Staked, node.Fined), s.MinStake())
+ amount := new(big.Int).Add(extra, big.NewInt(1))
+
+ if amount.Cmp(big.NewInt(0)) > 0 {
+ node.Fined = new(big.Int).Add(node.Fined, amount)
+ s.UpdateNode(offset, node)
+ }
+
+ return nil
+}
+
const decimalMultiplier = 100000000.0
// Configuration returns the current configuration.
@@ -2248,6 +2285,16 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return nil, errExecutionReverted
}
return res, nil
+ case "lastProposedHeight":
+ address := common.Address{}
+ if err := method.Inputs.Unpack(&address, arguments); err != nil {
+ return nil, errExecutionReverted
+ }
+ res, err := method.Outputs.Pack(g.state.LastProposedHeight(address))
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ return res, nil
case "lockupPeriod":
res, err := method.Outputs.Pack(g.state.LockupPeriod())
if err != nil {
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index 4b25b39da..55876f9b2 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -59,10 +59,22 @@ func randomBytes(minLength, maxLength int32) []byte {
return b
}
+func newPrefundAccount(s *state.StateDB) (*ecdsa.PrivateKey, common.Address) {
+ privKey, err := crypto.GenerateKey()
+ if err != nil {
+ panic(err)
+ }
+ address := crypto.PubkeyToAddress(privKey.PublicKey)
+
+ s.AddBalance(address, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2e6)))
+ return privKey, address
+}
+
type GovernanceStateTestSuite struct {
suite.Suite
- s *GovernanceState
+ stateDB *state.StateDB
+ s *GovernanceState
}
func (g *GovernanceStateTestSuite) SetupTest() {
@@ -71,7 +83,13 @@ func (g *GovernanceStateTestSuite) SetupTest() {
if err != nil {
panic(err)
}
+ g.stateDB = statedb
g.s = &GovernanceState{statedb}
+
+ config := params.TestnetChainConfig.Dexcon
+ g.s.Initialize(config, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e7)))
+
+ statedb.Commit(true)
}
func (g *GovernanceStateTestSuite) TestReadWriteEraseBytes() {
@@ -117,6 +135,31 @@ func (g *GovernanceStateTestSuite) TestReadWriteErase1DArray() {
}
}
+func (g *GovernanceStateTestSuite) TestDisqualify() {
+ privKey, addr := newPrefundAccount(g.stateDB)
+ pk := crypto.FromECDSAPub(&privKey.PublicKey)
+
+ g.s.Register(addr, pk, "Test", "test@dexon.org", "Taipei", "https://test.com", g.s.MinStake())
+
+ node := g.s.Node(big.NewInt(0))
+ g.Require().Equal(uint64(0), node.Fined.Uint64())
+
+ // Disqualify
+ g.s.Disqualify(node)
+ node = g.s.Node(big.NewInt(0))
+ g.Require().Equal(uint64(1), node.Fined.Uint64())
+
+ // Disqualify again should change nothing.
+ g.s.Disqualify(node)
+ node = g.s.Node(big.NewInt(0))
+ g.Require().Equal(uint64(1), node.Fined.Uint64())
+
+ // Disqualify none exist node should return error.
+ privKey2, _ := newPrefundAccount(g.stateDB)
+ node.PublicKey = crypto.FromECDSAPub(&privKey2.PublicKey)
+ g.Require().Error(g.s.Disqualify(node))
+}
+
func TestGovernanceState(t *testing.T) {
suite.Run(t, new(GovernanceStateTestSuite))
}
@@ -203,17 +246,6 @@ func (g *OracleContractsTestSuite) TearDownTest() {
}
}
-func (g *OracleContractsTestSuite) newPrefundAccount() (*ecdsa.PrivateKey, common.Address) {
- privKey, err := crypto.GenerateKey()
- if err != nil {
- panic(err)
- }
- address := crypto.PubkeyToAddress(privKey.PublicKey)
-
- g.stateDB.AddBalance(address, new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2e6)))
- return privKey, address
-}
-
func (g *OracleContractsTestSuite) call(
contractAddr common.Address, caller common.Address, input []byte, value *big.Int) ([]byte, error) {
@@ -225,7 +257,7 @@ func (g *OracleContractsTestSuite) call(
}
func (g *OracleContractsTestSuite) TestTransferOwnership() {
- _, addr := g.newPrefundAccount()
+ _, addr := newPrefundAccount(g.stateDB)
input, err := GovernanceABI.ABI.Pack("transferOwnership", addr)
g.Require().NoError(err)
@@ -241,7 +273,7 @@ func (g *OracleContractsTestSuite) TestTransferOwnership() {
}
func (g *OracleContractsTestSuite) TestTransferNodeOwnership() {
- privKey, addr := g.newPrefundAccount()
+ privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)
nodeKeyAddr := crypto.PubkeyToAddress(privKey.PublicKey)
@@ -253,14 +285,14 @@ func (g *OracleContractsTestSuite) TestTransferNodeOwnership() {
offset := g.s.NodesOffsetByAddress(addr)
- _, newAddr := g.newPrefundAccount()
+ _, newAddr := newPrefundAccount(g.stateDB)
newNodeKeyAddr := crypto.PubkeyToAddress(privKey.PublicKey)
input, err = GovernanceABI.ABI.Pack("transferNodeOwnership", newAddr)
g.Require().NoError(err)
// Call with non-owner.
- _, noneOwner := g.newPrefundAccount()
+ _, noneOwner := newPrefundAccount(g.stateDB)
_, err = g.call(GovernanceContractAddress, noneOwner, input, big.NewInt(0))
g.Require().Error(err)
@@ -273,7 +305,7 @@ func (g *OracleContractsTestSuite) TestTransferNodeOwnership() {
g.Require().Equal(offset.Uint64(), g.s.NodesOffsetByNodeKeyAddress(newNodeKeyAddr).Uint64())
// Call with owner.
- privKey2, addr2 := g.newPrefundAccount()
+ privKey2, addr2 := newPrefundAccount(g.stateDB)
pk2 := crypto.FromECDSAPub(&privKey2.PublicKey)
input, err = GovernanceABI.ABI.Pack("register", pk2, "Test2", "test1@dexon.org", "Taipei", "https://dexon.org")
g.Require().NoError(err)
@@ -288,7 +320,7 @@ func (g *OracleContractsTestSuite) TestTransferNodeOwnership() {
}
func (g *OracleContractsTestSuite) TestStakingMechanism() {
- privKey, addr := g.newPrefundAccount()
+ privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)
// Register with some stake.
@@ -374,7 +406,7 @@ func (g *OracleContractsTestSuite) TestStakingMechanism() {
amount = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
// 2nd node Stake.
- privKey2, addr2 := g.newPrefundAccount()
+ privKey2, addr2 := newPrefundAccount(g.stateDB)
pk2 := crypto.FromECDSAPub(&privKey2.PublicKey)
input, err = GovernanceABI.ABI.Pack("register", pk2, "Test2", "test2@dexon.org", "Taipei", "https://dexon.org")
g.Require().NoError(err)
@@ -440,7 +472,7 @@ func (g *OracleContractsTestSuite) TestStakingMechanism() {
}
func (g *OracleContractsTestSuite) TestFine() {
- privKey, addr := g.newPrefundAccount()
+ privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)
// Stake.
@@ -452,7 +484,7 @@ func (g *OracleContractsTestSuite) TestFine() {
g.Require().Equal(1, len(g.s.QualifiedNodes()))
g.Require().Equal(ownerStaked, g.s.Node(big.NewInt(0)).Staked)
- _, finePayer := g.newPrefundAccount()
+ _, finePayer := newPrefundAccount(g.stateDB)
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(5e5))
// Paying to node without fine should fail.
@@ -497,7 +529,7 @@ func (g *OracleContractsTestSuite) TestFine() {
}
func (g *OracleContractsTestSuite) TestUpdateConfiguration() {
- _, addr := g.newPrefundAccount()
+ _, addr := newPrefundAccount(g.stateDB)
input, err := GovernanceABI.ABI.Pack("updateConfiguration",
new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6)),
@@ -523,7 +555,7 @@ func (g *OracleContractsTestSuite) TestUpdateConfiguration() {
}
func (g *OracleContractsTestSuite) TestConfigurationReading() {
- _, addr := g.newPrefundAccount()
+ _, addr := newPrefundAccount(g.stateDB)
// CRS.
input, err := GovernanceABI.ABI.Pack("crs")
@@ -657,7 +689,7 @@ func (g *OracleContractsTestSuite) TestConfigurationReading() {
}
func (g *OracleContractsTestSuite) TestReportForkVote() {
- key, addr := g.newPrefundAccount()
+ key, addr := newPrefundAccount(g.stateDB)
pkBytes := crypto.FromECDSAPub(&key.PublicKey)
// Stake.
@@ -723,7 +755,7 @@ func (g *OracleContractsTestSuite) TestReportForkVote() {
}
func (g *OracleContractsTestSuite) TestReportForkBlock() {
- key, addr := g.newPrefundAccount()
+ key, addr := newPrefundAccount(g.stateDB)
pkBytes := crypto.FromECDSAPub(&key.PublicKey)
// Stake.
@@ -800,7 +832,7 @@ func (g *OracleContractsTestSuite) TestReportForkBlock() {
}
func (g *OracleContractsTestSuite) TestMiscVariableReading() {
- privKey, addr := g.newPrefundAccount()
+ privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)
input, err := GovernanceABI.ABI.Pack("totalSupply")
@@ -898,7 +930,7 @@ func (v *testTSigVerifierMock) VerifySignature(coreCommon.Hash, coreCrypto.Signa
func (g *OracleContractsTestSuite) TestResetDKG() {
for i := uint32(0); i < g.config.DKGSetSize; i++ {
- privKey, addr := g.newPrefundAccount()
+ privKey, addr := newPrefundAccount(g.stateDB)
pk := crypto.FromECDSAPub(&privKey.PublicKey)
// Stake.
@@ -1033,7 +1065,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
g.context.BlockNumber = big.NewInt(
roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
- _, addr := g.newPrefundAccount()
+ _, addr := newPrefundAccount(g.stateDB)
newCRS := randomBytes(common.HashLength, common.HashLength)
input, err := GovernanceABI.ABI.Pack("resetDKG", newCRS)
g.Require().NoError(err)
diff --git a/dex/app_test.go b/dex/app_test.go
index 7b158dd9e..e648abdbd 100644
--- a/dex/app_test.go
+++ b/dex/app_test.go
@@ -2299,12 +2299,10 @@ func newDexon(masterKey *ecdsa.PrivateKey, accountNum int) (*Dexon, []*ecdsa.Pri
db := ethdb.NewMemDatabase()
genesis := core.DefaultTestnetGenesisBlock()
- genesis.Alloc = core.GenesisAlloc{
- crypto.PubkeyToAddress(masterKey.PublicKey): {
- Balance: big.NewInt(100000000000000000),
- Staked: big.NewInt(50000000000000000),
- PublicKey: crypto.FromECDSAPub(&masterKey.PublicKey),
- },
+ genesis.Alloc[crypto.PubkeyToAddress(masterKey.PublicKey)] = core.GenesisAccount{
+ Balance: big.NewInt(100000000000000000),
+ Staked: big.NewInt(50000000000000000),
+ PublicKey: crypto.FromECDSAPub(&masterKey.PublicKey),
}
var accounts []*ecdsa.PrivateKey
@@ -2322,7 +2320,7 @@ func newDexon(masterKey *ecdsa.PrivateKey, accountNum int) (*Dexon, []*ecdsa.Pri
}
genesis.Config.Dexcon.BlockGasLimit = 2000000
- genesis.Config.Dexcon.RoundLength = 60
+ genesis.Config.Dexcon.RoundLength = 600
genesis.Config.Dexcon.Owner = crypto.PubkeyToAddress(masterKey.PublicKey)
chainConfig, _, err := core.SetupGenesisBlock(db, genesis)
diff --git a/dex/downloader/testchain_test.go b/dex/downloader/testchain_test.go
index 722159bc0..15528c509 100644
--- a/dex/downloader/testchain_test.go
+++ b/dex/downloader/testchain_test.go
@@ -342,3 +342,7 @@ func (g *govStateFetcher) GetStateForConfigAtRound(round uint64) *vm.GovernanceS
}
return nil
}
+
+func (g *govStateFetcher) NotarySetNodeKeyAddresses(round uint64) (map[common.Address]struct{}, error) {
+ return make(map[common.Address]struct{}), nil
+}
diff --git a/dex/governance.go b/dex/governance.go
index c2f2918b1..0d6ca0eba 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -20,13 +20,8 @@ package dex
import (
"context"
"crypto/ecdsa"
- "encoding/hex"
"math/big"
- 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"
@@ -42,11 +37,10 @@ import (
type DexconGovernance struct {
*core.Governance
- b *DexAPIBackend
- chainConfig *params.ChainConfig
- privateKey *ecdsa.PrivateKey
- address common.Address
- nodeSetCache *dexCore.NodeSetCache
+ b *DexAPIBackend
+ chainConfig *params.ChainConfig
+ privateKey *ecdsa.PrivateKey
+ address common.Address
}
// NewDexconGovernance returns a governance implementation of the DEXON
@@ -61,7 +55,6 @@ func NewDexconGovernance(backend *DexAPIBackend, chainConfig *params.ChainConfig
privateKey: privKey,
address: crypto.PubkeyToAddress(privKey.PublicKey),
}
- g.nodeSetCache = dexCore.NewNodeSetCache(g)
return g
}
@@ -110,36 +103,10 @@ func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
return d.b.SendTx(ctx, tx)
}
-// CRS returns the CRS for a given round.
-func (d *DexconGovernance) CRS(round uint64) coreCommon.Hash {
- if round <= dexCore.DKGDelayRound {
- s := d.GetStateAtRound(0)
- crs := s.CRS()
- for i := uint64(0); i < round; i++ {
- crs = crypto.Keccak256Hash(crs[:])
- }
- return coreCommon.Hash(crs)
- }
- if round > d.CRSRound() {
- return coreCommon.Hash{}
- }
- var s *vm.GovernanceState
- if round == d.CRSRound() {
- s = d.GetHeadState()
- } else {
- s = d.GetStateAtRound(round)
- }
- return coreCommon.Hash(s.CRS())
-}
-
func (d *DexconGovernance) Round() uint64 {
return d.b.CurrentBlock().Round()
}
-func (d *DexconGovernance) CRSRound() uint64 {
- return d.GetHeadState().CRSRound().Uint64()
-}
-
// ProposeCRS send proposals of a new CRS
func (d *DexconGovernance) ProposeCRS(round uint64, signedCRS []byte) {
data, err := vm.PackProposeCRS(round, signedCRS)
@@ -154,21 +121,6 @@ func (d *DexconGovernance) ProposeCRS(round uint64, signedCRS []byte) {
}
}
-// NodeSet returns the current node set.
-func (d *DexconGovernance) NodeSet(round uint64) []coreCrypto.PublicKey {
- s := d.GetStateForConfigAtRound(round)
- var pks []coreCrypto.PublicKey
-
- for _, n := range s.QualifiedNodes() {
- pk, err := coreEcdsa.NewPublicKeyFromByteSlice(n.PublicKey)
- if err != nil {
- panic(err)
- }
- pks = append(pks, pk)
- }
- return pks
-}
-
// AddDKGComplaint adds a DKGComplaint.
func (d *DexconGovernance) AddDKGComplaint(round uint64, complaint *dkgTypes.Complaint) {
data, err := vm.PackAddDKGComplaint(round, complaint)
@@ -253,49 +205,6 @@ func (d *DexconGovernance) ReportForkBlock(block1, block2 *coreTypes.Block) {
}
}
-func (d *DexconGovernance) NotarySet(round uint64) (map[string]struct{}, error) {
- notarySet, err := d.nodeSetCache.GetNotarySet(round)
- if err != nil {
- return nil, err
- }
-
- r := make(map[string]struct{}, len(notarySet))
- for id := range notarySet {
- if key, exists := d.nodeSetCache.GetPublicKey(id); exists {
- r[hex.EncodeToString(key.Bytes())] = struct{}{}
- }
- }
- return r, nil
-}
-
-func (d *DexconGovernance) NotarySetAddresses(round uint64) (map[common.Address]struct{}, error) {
- notarySet, err := d.nodeSetCache.GetNotarySet(round)
- if err != nil {
- return nil, err
- }
-
- r := make(map[common.Address]struct{}, len(notarySet))
- for id := range notarySet {
- r[vm.IdToAddress(id)] = struct{}{}
- }
- return r, nil
-}
-
-func (d *DexconGovernance) DKGSet(round uint64) (map[string]struct{}, error) {
- dkgSet, err := d.nodeSetCache.GetDKGSet(round)
- if err != nil {
- return nil, err
- }
-
- r := make(map[string]struct{}, len(dkgSet))
- for id := range dkgSet {
- if key, exists := d.nodeSetCache.GetPublicKey(id); exists {
- r[hex.EncodeToString(key.Bytes())] = struct{}{}
- }
- }
- return r, nil
-}
-
func (d *DexconGovernance) ResetDKG(newSignedCRS []byte) {
data, err := vm.PackResetDKG(newSignedCRS)
if err != nil {
diff --git a/dex/recovery.go b/dex/recovery.go
index cfc8ae203..0e5c60e1a 100644
--- a/dex/recovery.go
+++ b/dex/recovery.go
@@ -442,7 +442,7 @@ func (r *Recovery) Votes(height uint64) (uint64, error) {
return 0, err
}
- notarySet, err := r.gov.NotarySetAddresses(r.gov.Round())
+ notarySet, err := r.gov.NotarySetNodeKeyAddresses(r.gov.Round())
if err != nil {
return 0, err
}
diff --git a/params/config.go b/params/config.go
index f61a9b6df..1eb016019 100644
--- a/params/config.go
+++ b/params/config.go
@@ -26,10 +26,10 @@ import (
// Genesis hashes to enforce below configs on.
var (
- MainnetGenesisHash = common.HexToHash("0x8ac8e240790046eb72225eb2a2381f3ef5a7a88291fffc702ba08503cc2a1341")
- TestnetGenesisHash = common.HexToHash("0x3caf9a977e579b4de001956508b57563a4b61742c66f49323a1294ad214da29d")
- TaipeiGenesisHash = common.HexToHash("0x13e85a0207f2888ac9c1746c94d5d7fd87ff637cbd080b42d5db1252341f4428")
- YilanGenesisHash = common.HexToHash("0x6b1a94b5e4c24665942a3b768bd98b39d61771a5eaba97c0466644d78d8a2f11")
+ MainnetGenesisHash = common.HexToHash("0xa48b24e2e500e3a7f222673c240dcef6c4c4fd720e6c4653349adc6acae96fb8")
+ TestnetGenesisHash = common.HexToHash("0xf67217d7715cea0b2e8acada9b6a8e538fc3df0129dab32f8c1f6baff7a50034")
+ TaipeiGenesisHash = common.HexToHash("0xdcf32f39178f33cea762dd0e87e2be1eb9327997cb9cf20ef0645030d3ece6be")
+ YilanGenesisHash = common.HexToHash("0xbb48abd6cc576af3d0f84173e3476045def2f57c2e891e75a8835036d7012b82")
)
// TrustedCheckpoints associates each known checkpoint with the genesis hash of