aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-02-25 19:35:06 +0800
committerWei-Ning Huang <w@dexon.org>2019-03-12 12:19:09 +0800
commit4ce8adb190ae3351a507be54f38afa6b47ce18a3 (patch)
tree585b6f4bb5ee06b0fdab0f8e68f34e15b6ae0fed
parent0ac79d780ba63c574d648552f887c9411fdd76fe (diff)
downloaddexon-4ce8adb190ae3351a507be54f38afa6b47ce18a3.tar.gz
dexon-4ce8adb190ae3351a507be54f38afa6b47ce18a3.tar.zst
dexon-4ce8adb190ae3351a507be54f38afa6b47ce18a3.zip
core: vm: flatten governance
-rw-r--r--build/testtool/testtool.go76
-rw-r--r--consensus/dexcon/dexcon.go6
-rw-r--r--consensus/dexcon/dexcon_test.go10
-rw-r--r--consensus/dexcon/fake_dexcon.go8
-rw-r--r--core/dexon_chain_makers.go1
-rw-r--r--core/evm.go1
-rw-r--r--core/genesis.go25
-rw-r--r--core/governance.go68
-rw-r--r--core/headerchain.go2
-rw-r--r--core/tx_pool.go4
-rw-r--r--core/vm/evm.go1
-rw-r--r--core/vm/oracle_contract_abi.go171
-rw-r--r--core/vm/oracle_contracts.go603
-rw-r--r--core/vm/oracle_contracts_test.go171
-rw-r--r--dex/downloader/downloader.go11
-rw-r--r--dex/downloader/testchain_test.go76
-rw-r--r--dex/governance.go33
-rw-r--r--dex/handler.go27
-rw-r--r--dex/helper_test.go6
-rw-r--r--dex/protocol.go4
-rw-r--r--params/config.go6
21 files changed, 679 insertions, 631 deletions
diff --git a/build/testtool/testtool.go b/build/testtool/testtool.go
index 801c343b6..09e94fe16 100644
--- a/build/testtool/testtool.go
+++ b/build/testtool/testtool.go
@@ -11,6 +11,8 @@ import (
"strings"
"time"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
+
"github.com/dexon-foundation/dexon"
"github.com/dexon-foundation/dexon/accounts/abi"
"github.com/dexon-foundation/dexon/cmd/zoo/monkey"
@@ -37,14 +39,42 @@ func main() {
}
}
-func doVerifyGovCRS(args []string) {
- if len(args) < 2 {
- log.Fatal("arg length is not enough")
+func getBlockNumber(client *ethclient.Client, round int) *big.Int {
+ if round == 0 {
+ return big.NewInt(0)
+ }
+ abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
+ if err != nil {
+ log.Fatalf("read abi fail: %v", err)
}
- client, err := ethclient.Dial(args[0])
+ input, err := abiObject.Pack("roundHeight", big.NewInt(int64(round)))
if err != nil {
- log.Fatalf("new ethclient fail: %v", err)
+ log.Fatalf("pack input fail: %v", err)
+ }
+
+ result, err := client.CallContract(context.Background(), ethereum.CallMsg{
+ To: &vm.GovernanceContractAddress,
+ Data: input,
+ }, nil)
+ if err != nil {
+ log.Fatalf("call contract fail: %v", err)
+ }
+
+ if bytes.Equal(make([]byte, 32), result) {
+ log.Fatalf("round %d height not found", round)
+ }
+
+ roundHeight := new(big.Int)
+ if err := abiObject.Unpack(&roundHeight, "roundHeight", result); err != nil {
+ log.Fatalf("unpack output fail: %v", err)
+ }
+ return roundHeight
+}
+
+func doVerifyGovCRS(args []string) {
+ if len(args) < 2 {
+ log.Fatal("arg length is not enough")
}
abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
@@ -57,7 +87,14 @@ func doVerifyGovCRS(args []string) {
log.Fatalf("pasre round from arg 2 fail: %v", err)
}
- input, err := abiObject.Pack("crs", big.NewInt(int64(round)))
+ client, err := ethclient.Dial(args[0])
+ if err != nil {
+ log.Fatalf("new ethclient fail: %v", err)
+ }
+
+ blockNumber := getBlockNumber(client, round)
+
+ input, err := abiObject.Pack("crs")
if err != nil {
log.Fatalf("pack input fail: %v", err)
}
@@ -65,7 +102,7 @@ func doVerifyGovCRS(args []string) {
result, err := client.CallContract(context.Background(), ethereum.CallMsg{
To: &vm.GovernanceContractAddress,
Data: input,
- }, nil)
+ }, blockNumber)
if err != nil {
log.Fatalf("call contract fail: %v", err)
}
@@ -81,12 +118,6 @@ func doVerifyGovMPK(args []string) {
if len(args) < 3 {
log.Fatal("arg length is not enough")
}
-
- client, err := ethclient.Dial(args[0])
- if err != nil {
- log.Fatalf("new ethclient fail: %v", err)
- }
-
abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON))
if err != nil {
log.Fatalf("read abi fail: %v", err)
@@ -97,12 +128,23 @@ func doVerifyGovMPK(args []string) {
log.Fatalf("pasre round from arg 2 fail: %v", err)
}
+ if uint64(round) < dexCore.DKGDelayRound {
+ return
+ }
+
+ client, err := ethclient.Dial(args[0])
+ if err != nil {
+ log.Fatalf("new ethclient fail: %v", err)
+ }
+
+ blockNumber := getBlockNumber(client, round)
+
index, err := strconv.Atoi(args[2])
if err != nil {
- log.Fatalf("pasre round from arg 2 fail: %v", err)
+ log.Fatalf("pasre index from arg 2 fail: %v", err)
}
- input, err := abiObject.Pack("dkgMasterPublicKeys", big.NewInt(int64(round)), big.NewInt(int64(index)))
+ input, err := abiObject.Pack("dkgMasterPublicKeys", big.NewInt(int64(index)))
if err != nil {
log.Fatalf("pack input fail: %v", err)
}
@@ -110,13 +152,13 @@ func doVerifyGovMPK(args []string) {
result, err := client.CallContract(context.Background(), ethereum.CallMsg{
To: &vm.GovernanceContractAddress,
Data: input,
- }, nil)
+ }, blockNumber)
if err != nil {
log.Fatalf("call contract fail: %v", err)
}
if bytes.Equal(make([]byte, 0), result) {
- log.Fatalf("round %s index %s crs not found", args[1], args[2])
+ log.Fatalf("round %s index %s mpk not found", args[1], args[2])
}
log.Printf("get round %s index %s master public key %x", args[1], args[2], result)
diff --git a/consensus/dexcon/dexcon.go b/consensus/dexcon/dexcon.go
index aff5c9c45..c837e3a43 100644
--- a/consensus/dexcon/dexcon.go
+++ b/consensus/dexcon/dexcon.go
@@ -28,7 +28,7 @@ import (
)
type GovernanceStateFetcher interface {
- GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateHelper
+ GetStateForConfigAtRound(round uint64) *vm.GovernanceState
}
// Dexcon is a delegated proof-of-stake consensus engine.
@@ -108,7 +108,7 @@ func (d *Dexcon) Prepare(chain consensus.ChainReader, header *types.Header) erro
}
func (d *Dexcon) calculateBlockReward(round int64, state *state.StateDB) *big.Int {
- gs := d.govStateFetcer.GetGovStateHelperAtRound(uint64(round))
+ gs := d.govStateFetcer.GetStateForConfigAtRound(uint64(round))
config := gs.Configuration()
blocksPerRound := config.RoundLength
@@ -134,7 +134,7 @@ func (d *Dexcon) calculateBlockReward(round int64, state *state.StateDB) *big.In
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block.
func (d *Dexcon) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
- gs := vm.GovernanceStateHelper{state}
+ gs := vm.GovernanceState{state}
height := gs.RoundHeight(new(big.Int).SetUint64(header.Round))
if header.Round > 0 && height.Uint64() == 0 {
diff --git a/consensus/dexcon/dexcon_test.go b/consensus/dexcon/dexcon_test.go
index 65ed77cc8..f34823570 100644
--- a/consensus/dexcon/dexcon_test.go
+++ b/consensus/dexcon/dexcon_test.go
@@ -35,8 +35,8 @@ type GovStateFetcher struct {
statedb *state.StateDB
}
-func (g *GovStateFetcher) GetGovStateHelperAtRound(_ uint64) *vm.GovernanceStateHelper {
- return &vm.GovernanceStateHelper{g.statedb}
+func (g *GovStateFetcher) GetStateForConfigAtRound(_ uint64) *vm.GovernanceState {
+ return &vm.GovernanceState{g.statedb}
}
type DexconTestSuite struct {
@@ -45,7 +45,7 @@ type DexconTestSuite struct {
config *params.DexconConfig
memDB *ethdb.MemDatabase
stateDB *state.StateDB
- s *vm.GovernanceStateHelper
+ s *vm.GovernanceState
}
func (d *DexconTestSuite) SetupTest() {
@@ -56,7 +56,7 @@ func (d *DexconTestSuite) SetupTest() {
}
d.memDB = memDB
d.stateDB = stateDB
- d.s = &vm.GovernanceStateHelper{stateDB}
+ d.s = &vm.GovernanceState{stateDB}
config := params.TestnetChainConfig.Dexcon
config.LockupPeriod = 1000
@@ -73,7 +73,7 @@ func (d *DexconTestSuite) SetupTest() {
// Genesis CRS.
crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
- d.s.PushCRS(crs)
+ d.s.SetCRS(crs)
// Round 0 height.
d.s.PushRoundHeight(big.NewInt(0))
diff --git a/consensus/dexcon/fake_dexcon.go b/consensus/dexcon/fake_dexcon.go
index ca48b5275..ae7bed90e 100644
--- a/consensus/dexcon/fake_dexcon.go
+++ b/consensus/dexcon/fake_dexcon.go
@@ -6,6 +6,7 @@ import (
"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"
coreDKG "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg"
coreEcdsa "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
@@ -250,7 +251,12 @@ func (n *NodeSet) Randomness(round uint64, hash common.Hash) []byte {
}
func (n *NodeSet) SignCRS(round uint64) {
- signedCRS := n.TSig(round, n.crs[round])
+ var signedCRS []byte
+ if round < dexCore.DKGDelayRound {
+ signedCRS = crypto.Keccak256(n.signedCRS[round])
+ } else {
+ signedCRS = n.TSig(round, n.crs[round])
+ }
n.signedCRS[round+1] = signedCRS
n.crs[round+1] = crypto.Keccak256Hash(signedCRS)
}
diff --git a/core/dexon_chain_makers.go b/core/dexon_chain_makers.go
index 3031f3ae8..04ae22279 100644
--- a/core/dexon_chain_makers.go
+++ b/core/dexon_chain_makers.go
@@ -183,6 +183,7 @@ func GenerateDexonChain(config *params.ChainConfig, parent *types.Block, engine
}
b.header.DexconMeta = makeDexconMeta(b, parent)
+ b.header.Round = b.position.Round
// sign tsig to create dexcon, prepare witness
b.engine.Prepare(chain, b.header)
diff --git a/core/evm.go b/core/evm.go
index 9e4f00f7c..ae18ee9a6 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -67,6 +67,7 @@ func NewEVMContext(msg Message, header *types.Header, chain ChainContext, author
Time: new(big.Int).Set(header.Time),
Randomness: header.Randomness,
Difficulty: new(big.Int).Set(header.Difficulty),
+ Round: new(big.Int).SetUint64(header.Round),
GasLimit: header.GasLimit,
GasPrice: new(big.Int).Set(msg.GasPrice()),
}
diff --git a/core/genesis.go b/core/genesis.go
index ea521dc9b..5e91a3020 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -33,7 +33,6 @@ 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/crypto"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/log"
"github.com/dexon-foundation/dexon/params"
@@ -265,7 +264,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
db = ethdb.NewMemDatabase()
}
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
- govStateHelper := vm.GovernanceStateHelper{StateDB: statedb}
+ govStateHelper := vm.GovernanceState{StateDB: statedb}
totalSupply := big.NewInt(0)
totalStaked := big.NewInt(0)
@@ -309,26 +308,8 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
}
}
- if g.Config.Dexcon.NextHalvingSupply.Cmp(totalSupply) <= 0 {
- panic(fmt.Sprintf("invalid genesis found, totalSupply: %s, nextHavlingSupply: %s",
- totalSupply, g.Config.Dexcon.NextHalvingSupply))
- }
-
- // Genesis CRS.
- crs := crypto.Keccak256Hash([]byte(g.Config.Dexcon.GenesisCRSText))
- govStateHelper.PushCRS(crs)
-
- // Round 0 height.
- govStateHelper.PushRoundHeight(big.NewInt(0))
-
- // Owner.
- govStateHelper.SetOwner(g.Config.Dexcon.Owner)
-
- // Governance configuration.
- govStateHelper.UpdateConfiguration(g.Config.Dexcon)
-
- // Set totalSupply.
- govStateHelper.IncTotalSupply(totalSupply)
+ // Initialize governance.
+ govStateHelper.Initialize(g.Config.Dexcon, totalSupply)
}
// Set oracle contract.
diff --git a/core/governance.go b/core/governance.go
index 03f53ae6b..73fb0c923 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -48,16 +48,16 @@ func NewGovernance(db GovernanceStateDB) *Governance {
return &Governance{db: db}
}
-func (g *Governance) GetHeadHelper() *vm.GovernanceStateHelper {
+func (g *Governance) GetHeadState() *vm.GovernanceState {
headState, err := g.db.State()
if err != nil {
log.Error("Governance head state not ready", "err", err)
panic(err)
}
- return &vm.GovernanceStateHelper{StateDB: headState}
+ return &vm.GovernanceState{StateDB: headState}
}
-func (g *Governance) getHelperAtRound(round uint64) *vm.GovernanceStateHelper {
+func (g *Governance) getHelperAtRound(round uint64) *vm.GovernanceState {
height := g.GetRoundHeight(round)
// Sanity check
@@ -71,10 +71,10 @@ func (g *Governance) getHelperAtRound(round uint64) *vm.GovernanceStateHelper {
log.Error("Governance state not ready", "round", round, "height", height, "err", err)
panic(err)
}
- return &vm.GovernanceStateHelper{StateDB: s}
+ return &vm.GovernanceState{StateDB: s}
}
-func (g *Governance) GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateHelper {
+func (g *Governance) GetStateForConfigAtRound(round uint64) *vm.GovernanceState {
if round < dexCore.ConfigRoundShift {
round = 0
} else {
@@ -83,12 +83,22 @@ func (g *Governance) GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateH
return g.getHelperAtRound(round)
}
+func (g *Governance) GetStateAtRound(round uint64) *vm.GovernanceState {
+ height := g.GetRoundHeight(round)
+ s, err := g.db.StateAt(height)
+ if err != nil {
+ log.Error("Governance state not ready", "round", round, "height", height, "err", err)
+ panic(err)
+ }
+ return &vm.GovernanceState{StateDB: s}
+}
+
func (g *Governance) GetRoundHeight(round uint64) uint64 {
- return g.GetHeadHelper().RoundHeight(big.NewInt(int64(round))).Uint64()
+ return g.GetHeadState().RoundHeight(big.NewInt(int64(round))).Uint64()
}
func (g *Governance) Configuration(round uint64) *coreTypes.Config {
- configHelper := g.GetGovStateHelperAtRound(round)
+ configHelper := g.GetStateForConfigAtRound(round)
c := configHelper.Configuration()
return &coreTypes.Config{
LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
@@ -100,10 +110,25 @@ func (g *Governance) Configuration(round uint64) *coreTypes.Config {
}
}
+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 (g *Governance) DKGComplaints(round uint64) []*dkgTypes.Complaint {
- headHelper := g.GetHeadHelper()
+ s := g.GetStateForDKGAtRound(round)
+ if s == nil {
+ return nil
+ }
+
var dkgComplaints []*dkgTypes.Complaint
- for _, pk := range headHelper.DKGComplaints(big.NewInt(int64(round))) {
+ for _, pk := range s.DKGComplaints() {
x := new(dkgTypes.Complaint)
if err := rlp.DecodeBytes(pk, x); err != nil {
panic(err)
@@ -114,30 +139,39 @@ func (g *Governance) DKGComplaints(round uint64) []*dkgTypes.Complaint {
}
func (g *Governance) DKGMasterPublicKeys(round uint64) []*dkgTypes.MasterPublicKey {
- headHelper := g.GetHeadHelper()
- return headHelper.UniqueDKGMasterPublicKeys(big.NewInt(int64(round)))
+ s := g.GetStateForDKGAtRound(round)
+ if s == nil {
+ return nil
+ }
+ return s.UniqueDKGMasterPublicKeys()
}
func (g *Governance) IsDKGMPKReady(round uint64) bool {
- headHelper := g.GetHeadHelper()
+ s := g.GetStateForDKGAtRound(round)
+ if s == nil {
+ return false
+ }
config := g.Configuration(round)
threshold := 2*uint64(config.DKGSetSize)/3 + 1
- count := headHelper.DKGMPKReadysCount(big.NewInt(int64(round))).Uint64()
+ count := s.DKGMPKReadysCount().Uint64()
return count >= threshold
}
func (g *Governance) IsDKGFinal(round uint64) bool {
- headHelper := g.GetHeadHelper()
+ s := g.GetStateForDKGAtRound(round)
+ if s == nil {
+ return false
+ }
config := g.Configuration(round)
threshold := 2*uint64(config.DKGSetSize)/3 + 1
- count := headHelper.DKGFinalizedsCount(big.NewInt(int64(round))).Uint64()
+ count := s.DKGFinalizedsCount().Uint64()
return count >= threshold
}
func (g *Governance) MinGasPrice(round uint64) *big.Int {
- return g.GetGovStateHelperAtRound(round).MinGasPrice()
+ return g.GetStateForConfigAtRound(round).MinGasPrice()
}
func (g *Governance) DKGResetCount(round uint64) uint64 {
- return g.GetHeadHelper().DKGResetCount(big.NewInt(int64(round))).Uint64()
+ return g.GetHeadState().DKGResetCount(big.NewInt(int64(round))).Uint64()
}
diff --git a/core/headerchain.go b/core/headerchain.go
index 0ebf1935c..c1ad04e5d 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -538,7 +538,7 @@ func (hc *HeaderChain) verifyDexonHeader(header *types.Header,
return fmt.Errorf("round mismatch")
}
- gs := gov.GetGovStateHelperAtRound(header.Round)
+ gs := gov.GetStateForConfigAtRound(header.Round)
config := gs.Configuration()
if header.GasLimit != config.BlockGasLimit {
return fmt.Errorf("block gas limit mismatch")
diff --git a/core/tx_pool.go b/core/tx_pool.go
index 0a1b3f132..1719b4b4e 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -397,7 +397,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
} else {
round -= dexCore.ConfigRoundShift
}
- state := &vm.GovernanceStateHelper{StateDB: statedb}
+ state := &vm.GovernanceState{StateDB: statedb}
height := state.RoundHeight(new(big.Int).SetUint64((round))).Uint64()
block := pool.chain.GetBlockByNumber(height)
if block == nil {
@@ -409,7 +409,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
log.Error("Failed to get txpool state for min gas price", "err", err)
panic("cannot get state for new round's min gas price")
}
- govState := &vm.GovernanceStateHelper{StateDB: configState}
+ govState := &vm.GovernanceState{StateDB: configState}
pool.setGovPrice(govState.MinGasPrice())
}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 422d52ccb..6b2844020 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -101,6 +101,7 @@ type Context struct {
Time *big.Int // Provides information for TIME
Randomness []byte // Provides information for RAND
Difficulty *big.Int // Provides information for DIFFICULTY
+ Round *big.Int // Current round number.
RandCallIndex uint64 // Number of times opRand is called
}
diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go
index ff4a94b29..43055bc4a 100644
--- a/core/vm/oracle_contract_abi.go
+++ b/core/vm/oracle_contract_abi.go
@@ -47,29 +47,6 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- },
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "dkgComplaints",
- "outputs": [
- {
- "name": "",
- "type": "bytes"
- }
- ],
- "payable": false,
- "stateMutability": "view",
- "type": "function"
- },
- {
- "constant": true,
"inputs": [],
"name": "notarySetSize",
"outputs": [
@@ -223,14 +200,26 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
+ "type": "address"
+ },
+ {
+ "name": "",
"type": "uint256"
}
],
- "name": "crs",
+ "name": "delegators",
"outputs": [
{
- "name": "",
- "type": "bytes32"
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "undelegated_at",
+ "type": "uint256"
}
],
"payable": false,
@@ -242,14 +231,14 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "uint256"
+ "type": "address"
}
],
- "name": "dkgMPKReadysCount",
+ "name": "dkgFinalizeds",
"outputs": [
{
"name": "",
- "type": "uint256"
+ "type": "bool"
}
],
"payable": false,
@@ -258,21 +247,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- },
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "dkgMPKReadys",
+ "inputs": [],
+ "name": "blockGasLimit",
"outputs": [
{
"name": "",
- "type": "bool"
+ "type": "uint256"
}
],
"payable": false,
@@ -284,26 +264,14 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "address"
- },
- {
- "name": "",
- "type": "uint256"
+ "type": "bytes32"
}
],
- "name": "delegators",
+ "name": "nodesOffsetByID",
"outputs": [
{
- "name": "owner",
- "type": "address"
- },
- {
- "name": "value",
- "type": "uint256"
- },
- {
- "name": "undelegated_at",
- "type": "uint256"
+ "name": "",
+ "type": "int256"
}
],
"payable": false,
@@ -313,7 +281,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "blockGasLimit",
+ "name": "totalStaked",
"outputs": [
{
"name": "",
@@ -329,10 +297,10 @@ const GovernanceABIJSON = `
"inputs": [
{
"name": "",
- "type": "bytes32"
+ "type": "address"
}
],
- "name": "nodesOffsetByID",
+ "name": "nodesOffsetByAddress",
"outputs": [
{
"name": "",
@@ -346,11 +314,11 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "totalStaked",
+ "name": "crs",
"outputs": [
{
"name": "",
- "type": "uint256"
+ "type": "bytes32"
}
],
"payable": false,
@@ -359,17 +327,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "address"
- }
- ],
- "name": "nodesOffsetByAddress",
+ "inputs": [],
+ "name": "roundLength",
"outputs": [
{
"name": "",
- "type": "int256"
+ "type": "uint256"
}
],
"payable": false,
@@ -379,7 +342,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "roundLength",
+ "name": "nextHalvingSupply",
"outputs": [
{
"name": "",
@@ -392,14 +355,19 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [],
- "name": "nextHalvingSupply",
- "outputs": [
+ "inputs": [
{
"name": "",
"type": "uint256"
}
],
+ "name": "dkgComplaints",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bytes"
+ }
+ ],
"payable": false,
"stateMutability": "view",
"type": "function"
@@ -420,6 +388,25 @@ const GovernanceABIJSON = `
},
{
"constant": true,
+ "inputs": [
+ {
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "dkgMPKReadys",
+ "outputs": [
+ {
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "payable": false,
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "constant": true,
"inputs": [],
"name": "lastHalvedAmount",
"outputs": [
@@ -506,7 +493,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "minBlockInterval",
+ "name": "dkgMPKReadysCount",
"outputs": [
{
"name": "",
@@ -519,21 +506,12 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- },
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "dkgMasterPublicKeys",
+ "inputs": [],
+ "name": "minBlockInterval",
"outputs": [
{
"name": "",
- "type": "bytes"
+ "type": "uint256"
}
],
"payable": false,
@@ -546,17 +524,13 @@ const GovernanceABIJSON = `
{
"name": "",
"type": "uint256"
- },
- {
- "name": "",
- "type": "address"
}
],
- "name": "dkgFinalizeds",
+ "name": "dkgMasterPublicKeys",
"outputs": [
{
"name": "",
- "type": "bool"
+ "type": "bytes"
}
],
"payable": false,
@@ -580,7 +554,7 @@ const GovernanceABIJSON = `
{
"constant": true,
"inputs": [],
- "name": "lockupPeriod",
+ "name": "dkgFinalizedsCount",
"outputs": [
{
"name": "",
@@ -593,13 +567,8 @@ const GovernanceABIJSON = `
},
{
"constant": true,
- "inputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "dkgFinalizedsCount",
+ "inputs": [],
+ "name": "lockupPeriod",
"outputs": [
{
"name": "",
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index aa93c97fb..fcdc1d0a2 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -20,6 +20,7 @@ package vm
import (
"bytes"
"errors"
+ "fmt"
"math/big"
"sort"
@@ -31,7 +32,7 @@ import (
"github.com/dexon-foundation/dexon/rlp"
coreCommon "github.com/dexon-foundation/dexon-consensus/common"
- "github.com/dexon-foundation/dexon-consensus/core"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
coreCrypto "github.com/dexon-foundation/dexon-consensus/core/crypto"
coreUtils "github.com/dexon-foundation/dexon-consensus/core/utils"
@@ -60,7 +61,9 @@ const (
nodesOffsetByIDLoc
delegatorsLoc
delegatorsOffsetLoc
+ crsRoundLoc
crsLoc
+ dkgRoundLoc
dkgMasterPublicKeysLoc
dkgComplaintsLoc
dkgReadyLoc
@@ -96,36 +99,36 @@ func publicKeyToNodeID(pkBytes []byte) (Bytes32, error) {
}
// State manipulation helper fro the governance contract.
-type GovernanceStateHelper struct {
+type GovernanceState struct {
StateDB StateDB
}
-func (s *GovernanceStateHelper) getState(loc common.Hash) common.Hash {
+func (s *GovernanceState) getState(loc common.Hash) common.Hash {
return s.StateDB.GetState(GovernanceContractAddress, loc)
}
-func (s *GovernanceStateHelper) setState(loc common.Hash, val common.Hash) {
+func (s *GovernanceState) setState(loc common.Hash, val common.Hash) {
s.StateDB.SetState(GovernanceContractAddress, loc, val)
}
-func (s *GovernanceStateHelper) getStateBigInt(loc *big.Int) *big.Int {
+func (s *GovernanceState) getStateBigInt(loc *big.Int) *big.Int {
res := s.StateDB.GetState(GovernanceContractAddress, common.BigToHash(loc))
return new(big.Int).SetBytes(res.Bytes())
}
-func (s *GovernanceStateHelper) setStateBigInt(loc *big.Int, val *big.Int) {
+func (s *GovernanceState) setStateBigInt(loc *big.Int, val *big.Int) {
s.setState(common.BigToHash(loc), common.BigToHash(val))
}
-func (s *GovernanceStateHelper) getSlotLoc(loc *big.Int) *big.Int {
+func (s *GovernanceState) getSlotLoc(loc *big.Int) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(common.BigToHash(loc).Bytes()))
}
-func (s *GovernanceStateHelper) getMapLoc(pos *big.Int, key []byte) *big.Int {
+func (s *GovernanceState) getMapLoc(pos *big.Int, key []byte) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(key, common.BigToHash(pos).Bytes()))
}
-func (s *GovernanceStateHelper) readBytes(loc *big.Int) []byte {
+func (s *GovernanceState) readBytes(loc *big.Int) []byte {
// Length of the dynamic array (bytes).
rawLength := s.getStateBigInt(loc)
lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
@@ -158,7 +161,7 @@ func (s *GovernanceStateHelper) readBytes(loc *big.Int) []byte {
return data
}
-func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
+func (s *GovernanceState) writeBytes(loc *big.Int, data []byte) {
length := int64(len(data))
if length == 0 {
@@ -204,7 +207,7 @@ func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
}
}
-func (s *GovernanceStateHelper) eraseBytes(loc *big.Int) {
+func (s *GovernanceState) eraseBytes(loc *big.Int) {
// Length of the dynamic array (bytes).
rawLength := s.getStateBigInt(loc)
lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
@@ -227,10 +230,7 @@ func (s *GovernanceStateHelper) eraseBytes(loc *big.Int) {
s.setStateBigInt(loc, big.NewInt(0))
}
-func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) read1DByteArray(loc *big.Int) [][]byte {
arrayLength := s.getStateBigInt(loc)
dataLoc := s.getSlotLoc(loc)
@@ -243,11 +243,7 @@ func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
return data
}
-func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []byte) {
- // Find the loc of the last element.
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) appendTo1DByteArray(loc *big.Int, data []byte) {
// Increase length by 1.
arrayLength := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(arrayLength, big.NewInt(1)))
@@ -258,10 +254,7 @@ func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []
s.writeBytes(elementLoc, data)
}
-func (s *GovernanceStateHelper) erase2DByteArray(pos, index *big.Int) {
- baseLoc := s.getSlotLoc(pos)
- loc := new(big.Int).Add(baseLoc, index)
-
+func (s *GovernanceState) erase1DByteArray(loc *big.Int) {
arrayLength := s.getStateBigInt(loc)
dataLoc := s.getSlotLoc(loc)
@@ -273,12 +266,12 @@ func (s *GovernanceStateHelper) erase2DByteArray(pos, index *big.Int) {
}
// uint256[] public roundHeight;
-func (s *GovernanceStateHelper) RoundHeight(round *big.Int) *big.Int {
+func (s *GovernanceState) RoundHeight(round *big.Int) *big.Int {
baseLoc := s.getSlotLoc(big.NewInt(roundHeightLoc))
loc := new(big.Int).Add(baseLoc, round)
return s.getStateBigInt(loc)
}
-func (s *GovernanceStateHelper) PushRoundHeight(height *big.Int) {
+func (s *GovernanceState) PushRoundHeight(height *big.Int) {
// Increase length by 1.
length := s.getStateBigInt(big.NewInt(roundHeightLoc))
s.setStateBigInt(big.NewInt(roundHeightLoc), new(big.Int).Add(length, big.NewInt(1)))
@@ -290,24 +283,24 @@ func (s *GovernanceStateHelper) PushRoundHeight(height *big.Int) {
}
// uint256 public totalSupply;
-func (s *GovernanceStateHelper) TotalSupply() *big.Int {
+func (s *GovernanceState) TotalSupply() *big.Int {
return s.getStateBigInt(big.NewInt(totalSupplyLoc))
}
-func (s *GovernanceStateHelper) IncTotalSupply(amount *big.Int) {
+func (s *GovernanceState) IncTotalSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalSupplyLoc), new(big.Int).Add(s.TotalSupply(), amount))
}
-func (s *GovernanceStateHelper) DecTotalSupply(amount *big.Int) {
+func (s *GovernanceState) DecTotalSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalSupplyLoc), new(big.Int).Sub(s.TotalSupply(), amount))
}
// uint256 public totalStaked;
-func (s *GovernanceStateHelper) TotalStaked() *big.Int {
+func (s *GovernanceState) TotalStaked() *big.Int {
return s.getStateBigInt(big.NewInt(totalStakedLoc))
}
-func (s *GovernanceStateHelper) IncTotalStaked(amount *big.Int) {
+func (s *GovernanceState) IncTotalStaked(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalStakedLoc), new(big.Int).Add(s.TotalStaked(), amount))
}
-func (s *GovernanceStateHelper) DecTotalStaked(amount *big.Int) {
+func (s *GovernanceState) DecTotalStaked(amount *big.Int) {
s.setStateBigInt(big.NewInt(totalStakedLoc), new(big.Int).Sub(s.TotalStaked(), amount))
}
@@ -337,10 +330,10 @@ type nodeInfo struct {
const nodeStructSize = 8
-func (s *GovernanceStateHelper) LenNodes() *big.Int {
+func (s *GovernanceState) LenNodes() *big.Int {
return s.getStateBigInt(big.NewInt(nodesLoc))
}
-func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo {
+func (s *GovernanceState) Node(index *big.Int) *nodeInfo {
node := new(nodeInfo)
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
@@ -381,14 +374,14 @@ func (s *GovernanceStateHelper) Node(index *big.Int) *nodeInfo {
return node
}
-func (s *GovernanceStateHelper) PushNode(n *nodeInfo) {
+func (s *GovernanceState) PushNode(n *nodeInfo) {
// Increase length by 1.
arrayLength := s.LenNodes()
s.setStateBigInt(big.NewInt(nodesLoc), new(big.Int).Add(arrayLength, big.NewInt(1)))
s.UpdateNode(arrayLength, n)
}
-func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) {
+func (s *GovernanceState) UpdateNode(index *big.Int, n *nodeInfo) {
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
elementBaseLoc := new(big.Int).Add(arrayBaseLoc,
new(big.Int).Mul(index, big.NewInt(nodeStructSize)))
@@ -425,7 +418,7 @@ func (s *GovernanceStateHelper) UpdateNode(index *big.Int, n *nodeInfo) {
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(7))
s.writeBytes(loc, []byte(n.Url))
}
-func (s *GovernanceStateHelper) PopLastNode() {
+func (s *GovernanceState) PopLastNode() {
// Decrease length by 1.
arrayLength := s.LenNodes()
newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1))
@@ -436,14 +429,14 @@ func (s *GovernanceStateHelper) PopLastNode() {
Fined: big.NewInt(0),
})
}
-func (s *GovernanceStateHelper) Nodes() []*nodeInfo {
+func (s *GovernanceState) Nodes() []*nodeInfo {
var nodes []*nodeInfo
for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
nodes = append(nodes, s.Node(big.NewInt(i)))
}
return nodes
}
-func (s *GovernanceStateHelper) QualifiedNodes() []*nodeInfo {
+func (s *GovernanceState) QualifiedNodes() []*nodeInfo {
var nodes []*nodeInfo
for i := int64(0); i < int64(s.LenNodes().Uint64()); i++ {
node := s.Node(big.NewInt(i))
@@ -455,34 +448,34 @@ func (s *GovernanceStateHelper) QualifiedNodes() []*nodeInfo {
}
// mapping(address => uint256) public nodeOffsetByAddress;
-func (s *GovernanceStateHelper) NodesOffsetByAddress(addr common.Address) *big.Int {
+func (s *GovernanceState) NodesOffsetByAddress(addr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutNodesOffsetByAddress(addr common.Address, offset *big.Int) {
+func (s *GovernanceState) PutNodesOffsetByAddress(addr common.Address, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteNodesOffsetByAddress(addr common.Address) {
+func (s *GovernanceState) DeleteNodesOffsetByAddress(addr common.Address) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByAddressLoc), addr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
// mapping(address => uint256) public nodeOffsetByID;
-func (s *GovernanceStateHelper) NodesOffsetByID(id Bytes32) *big.Int {
+func (s *GovernanceState) NodesOffsetByID(id Bytes32) *big.Int {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutNodesOffsetByID(id Bytes32, offset *big.Int) {
+func (s *GovernanceState) PutNodesOffsetByID(id Bytes32, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteNodesOffsetByID(id Bytes32) {
+func (s *GovernanceState) DeleteNodesOffsetByID(id Bytes32) {
loc := s.getMapLoc(big.NewInt(nodesOffsetByIDLoc), id[:])
s.setStateBigInt(loc, big.NewInt(0))
}
-func (s *GovernanceStateHelper) PutNodeOffsets(n *nodeInfo, offset *big.Int) error {
+func (s *GovernanceState) PutNodeOffsets(n *nodeInfo, offset *big.Int) error {
id, err := publicKeyToNodeID(n.PublicKey)
if err != nil {
return err
@@ -508,11 +501,11 @@ type delegatorInfo struct {
const delegatorStructSize = 3
// mapping(address => Delegator[]) public delegators;
-func (s *GovernanceStateHelper) LenDelegators(nodeAddr common.Address) *big.Int {
+func (s *GovernanceState) LenDelegators(nodeAddr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
return s.getStateBigInt(loc)
}
-func (s *GovernanceStateHelper) Delegator(nodeAddr common.Address, offset *big.Int) *delegatorInfo {
+func (s *GovernanceState) Delegator(nodeAddr common.Address, offset *big.Int) *delegatorInfo {
delegator := new(delegatorInfo)
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
@@ -533,7 +526,7 @@ func (s *GovernanceStateHelper) Delegator(nodeAddr common.Address, offset *big.I
return delegator
}
-func (s *GovernanceStateHelper) PushDelegator(nodeAddr common.Address, delegator *delegatorInfo) {
+func (s *GovernanceState) PushDelegator(nodeAddr common.Address, delegator *delegatorInfo) {
// Increase length by 1.
arrayLength := s.LenDelegators(nodeAddr)
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
@@ -541,7 +534,7 @@ func (s *GovernanceStateHelper) PushDelegator(nodeAddr common.Address, delegator
s.UpdateDelegator(nodeAddr, arrayLength, delegator)
}
-func (s *GovernanceStateHelper) UpdateDelegator(nodeAddr common.Address, offset *big.Int, delegator *delegatorInfo) {
+func (s *GovernanceState) UpdateDelegator(nodeAddr common.Address, offset *big.Int, delegator *delegatorInfo) {
loc := s.getMapLoc(big.NewInt(delegatorsLoc), nodeAddr.Bytes())
arrayBaseLoc := s.getSlotLoc(loc)
elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(big.NewInt(delegatorStructSize), offset))
@@ -558,7 +551,7 @@ func (s *GovernanceStateHelper) UpdateDelegator(nodeAddr common.Address, offset
loc = new(big.Int).Add(elementBaseLoc, big.NewInt(2))
s.setStateBigInt(loc, delegator.UndelegatedAt)
}
-func (s *GovernanceStateHelper) PopLastDelegator(nodeAddr common.Address) {
+func (s *GovernanceState) PopLastDelegator(nodeAddr common.Address) {
// Decrease length by 1.
arrayLength := s.LenDelegators(nodeAddr)
newArrayLength := new(big.Int).Sub(arrayLength, big.NewInt(1))
@@ -572,67 +565,55 @@ func (s *GovernanceStateHelper) PopLastDelegator(nodeAddr common.Address) {
}
// mapping(address => mapping(address => uint256)) delegatorsOffset;
-func (s *GovernanceStateHelper) DelegatorsOffset(nodeAddr, delegatorAddr common.Address) *big.Int {
+func (s *GovernanceState) DelegatorsOffset(nodeAddr, delegatorAddr common.Address) *big.Int {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *GovernanceStateHelper) PutDelegatorOffset(nodeAddr, delegatorAddr common.Address, offset *big.Int) {
+func (s *GovernanceState) PutDelegatorOffset(nodeAddr, delegatorAddr common.Address, offset *big.Int) {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *GovernanceStateHelper) DeleteDelegatorsOffset(nodeAddr, delegatorAddr common.Address) {
+func (s *GovernanceState) DeleteDelegatorsOffset(nodeAddr, delegatorAddr common.Address) {
loc := s.getMapLoc(s.getMapLoc(big.NewInt(delegatorsOffsetLoc), nodeAddr.Bytes()), delegatorAddr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
-// bytes32[] public crs;
-func (s *GovernanceStateHelper) LenCRS() *big.Int {
- return s.getStateBigInt(big.NewInt(crsLoc))
+// uint256 public crsRound;
+func (s *GovernanceState) CRSRound() *big.Int {
+ return s.getStateBigInt(big.NewInt(crsRoundLoc))
}
-func (s *GovernanceStateHelper) CRS(index *big.Int) common.Hash {
- baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
- loc := new(big.Int).Add(baseLoc, index)
- return s.getState(common.BigToHash(loc))
+func (s *GovernanceState) SetCRSRound(round *big.Int) {
+ s.setStateBigInt(big.NewInt(crsRoundLoc), round)
}
-func (s *GovernanceStateHelper) CurrentCRS() common.Hash {
- return s.CRS(new(big.Int).Sub(s.LenCRS(), big.NewInt(1)))
-}
-func (s *GovernanceStateHelper) PushCRS(crs common.Hash) {
- // increase length by 1.
- length := s.getStateBigInt(big.NewInt(crsLoc))
- s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Add(length, big.NewInt(1)))
-
- baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
- loc := new(big.Int).Add(baseLoc, length)
- s.setState(common.BigToHash(loc), crs)
+// bytes32 public crs;
+func (s *GovernanceState) CRS() common.Hash {
+ return s.getState(common.BigToHash(big.NewInt(crsLoc)))
+}
+func (s *GovernanceState) SetCRS(crs common.Hash) {
+ s.setState(common.BigToHash(big.NewInt(crsLoc)), crs)
}
-func (s *GovernanceStateHelper) PopCRS() {
- // decrease length by 1.
- length := s.getStateBigInt(big.NewInt(crsLoc))
- s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Sub(length, big.NewInt(1)))
-
- baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
- loc := new(big.Int).Add(baseLoc, length)
- s.setState(common.BigToHash(loc), common.Hash{})
+// uint256 public dkgRound;
+func (s *GovernanceState) DKGRound() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgRoundLoc))
}
-func (s *GovernanceStateHelper) Round() *big.Int {
- return new(big.Int).Sub(s.getStateBigInt(big.NewInt(crsLoc)), big.NewInt(1))
+func (s *GovernanceState) SetDKGRound(round *big.Int) {
+ s.setStateBigInt(big.NewInt(dkgRoundLoc), round)
}
-// bytes[][] public dkgMasterPublicKeys;
-func (s *GovernanceStateHelper) DKGMasterPublicKeys(round *big.Int) [][]byte {
- return s.read2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
+// bytes[] public dkgMasterPublicKeys;
+func (s *GovernanceState) DKGMasterPublicKeys() [][]byte {
+ return s.read1DByteArray(big.NewInt(dkgMasterPublicKeysLoc))
}
-func (s *GovernanceStateHelper) PushDKGMasterPublicKey(round *big.Int, mpk []byte) {
- s.appendTo2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round, mpk)
+func (s *GovernanceState) PushDKGMasterPublicKey(mpk []byte) {
+ s.appendTo1DByteArray(big.NewInt(dkgMasterPublicKeysLoc), mpk)
}
-func (s *GovernanceStateHelper) UniqueDKGMasterPublicKeys(round *big.Int) []*dkgTypes.MasterPublicKey {
+func (s *GovernanceState) UniqueDKGMasterPublicKeys() []*dkgTypes.MasterPublicKey {
// Prepare DKGMasterPublicKeys.
var dkgMasterPKs []*dkgTypes.MasterPublicKey
existence := make(map[coreTypes.NodeID]struct{})
- for _, mpk := range s.DKGMasterPublicKeys(round) {
+ for _, mpk := range s.DKGMasterPublicKeys() {
x := new(dkgTypes.MasterPublicKey)
if err := rlp.DecodeBytes(mpk, x); err != nil {
panic(err)
@@ -647,10 +628,10 @@ func (s *GovernanceStateHelper) UniqueDKGMasterPublicKeys(round *big.Int) []*dkg
}
return dkgMasterPKs
}
-func (s *GovernanceStateHelper) GetDKGMasterPublicKeyByProposerID(
- round *big.Int, proposerID coreTypes.NodeID) (*dkgTypes.MasterPublicKey, error) {
+func (s *GovernanceState) GetDKGMasterPublicKeyByProposerID(
+ proposerID coreTypes.NodeID) (*dkgTypes.MasterPublicKey, error) {
- for _, mpk := range s.DKGMasterPublicKeys(round) {
+ for _, mpk := range s.DKGMasterPublicKeys() {
x := new(dkgTypes.MasterPublicKey)
if err := rlp.DecodeBytes(mpk, x); err != nil {
panic(err)
@@ -661,199 +642,189 @@ func (s *GovernanceStateHelper) GetDKGMasterPublicKeyByProposerID(
}
return nil, errors.New("not found")
}
-func (s *GovernanceStateHelper) ClearDKGMasterPublicKeys(round *big.Int) {
- s.erase2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
+func (s *GovernanceState) ClearDKGMasterPublicKeys() {
+ s.erase1DByteArray(big.NewInt(dkgMasterPublicKeysLoc))
}
-// bytes[][] public dkgComplaints;
-func (s *GovernanceStateHelper) DKGComplaints(round *big.Int) [][]byte {
- return s.read2DByteArray(big.NewInt(dkgComplaintsLoc), round)
+// bytes[] public dkgComplaints;
+func (s *GovernanceState) DKGComplaints() [][]byte {
+ return s.read1DByteArray(big.NewInt(dkgComplaintsLoc))
}
-func (s *GovernanceStateHelper) PushDKGComplaint(round *big.Int, complaint []byte) {
- s.appendTo2DByteArray(big.NewInt(dkgComplaintsLoc), round, complaint)
+func (s *GovernanceState) PushDKGComplaint(complaint []byte) {
+ s.appendTo1DByteArray(big.NewInt(dkgComplaintsLoc), complaint)
}
-func (s *GovernanceStateHelper) ClearDKGComplaints(round *big.Int) {
- s.erase2DByteArray(big.NewInt(dkgComplaintsLoc), round)
+func (s *GovernanceState) ClearDKGComplaints() {
+ s.erase1DByteArray(big.NewInt(dkgComplaintsLoc))
}
-// mapping(address => bool)[] public dkgReady;
-func (s *GovernanceStateHelper) DKGMPKReady(round *big.Int, addr common.Address) bool {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadyLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+// mapping(address => bool) public dkgReady;
+func (s *GovernanceState) DKGMPKReady(addr common.Address) bool {
+ mapLoc := s.getMapLoc(big.NewInt(dkgReadyLoc), addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *GovernanceStateHelper) PutDKGMPKReady(round *big.Int, addr common.Address, ready bool) {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadyLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+func (s *GovernanceState) PutDKGMPKReady(addr common.Address, ready bool) {
+ mapLoc := s.getMapLoc(big.NewInt(dkgReadyLoc), addr.Bytes())
res := big.NewInt(0)
if ready {
res = big.NewInt(1)
}
s.setStateBigInt(mapLoc, res)
}
-func (s *GovernanceStateHelper) ClearDKGMPKReady(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+func (s *GovernanceState) ClearDKGMPKReady(dkgSet map[coreTypes.NodeID]struct{}) {
for id := range dkgSet {
offset := s.NodesOffsetByID(Bytes32(id.Hash))
if offset.Cmp(big.NewInt(0)) < 0 {
panic(errors.New("DKG node does not exist"))
}
node := s.Node(offset)
- s.PutDKGMPKReady(round, node.Owner, false)
+ s.PutDKGMPKReady(node.Owner, false)
}
}
-// uint256[] public dkgReadysCount;
-func (s *GovernanceStateHelper) DKGMPKReadysCount(round *big.Int) *big.Int {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- return s.getStateBigInt(loc)
+// uint256 public dkgReadysCount;
+func (s *GovernanceState) DKGMPKReadysCount() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgReadysCountLoc))
}
-func (s *GovernanceStateHelper) IncDKGMPKReadysCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- count := s.getStateBigInt(loc)
- s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
+func (s *GovernanceState) IncDKGMPKReadysCount() {
+ s.setStateBigInt(big.NewInt(dkgReadysCountLoc),
+ new(big.Int).Add(s.getStateBigInt(big.NewInt(dkgReadysCountLoc)), big.NewInt(1)))
}
-func (s *GovernanceStateHelper) ResetDKGMPKReadysCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgReadysCountLoc)), round)
- s.setStateBigInt(loc, big.NewInt(0))
+func (s *GovernanceState) ResetDKGMPKReadysCount() {
+ s.setStateBigInt(big.NewInt(dkgReadysCountLoc), big.NewInt(0))
}
-// mapping(address => bool)[] public dkgFinalized;
-func (s *GovernanceStateHelper) DKGFinalized(round *big.Int, addr common.Address) bool {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+// mapping(address => bool) public dkgFinalized;
+func (s *GovernanceState) DKGFinalized(addr common.Address) bool {
+ mapLoc := s.getMapLoc(big.NewInt(dkgFinalizedLoc), addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *GovernanceStateHelper) PutDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
- baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedLoc)), round)
- mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
+func (s *GovernanceState) PutDKGFinalized(addr common.Address, finalized bool) {
+ mapLoc := s.getMapLoc(big.NewInt(dkgFinalizedLoc), addr.Bytes())
res := big.NewInt(0)
if finalized {
res = big.NewInt(1)
}
s.setStateBigInt(mapLoc, res)
}
-func (s *GovernanceStateHelper) ClearDKGFinalized(round *big.Int, dkgSet map[coreTypes.NodeID]struct{}) {
+func (s *GovernanceState) ClearDKGFinalized(dkgSet map[coreTypes.NodeID]struct{}) {
for id := range dkgSet {
offset := s.NodesOffsetByID(Bytes32(id.Hash))
if offset.Cmp(big.NewInt(0)) < 0 {
panic(errors.New("DKG node does not exist"))
}
node := s.Node(offset)
- s.PutDKGFinalized(round, node.Owner, false)
+ s.PutDKGFinalized(node.Owner, false)
}
}
-// uint256[] public dkgFinalizedsCount;
-func (s *GovernanceStateHelper) DKGFinalizedsCount(round *big.Int) *big.Int {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
- return s.getStateBigInt(loc)
+// uint256 public dkgFinalizedsCount;
+func (s *GovernanceState) DKGFinalizedsCount() *big.Int {
+ return s.getStateBigInt(big.NewInt(dkgFinalizedsCountLoc))
}
-func (s *GovernanceStateHelper) IncDKGFinalizedsCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
- count := s.getStateBigInt(loc)
- s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
+func (s *GovernanceState) IncDKGFinalizedsCount() {
+ s.setStateBigInt(big.NewInt(dkgFinalizedsCountLoc),
+ new(big.Int).Add(s.getStateBigInt(big.NewInt(dkgFinalizedsCountLoc)), big.NewInt(1)))
}
-func (s *GovernanceStateHelper) ResetDKGFinalizedsCount(round *big.Int) {
- loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
- s.setStateBigInt(loc, big.NewInt(0))
+func (s *GovernanceState) ResetDKGFinalizedsCount() {
+ s.setStateBigInt(big.NewInt(dkgFinalizedsCountLoc), big.NewInt(0))
}
// address public owner;
-func (s *GovernanceStateHelper) Owner() common.Address {
+func (s *GovernanceState) Owner() common.Address {
val := s.getState(common.BigToHash(big.NewInt(ownerLoc)))
return common.BytesToAddress(val.Bytes())
}
-func (s *GovernanceStateHelper) SetOwner(newOwner common.Address) {
+func (s *GovernanceState) SetOwner(newOwner common.Address) {
s.setState(common.BigToHash(big.NewInt(ownerLoc)), newOwner.Hash())
}
// uint256 public minStake;
-func (s *GovernanceStateHelper) MinStake() *big.Int {
+func (s *GovernanceState) MinStake() *big.Int {
return s.getStateBigInt(big.NewInt(minStakeLoc))
}
// uint256 public lockupPeriod;
-func (s *GovernanceStateHelper) LockupPeriod() *big.Int {
+func (s *GovernanceState) LockupPeriod() *big.Int {
return s.getStateBigInt(big.NewInt(lockupPeriodLoc))
}
// uint256 public miningVelocity;
-func (s *GovernanceStateHelper) MiningVelocity() *big.Int {
+func (s *GovernanceState) MiningVelocity() *big.Int {
return s.getStateBigInt(big.NewInt(miningVelocityLoc))
}
-func (s *GovernanceStateHelper) HalfMiningVelocity() {
+func (s *GovernanceState) HalfMiningVelocity() {
s.setStateBigInt(big.NewInt(miningVelocityLoc),
new(big.Int).Div(s.MiningVelocity(), big.NewInt(2)))
}
// uint256 public nextHalvingSupply;
-func (s *GovernanceStateHelper) NextHalvingSupply() *big.Int {
+func (s *GovernanceState) NextHalvingSupply() *big.Int {
return s.getStateBigInt(big.NewInt(nextHalvingSupplyLoc))
}
-func (s *GovernanceStateHelper) IncNextHalvingSupply(amount *big.Int) {
+func (s *GovernanceState) IncNextHalvingSupply(amount *big.Int) {
s.setStateBigInt(big.NewInt(nextHalvingSupplyLoc),
new(big.Int).Add(s.NextHalvingSupply(), amount))
}
// uint256 public lastHalvedAmount;
-func (s *GovernanceStateHelper) LastHalvedAmount() *big.Int {
+func (s *GovernanceState) LastHalvedAmount() *big.Int {
return s.getStateBigInt(big.NewInt(lastHalvedAmountLoc))
}
-func (s *GovernanceStateHelper) HalfLastHalvedAmount() {
+func (s *GovernanceState) HalfLastHalvedAmount() {
s.setStateBigInt(big.NewInt(lastHalvedAmountLoc),
new(big.Int).Div(s.LastHalvedAmount(), big.NewInt(2)))
}
-func (s *GovernanceStateHelper) MiningHalved() {
+func (s *GovernanceState) MiningHalved() {
s.HalfMiningVelocity()
s.HalfLastHalvedAmount()
s.IncNextHalvingSupply(s.LastHalvedAmount())
}
// uint256 public blockGasLimit;
-func (s *GovernanceStateHelper) BlockGasLimit() *big.Int {
+func (s *GovernanceState) BlockGasLimit() *big.Int {
return s.getStateBigInt(big.NewInt(blockGasLimitLoc))
}
-func (s *GovernanceStateHelper) SetBlockGasLimit(reward *big.Int) {
+func (s *GovernanceState) SetBlockGasLimit(reward *big.Int) {
s.setStateBigInt(big.NewInt(blockGasLimitLoc), reward)
}
// uint256 public lambdaBA;
-func (s *GovernanceStateHelper) LambdaBA() *big.Int {
+func (s *GovernanceState) LambdaBA() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaBALoc))
}
// uint256 public lambdaDKG;
-func (s *GovernanceStateHelper) LambdaDKG() *big.Int {
+func (s *GovernanceState) LambdaDKG() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaDKGLoc))
}
// uint256 public notarySetSize;
-func (s *GovernanceStateHelper) NotarySetSize() *big.Int {
+func (s *GovernanceState) NotarySetSize() *big.Int {
return s.getStateBigInt(big.NewInt(notarySetSizeLoc))
}
// uint256 public dkgSetSize;
-func (s *GovernanceStateHelper) DKGSetSize() *big.Int {
+func (s *GovernanceState) DKGSetSize() *big.Int {
return s.getStateBigInt(big.NewInt(dkgSetSizeLoc))
}
// uint256 public roundLength;
-func (s *GovernanceStateHelper) RoundLength() *big.Int {
+func (s *GovernanceState) RoundLength() *big.Int {
return s.getStateBigInt(big.NewInt(roundLengthLoc))
}
// uint256 public minBlockInterval;
-func (s *GovernanceStateHelper) MinBlockInterval() *big.Int {
+func (s *GovernanceState) MinBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(minBlockIntervalLoc))
}
// uint256[] public fineValues;
-func (s *GovernanceStateHelper) FineValue(index *big.Int) *big.Int {
+func (s *GovernanceState) FineValue(index *big.Int) *big.Int {
arrayBaseLoc := s.getSlotLoc(big.NewInt(fineValuesLoc))
return s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, index))
}
-func (s *GovernanceStateHelper) FineValues() []*big.Int {
+func (s *GovernanceState) FineValues() []*big.Int {
len := s.getStateBigInt(big.NewInt(fineValuesLoc))
result := make([]*big.Int, len.Uint64())
for i := 0; i < int(len.Uint64()); i++ {
@@ -861,7 +832,7 @@ func (s *GovernanceStateHelper) FineValues() []*big.Int {
}
return result
}
-func (s *GovernanceStateHelper) SetFineValues(values []*big.Int) {
+func (s *GovernanceState) SetFineValues(values []*big.Int) {
s.setStateBigInt(big.NewInt(fineValuesLoc), big.NewInt(int64(len(values))))
arrayBaseLoc := s.getSlotLoc(big.NewInt(fineValuesLoc))
@@ -871,11 +842,11 @@ func (s *GovernanceStateHelper) SetFineValues(values []*big.Int) {
}
// mapping(bytes32 => bool) public fineRdecords;
-func (s *GovernanceStateHelper) FineRecords(recordHash Bytes32) bool {
+func (s *GovernanceState) FineRecords(recordHash Bytes32) bool {
loc := s.getMapLoc(big.NewInt(finedRecordsLoc), recordHash[:])
return s.getStateBigInt(loc).Cmp(big.NewInt(0)) > 0
}
-func (s *GovernanceStateHelper) SetFineRecords(recordHash Bytes32, status bool) {
+func (s *GovernanceState) SetFineRecords(recordHash Bytes32, status bool) {
loc := s.getMapLoc(big.NewInt(finedRecordsLoc), recordHash[:])
value := int64(0)
if status {
@@ -885,23 +856,50 @@ func (s *GovernanceStateHelper) SetFineRecords(recordHash Bytes32, status bool)
}
// uint256[] public DKGResetCount;
-func (s *GovernanceStateHelper) DKGResetCount(round *big.Int) *big.Int {
+func (s *GovernanceState) DKGResetCount(round *big.Int) *big.Int {
arrayBaseLoc := s.getSlotLoc(big.NewInt(dkgResetCountLoc))
return s.getStateBigInt(new(big.Int).Add(arrayBaseLoc, round))
}
-func (s *GovernanceStateHelper) IncDKGResetCount(round *big.Int) {
+func (s *GovernanceState) IncDKGResetCount(round *big.Int) {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgResetCountLoc)), round)
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
// uint256 public minGasPrice;
-func (s *GovernanceStateHelper) MinGasPrice() *big.Int {
+func (s *GovernanceState) MinGasPrice() *big.Int {
return s.getStateBigInt(big.NewInt(minGasPriceLoc))
}
+// Initialize initializes governance contract state.
+func (s *GovernanceState) Initialize(config *params.DexconConfig, totalSupply *big.Int) {
+ if config.NextHalvingSupply.Cmp(totalSupply) <= 0 {
+ panic(fmt.Sprintf("invalid genesis found, totalSupply: %s, nextHavlingSupply: %s",
+ totalSupply, config.NextHalvingSupply))
+ }
+
+ // Genesis CRS.
+ crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
+ s.SetCRS(crs)
+
+ // Round 0 height.
+ s.PushRoundHeight(big.NewInt(0))
+
+ // Owner.
+ s.SetOwner(config.Owner)
+
+ // Governance configuration.
+ s.UpdateConfiguration(config)
+
+ // Set totalSupply.
+ s.IncTotalSupply(totalSupply)
+
+ // Set DKGRound.
+ s.SetDKGRound(big.NewInt(int64(dexCore.DKGDelayRound)))
+}
+
// Stake is a helper function for creating genesis state.
-func (s *GovernanceStateHelper) Stake(
+func (s *GovernanceState) Stake(
addr common.Address, publicKey []byte, staked *big.Int,
name, email, location, url string) {
offset := s.LenNodes()
@@ -939,7 +937,7 @@ func (s *GovernanceStateHelper) Stake(
const decimalMultiplier = 100000000.0
// Configuration returns the current configuration.
-func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
+func (s *GovernanceState) Configuration() *params.DexconConfig {
return &params.DexconConfig{
MinStake: s.getStateBigInt(big.NewInt(minStakeLoc)),
LockupPeriod: s.getStateBigInt(big.NewInt(lockupPeriodLoc)).Uint64(),
@@ -959,7 +957,7 @@ func (s *GovernanceStateHelper) Configuration() *params.DexconConfig {
}
// UpdateConfiguration updates system configuration.
-func (s *GovernanceStateHelper) UpdateConfiguration(cfg *params.DexconConfig) {
+func (s *GovernanceState) UpdateConfiguration(cfg *params.DexconConfig) {
s.setStateBigInt(big.NewInt(minStakeLoc), cfg.MinStake)
s.setStateBigInt(big.NewInt(lockupPeriodLoc), big.NewInt(int64(cfg.LockupPeriod)))
s.setStateBigInt(big.NewInt(miningVelocityLoc), big.NewInt(int64(cfg.MiningVelocity*decimalMultiplier)))
@@ -991,7 +989,7 @@ type rawConfigStruct struct {
}
// UpdateConfigurationRaw updates system configuration.
-func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
+func (s *GovernanceState) UpdateConfigurationRaw(cfg *rawConfigStruct) {
s.setStateBigInt(big.NewInt(minStakeLoc), cfg.MinStake)
s.setStateBigInt(big.NewInt(lockupPeriodLoc), cfg.LockupPeriod)
s.setStateBigInt(big.NewInt(blockGasLimitLoc), cfg.BlockGasLimit)
@@ -1006,7 +1004,7 @@ func (s *GovernanceStateHelper) UpdateConfigurationRaw(cfg *rawConfigStruct) {
}
// event ConfigurationChanged();
-func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
+func (s *GovernanceState) emitConfigurationChangedEvent() {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["ConfigurationChanged"].Id()},
@@ -1015,7 +1013,7 @@ func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
}
// event CRSProposed(uint256 round, bytes32 crs);
-func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
+func (s *GovernanceState) emitCRSProposed(round *big.Int, crs common.Hash) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["CRSProposed"].Id(), common.BigToHash(round)},
@@ -1024,7 +1022,7 @@ func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash)
}
// event Staked(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
+func (s *GovernanceState) emitStaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Staked"].Id(), nodeAddr.Hash()},
@@ -1033,7 +1031,7 @@ func (s *GovernanceStateHelper) emitStaked(nodeAddr common.Address) {
}
// event Unstaked(address indexed NodeAddress);
-func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
+func (s *GovernanceState) emitUnstaked(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Unstaked"].Id(), nodeAddr.Hash()},
@@ -1042,7 +1040,7 @@ func (s *GovernanceStateHelper) emitUnstaked(nodeAddr common.Address) {
}
// event NodeRemoved(address indexed NodeAddress);
-func (s *GovernanceStateHelper) emitNodeRemoved(nodeAddr common.Address) {
+func (s *GovernanceState) emitNodeRemoved(nodeAddr common.Address) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["NodeRemoved"].Id(), nodeAddr.Hash()},
@@ -1051,7 +1049,7 @@ func (s *GovernanceStateHelper) emitNodeRemoved(nodeAddr common.Address) {
}
// event Delegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitDelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Delegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1060,7 +1058,7 @@ func (s *GovernanceStateHelper) emitDelegated(nodeAddr, delegatorAddr common.Add
}
// event Undelegated(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitUndelegated(nodeAddr, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Undelegated"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1069,7 +1067,7 @@ func (s *GovernanceStateHelper) emitUndelegated(nodeAddr, delegatorAddr common.A
}
// event Withdrawn(address indexed NodeAddress, address indexed DelegatorAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitWithdrawn(nodeAddr common.Address, delegatorAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Withdrawn"].Id(), nodeAddr.Hash(), delegatorAddr.Hash()},
@@ -1078,7 +1076,7 @@ func (s *GovernanceStateHelper) emitWithdrawn(nodeAddr common.Address, delegator
}
// event ForkReported(address indexed NodeAddress, address indexed Type, bytes Arg1, bytes Arg2);
-func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, reportType *big.Int, arg1, arg2 []byte) {
+func (s *GovernanceState) emitForkReported(nodeAddr common.Address, reportType *big.Int, arg1, arg2 []byte) {
t, err := abi.NewType("bytes", nil)
if err != nil {
@@ -1110,7 +1108,7 @@ func (s *GovernanceStateHelper) emitForkReported(nodeAddr common.Address, report
}
// event Fined(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitFined(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["Fined"].Id(), nodeAddr.Hash()},
@@ -1119,7 +1117,7 @@ func (s *GovernanceStateHelper) emitFined(nodeAddr common.Address, amount *big.I
}
// event FinePaid(address indexed NodeAddress, uint256 Amount);
-func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *big.Int) {
+func (s *GovernanceState) emitFinePaid(nodeAddr common.Address, amount *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["FinePaid"].Id(), nodeAddr.Hash()},
@@ -1128,7 +1126,7 @@ func (s *GovernanceStateHelper) emitFinePaid(nodeAddr common.Address, amount *bi
}
// event DKGReset(uint256 indexed Round, uint256 BlockHeight);
-func (s *GovernanceStateHelper) emitDKGReset(round *big.Int, blockHeight *big.Int) {
+func (s *GovernanceState) emitDKGReset(round *big.Int, blockHeight *big.Int) {
s.StateDB.AddLog(&types.Log{
Address: GovernanceContractAddress,
Topics: []common.Hash{GovernanceABI.Events["DKGReset"].Id(), common.BigToHash(round)},
@@ -1136,25 +1134,28 @@ func (s *GovernanceStateHelper) emitDKGReset(round *big.Int, blockHeight *big.In
})
}
-func getConfigState(evm *EVM, round *big.Int) (*GovernanceStateHelper, error) {
- configRound := big.NewInt(0)
- if round.Uint64() > core.ConfigRoundShift {
- configRound = new(big.Int).Sub(round, big.NewInt(int64(core.ConfigRoundShift)))
- }
-
- gs := &GovernanceStateHelper{evm.StateDB}
- height := gs.RoundHeight(configRound).Uint64()
- if round.Uint64() > core.ConfigRoundShift {
+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 &GovernanceStateHelper{statedb}, err
+ 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 {
- SetState(GovernanceStateHelper)
+ SetState(GovernanceState)
NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error)
}
type tsigVerifierIntf interface {
@@ -1164,28 +1165,27 @@ type tsigVerifierIntf interface {
// GovernanceContract represents the governance contract of DEXCON.
type GovernanceContract struct {
evm *EVM
- state GovernanceStateHelper
+ state GovernanceState
contract *Contract
coreDKGUtils coreDKGUtils
}
// defaultCoreDKGUtils implements coreDKGUtils.
type defaultCoreDKGUtils struct {
- state GovernanceStateHelper
+ state GovernanceState
}
-func (c *defaultCoreDKGUtils) SetState(state GovernanceStateHelper) {
+func (c *defaultCoreDKGUtils) SetState(state GovernanceState) {
c.state = state
}
-func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int,
- threshold int) (tsigVerifierIntf, error) {
+func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int, threshold int) (tsigVerifierIntf, error) {
// Prepare DKGMasterPublicKeys.
- mpks := c.state.UniqueDKGMasterPublicKeys(round)
+ mpks := c.state.UniqueDKGMasterPublicKeys()
// Prepare DKGComplaints.
var complaints []*dkgTypes.Complaint
- for _, comp := range c.state.DKGComplaints(round) {
+ for _, comp := range c.state.DKGComplaints() {
x := new(dkgTypes.Complaint)
if err := rlp.DecodeBytes(comp, x); err != nil {
panic(err)
@@ -1193,7 +1193,7 @@ func (c *defaultCoreDKGUtils) NewGroupPublicKey(round *big.Int,
complaints = append(complaints, x)
}
- return core.NewDKGGroupPublicKey(round.Uint64(), mpks, complaints, threshold)
+ return dexCore.NewDKGGroupPublicKey(round.Uint64(), mpks, complaints, threshold)
}
func (g *GovernanceContract) Address() common.Address {
@@ -1229,7 +1229,7 @@ func (g *GovernanceContract) configDKGSetSize(round *big.Int) *big.Int {
return s.DKGSetSize()
}
func (g *GovernanceContract) getDKGSet(round *big.Int) map[coreTypes.NodeID]struct{} {
- target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CRS(round)))
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.state.CRS()))
ns := coreTypes.NewNodeSet()
state, err := getConfigState(g.evm, round)
@@ -1252,15 +1252,21 @@ func (g *GovernanceContract) inDKGSet(round *big.Int, nodeID coreTypes.NodeID) b
return ok
}
-func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
+func (g *GovernanceContract) clearDKG() {
+ dkgSet := g.getDKGSet(g.evm.Round)
+ g.state.ClearDKGMasterPublicKeys()
+ g.state.ClearDKGComplaints()
+ g.state.ClearDKGMPKReady(dkgSet)
+ g.state.ResetDKGMPKReadysCount()
+ g.state.ClearDKGFinalized(dkgSet)
+ g.state.ResetDKGFinalizedsCount()
+}
+func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byte, error) {
caller := g.contract.Caller()
// Finalized caller is not allowed to propose complaint.
- if g.state.DKGFinalized(round, caller) {
+ if g.state.DKGFinalized(caller) {
return g.penalize()
}
@@ -1270,7 +1276,7 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
// If 2f + 1 of DKG set is finalized, one can not propose complaint anymore.
- if g.state.DKGFinalizedsCount(round).Cmp(threshold) > 0 {
+ if g.state.DKGFinalizedsCount().Cmp(threshold) > 0 {
return nil, errExecutionReverted
}
@@ -1289,8 +1295,7 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
return g.penalize()
}
- mpk, err := g.state.GetDKGMasterPublicKeyByProposerID(
- round, dkgComplaint.PrivateShare.ProposerID)
+ mpk, err := g.state.GetDKGMasterPublicKeyByProposerID(dkgComplaint.PrivateShare.ProposerID)
if err != nil {
return g.penalize()
}
@@ -1315,28 +1320,35 @@ func (g *GovernanceContract) addDKGComplaint(round *big.Int, comp []byte) ([]byt
}
}
- g.state.PushDKGComplaint(round, comp)
+ g.state.PushDKGComplaint(comp)
// Set this to relatively high to prevent spamming
return g.useGas(5000000)
}
func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) ([]byte, error) {
- // Can only add DKG master public key of current and next round.
- if round.Cmp(new(big.Int).Add(g.state.Round(), big.NewInt(1))) > 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
offset := g.state.NodesOffsetByAddress(caller)
+ if g.evm.Round.Uint64() > 0 {
+ if round.Uint64() != g.evm.Round.Uint64()+1 {
+ return nil, errExecutionReverted
+ }
+
+ if g.state.DKGRound().Cmp(g.evm.Round) == 0 {
+ // Clear DKG states for next round.
+ g.clearDKG()
+ g.state.SetDKGRound(round)
+ }
+ }
+
// Can not add dkg mpk if not staked.
if offset.Cmp(big.NewInt(0)) < 0 {
return nil, errExecutionReverted
}
// MPKReady caller is not allowed to propose mpk.
- if g.state.DKGMPKReady(round, caller) {
+ if g.state.DKGMPKReady(caller) {
return g.penalize()
}
@@ -1346,7 +1358,7 @@ func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) (
new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
// If 2f + 1 of DKG set is mpk ready, one can not propose mpk anymore.
- if g.state.DKGMPKReadysCount(round).Cmp(threshold) > 0 {
+ if g.state.DKGMPKReadysCount().Cmp(threshold) > 0 {
return nil, errExecutionReverted
}
@@ -1365,16 +1377,12 @@ func (g *GovernanceContract) addDKGMasterPublicKey(round *big.Int, mpk []byte) (
return g.penalize()
}
- g.state.PushDKGMasterPublicKey(round, mpk)
+ g.state.PushDKGMasterPublicKey(mpk)
return g.useGas(100000)
}
func (g *GovernanceContract) addDKGMPKReady(round *big.Int, ready []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
var dkgReady dkgTypes.MPKReady
@@ -1392,18 +1400,14 @@ func (g *GovernanceContract) addDKGMPKReady(round *big.Int, ready []byte) ([]byt
return g.penalize()
}
- if !g.state.DKGMPKReady(round, caller) {
- g.state.PutDKGMPKReady(round, caller, true)
- g.state.IncDKGMPKReadysCount(round)
+ if !g.state.DKGMPKReady(caller) {
+ g.state.PutDKGMPKReady(caller, true)
+ g.state.IncDKGMPKReadysCount()
}
return g.useGas(100000)
}
func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]byte, error) {
- if round.Cmp(g.state.Round()) != 0 {
- return g.penalize()
- }
-
caller := g.contract.Caller()
var dkgFinalize dkgTypes.Finalize
@@ -1421,9 +1425,9 @@ func (g *GovernanceContract) addDKGFinalize(round *big.Int, finalize []byte) ([]
return g.penalize()
}
- if !g.state.DKGFinalized(round, caller) {
- g.state.PutDKGFinalized(round, caller, true)
- g.state.IncDKGFinalizedsCount(round)
+ if !g.state.DKGFinalized(caller) {
+ g.state.PutDKGFinalized(caller, true)
+ g.state.IncDKGFinalizedsCount()
}
return g.useGas(100000)
@@ -1688,18 +1692,22 @@ func (g *GovernanceContract) payFine(nodeAddr common.Address) ([]byte, error) {
}
func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([]byte, error) {
- round := g.state.Round()
-
- if nextRound.Cmp(round) <= 0 {
+ if nextRound.Uint64() != g.evm.Round.Uint64()+1 ||
+ g.state.CRSRound().Uint64() == nextRound.Uint64() {
return nil, errExecutionReverted
}
- prevCRS := g.state.CRS(round)
+ prevCRS := g.state.CRS()
- threshold := int(g.state.DKGSetSize().Uint64()/3 + 1)
+ // CRS(n) = hash(CRS(n-1)) if n <= core.DKGRoundDelay
+ if g.evm.Round.Uint64() == dexCore.DKGDelayRound {
+ for i := uint64(0); i < dexCore.DKGDelayRound; i++ {
+ prevCRS = crypto.Keccak256Hash(prevCRS[:])
+ }
+ }
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
- round, threshold)
+ threshold := int(g.state.DKGSetSize().Uint64()/3 + 1)
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(nextRound, threshold)
if err != nil {
return nil, errExecutionReverted
}
@@ -1712,10 +1720,10 @@ func (g *GovernanceContract) proposeCRS(nextRound *big.Int, signedCRS []byte) ([
}
// Save new CRS into state and increase round.
- newCRS := crypto.Keccak256(signedCRS)
- crs := common.BytesToHash(newCRS)
+ crs := crypto.Keccak256Hash(signedCRS)
- g.state.PushCRS(crs)
+ g.state.SetCRS(crs)
+ g.state.SetCRSRound(nextRound)
g.state.emitCRSProposed(nextRound, crs)
// To encourage DKG set to propose the correct value, correctly submitting
@@ -1811,23 +1819,24 @@ func (g *GovernanceContract) report(reportType *big.Int, arg1, arg2 []byte) ([]b
}
func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
- // Check if current block over 80% of current round.
- round := g.state.Round()
+ round := g.evm.Round
+ nextRound := new(big.Int).Add(round, big.NewInt(1))
+
resetCount := g.state.DKGResetCount(round)
+
// Just restart DEXON if failed at round 0.
if round.Cmp(big.NewInt(0)) == 0 {
return nil, errExecutionReverted
}
- // target = 80 + 100 * DKGResetCount
+ // Extend the the current round.
+ // target = (80 + 100 * DKGResetCount)%
target := new(big.Int).Add(
big.NewInt(80),
new(big.Int).Mul(big.NewInt(100), resetCount))
- // Round() is increased if CRS is signed. But we want to extend round r-1 now.
- curRound := new(big.Int).Sub(round, big.NewInt(1))
- roundHeight := g.state.RoundHeight(curRound)
- gs, err := getConfigState(g.evm, curRound)
+ roundHeight := g.state.RoundHeight(round)
+ gs, err := getConfigState(g.evm, round)
if err != nil {
return nil, err
}
@@ -1838,6 +1847,7 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
targetBlockNum.Quo(targetBlockNum, big.NewInt(100))
targetBlockNum.Add(targetBlockNum, roundHeight)
+ // Check if current block over 80% of current round.
blockHeight := g.evm.Context.BlockNumber
if blockHeight.Cmp(targetBlockNum) < 0 {
return nil, errExecutionReverted
@@ -1850,35 +1860,30 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
new(big.Int).Div(g.state.DKGSetSize(), big.NewInt(3)))
// If 2f + 1 of DKG set is finalized, check if DKG succeeded.
- if g.state.DKGFinalizedsCount(round).Cmp(threshold) > 0 {
- _, err := g.coreDKGUtils.NewGroupPublicKey(
- round, int(threshold.Int64()))
+ if g.state.DKGFinalizedsCount().Cmp(threshold) > 0 {
+ _, err := g.coreDKGUtils.NewGroupPublicKey(nextRound, int(threshold.Int64()))
// DKG success.
if err == nil {
return nil, errExecutionReverted
}
switch err {
- case core.ErrNotReachThreshold, core.ErrInvalidThreshold:
+ case dexCore.ErrNotReachThreshold, dexCore.ErrInvalidThreshold:
default:
return nil, errExecutionReverted
}
}
- // Clear dkg states for next round.
- dkgSet := g.getDKGSet(round)
- g.state.ClearDKGMasterPublicKeys(round)
- g.state.ClearDKGComplaints(round)
- g.state.ClearDKGMPKReady(round, dkgSet)
- g.state.ResetDKGMPKReadysCount(round)
- g.state.ClearDKGFinalized(round, dkgSet)
- g.state.ResetDKGFinalizedsCount(round)
+
// Update CRS.
- prevCRS := g.state.CRS(curRound)
+ headState, err := getRoundState(g.evm, round)
+ if err != nil {
+ return nil, errExecutionReverted
+ }
+ prevCRS := headState.CRS()
for i := uint64(0); i < resetCount.Uint64()+1; i++ {
prevCRS = crypto.Keccak256Hash(prevCRS[:])
}
- dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(
- curRound, int(config.DKGSetSize/3+1))
+ dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(round, int(config.DKGSetSize/3+1))
if err != nil {
return nil, errExecutionReverted
}
@@ -1890,16 +1895,22 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) {
return g.penalize()
}
+ newRound := new(big.Int).Add(g.evm.Round, big.NewInt(1))
+
+ // Clear DKG states for next round.
+ g.clearDKG()
+ g.state.SetDKGRound(newRound)
+
// Save new CRS into state and increase round.
newCRS := crypto.Keccak256(newSignedCRS)
crs := common.BytesToHash(newCRS)
- g.state.PopCRS()
- g.state.PushCRS(crs)
- g.state.emitCRSProposed(round, crs)
+ g.state.SetCRS(crs)
+ g.state.SetCRSRound(newRound)
+ g.state.emitCRSProposed(newRound, crs)
// Increase reset count.
- g.state.IncDKGResetCount(round)
+ g.state.IncDKGResetCount(new(big.Int).Add(round, big.NewInt(1)))
g.state.emitDKGReset(round, blockHeight)
return nil, nil
@@ -1913,7 +1924,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
// Initialize contract state.
g.evm = evm
- g.state = GovernanceStateHelper{evm.StateDB}
+ g.state = GovernanceState{evm.StateDB}
g.contract = contract
g.coreDKGUtils.SetState(g.state)
@@ -2068,11 +2079,7 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
return res, nil
case "crs":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- res, err := method.Outputs.Pack(g.state.CRS(round))
+ res, err := method.Outputs.Pack(g.state.CRS())
if err != nil {
return nil, errExecutionReverted
}
@@ -2101,12 +2108,11 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
return res, nil
case "dkgComplaints":
- round, index := new(big.Int), new(big.Int)
- args := []interface{}{&round, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
return nil, errExecutionReverted
}
- complaints := g.state.DKGComplaints(round)
+ complaints := g.state.DKGComplaints()
if int(index.Uint64()) >= len(complaints) {
return nil, errExecutionReverted
}
@@ -2117,23 +2123,18 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
}
return res, nil
case "dkgReadys":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ addr := common.Address{}
+ if err := method.Inputs.Unpack(&addr, arguments); err != nil {
return nil, errExecutionReverted
}
- ready := g.state.DKGMPKReady(round, addr)
+ ready := g.state.DKGMPKReady(addr)
res, err := method.Outputs.Pack(ready)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "dkgReadysCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGMPKReadysCount(round)
+ count := g.state.DKGMPKReadysCount()
res, err := method.Outputs.Pack(count)
if err != nil {
return nil, errExecutionReverted
@@ -2141,35 +2142,29 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re
return res, nil
case "dkgFinalizeds":
- round, addr := new(big.Int), common.Address{}
- args := []interface{}{&round, &addr}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ addr := common.Address{}
+ if err := method.Inputs.Unpack(&addr, arguments); err != nil {
return nil, errExecutionReverted
}
- finalized := g.state.DKGFinalized(round, addr)
+ finalized := g.state.DKGFinalized(addr)
res, err := method.Outputs.Pack(finalized)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "dkgFinalizedsCount":
- round := new(big.Int)
- if err := method.Inputs.Unpack(&round, arguments); err != nil {
- return nil, errExecutionReverted
- }
- count := g.state.DKGFinalizedsCount(round)
+ count := g.state.DKGFinalizedsCount()
res, err := method.Outputs.Pack(count)
if err != nil {
return nil, errExecutionReverted
}
return res, nil
case "dkgMasterPublicKeys":
- round, index := new(big.Int), new(big.Int)
- args := []interface{}{&round, &index}
- if err := method.Inputs.Unpack(&args, arguments); err != nil {
+ index := new(big.Int)
+ if err := method.Inputs.Unpack(&index, arguments); err != nil {
return nil, errExecutionReverted
}
- mpks := g.state.DKGMasterPublicKeys(round)
+ mpks := g.state.DKGMasterPublicKeys()
if int(index.Uint64()) >= len(mpks) {
return nil, errExecutionReverted
}
@@ -2442,7 +2437,6 @@ func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) {
if err != nil {
return nil, err
}
-
data := append(method.Id(), res...)
return data, nil
}
@@ -2464,7 +2458,6 @@ func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) {
if err != nil {
return nil, err
}
-
data := append(method.Id(), res...)
return data, nil
}
diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go
index 4980d4b77..c96256e5d 100644
--- a/core/vm/oracle_contracts_test.go
+++ b/core/vm/oracle_contracts_test.go
@@ -27,6 +27,7 @@ import (
"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"
@@ -57,22 +58,22 @@ func randomBytes(minLength, maxLength int32) []byte {
return b
}
-type GovernanceStateHelperTestSuite struct {
+type GovernanceStateTestSuite struct {
suite.Suite
- s *GovernanceStateHelper
+ s *GovernanceState
}
-func (g *GovernanceStateHelperTestSuite) SetupTest() {
+func (g *GovernanceStateTestSuite) SetupTest() {
db := state.NewDatabase(ethdb.NewMemDatabase())
statedb, err := state.New(common.Hash{}, db)
if err != nil {
panic(err)
}
- g.s = &GovernanceStateHelper{statedb}
+ g.s = &GovernanceState{statedb}
}
-func (g *GovernanceStateHelperTestSuite) TestReadWriteEraseBytes() {
+func (g *GovernanceStateTestSuite) TestReadWriteEraseBytes() {
for i := 0; i < 100; i++ {
// Short bytes.
loc := big.NewInt(rand.Int63())
@@ -96,30 +97,27 @@ func (g *GovernanceStateHelperTestSuite) TestReadWriteEraseBytes() {
}
}
-func (g *GovernanceStateHelperTestSuite) TestReadWriteErase2DArray() {
- for i := 0; i < 50; i++ {
- loc := big.NewInt(rand.Int63())
- for j := 0; j < 50; j++ {
- idx := big.NewInt(int64(j))
- data := make([][]byte, 30)
- for key := range data {
- data[key] = randomBytes(3, 32)
- g.s.appendTo2DByteArray(loc, idx, data[key])
- }
- read := g.s.read2DByteArray(loc, idx)
- g.Require().Len(read, len(data))
- for key := range data {
- g.Require().Equal(0, bytes.Compare(data[key], read[key]))
- }
- g.s.erase2DByteArray(loc, idx)
- read = g.s.read2DByteArray(loc, idx)
- g.Require().Len(read, 0)
+func (g *GovernanceStateTestSuite) TestReadWriteErase1DArray() {
+ for j := 0; j < 50; j++ {
+ idx := big.NewInt(int64(j))
+ data := make([][]byte, 30)
+ for key := range data {
+ data[key] = randomBytes(3, 32)
+ g.s.appendTo1DByteArray(idx, data[key])
}
+ read := g.s.read1DByteArray(idx)
+ g.Require().Len(read, len(data))
+ for key := range data {
+ g.Require().Equal(0, bytes.Compare(data[key], read[key]))
+ }
+ g.s.erase1DByteArray(idx)
+ read = g.s.read1DByteArray(idx)
+ g.Require().Len(read, 0)
}
}
-func TestGovernanceStateHelper(t *testing.T) {
- suite.Run(t, new(GovernanceStateHelperTestSuite))
+func TestGovernanceState(t *testing.T) {
+ suite.Run(t, new(GovernanceStateTestSuite))
}
type OracleContractsTestSuite struct {
@@ -129,7 +127,7 @@ type OracleContractsTestSuite struct {
config *params.DexconConfig
memDB *ethdb.MemDatabase
stateDB *state.StateDB
- s *GovernanceStateHelper
+ s *GovernanceState
}
func (g *OracleContractsTestSuite) SetupTest() {
@@ -140,7 +138,7 @@ func (g *OracleContractsTestSuite) SetupTest() {
}
g.memDB = memDB
g.stateDB = stateDB
- g.s = &GovernanceStateHelper{stateDB}
+ g.s = &GovernanceState{stateDB}
config := params.TestnetChainConfig.Dexcon
config.LockupPeriod = 1000
@@ -156,7 +154,7 @@ func (g *OracleContractsTestSuite) SetupTest() {
// Genesis CRS.
crs := crypto.Keccak256Hash([]byte(config.GenesisCRSText))
- g.s.PushCRS(crs)
+ g.s.SetCRS(crs)
// Round 0 height.
g.s.PushRoundHeight(big.NewInt(0))
@@ -671,7 +669,7 @@ func (g *OracleContractsTestSuite) TestConfigurationReading() {
_, addr := g.newPrefundAccount()
// CRS.
- input, err := GovernanceABI.ABI.Pack("crs", big.NewInt(0))
+ input, err := GovernanceABI.ABI.Pack("crs")
g.Require().NoError(err)
res, err := g.call(GovernanceContractAddress, addr, input, big.NewInt(0))
g.Require().NoError(err)
@@ -1082,7 +1080,7 @@ type testCoreMock struct {
tsigReturn bool
}
-func (m *testCoreMock) SetState(GovernanceStateHelper) {}
+func (m *testCoreMock) SetState(GovernanceState) {}
func (m *testCoreMock) NewGroupPublicKey(*big.Int, int) (tsigVerifierIntf, error) {
if m.newDKGGPKError != nil {
@@ -1106,7 +1104,8 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
// Stake.
amount := new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e6))
- input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1", "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
+ input, err := GovernanceABI.ABI.Pack("stake", pk, "Test1",
+ "test1@dexon.org", "Taipei, Taiwan", "https://dexon.org")
g.Require().NoError(err)
_, err = g.call(GovernanceContractAddress, addr, input, amount)
g.Require().NoError(err)
@@ -1114,10 +1113,29 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
g.Require().Len(g.s.QualifiedNodes(), int(g.config.DKGSetSize))
addrs := make(map[int][]common.Address)
- addDKG := func(round int, final bool) {
+ dkgSets := make(map[int]map[coreTypes.NodeID]struct{})
+ addDKG := func(round int, final, proposeCRS bool) {
+ if proposeCRS && uint64(round) > dexCore.DKGDelayRound {
+ // ProposeCRS and clear DKG state.
+ input, err := GovernanceABI.ABI.Pack(
+ "proposeCRS", big.NewInt(int64(round)), randomBytes(32, 32))
+ g.Require().NoError(err)
+ _, err = g.call(GovernanceContractAddress, addrs[round-1][0], input, big.NewInt(0))
+ g.Require().NoError(err)
+
+ // Clear DKG states for next round.
+ dkgSet := dkgSets[round-1]
+ g.s.ClearDKGMasterPublicKeys()
+ g.s.ClearDKGComplaints()
+ g.s.ClearDKGMPKReady(dkgSet)
+ g.s.ResetDKGMPKReadysCount()
+ g.s.ClearDKGFinalized(dkgSet)
+ g.s.ResetDKGFinalizedsCount()
+ g.s.SetDKGRound(big.NewInt(int64(round)))
+ }
+
addrs[round] = []common.Address{}
- r := big.NewInt(int64(round))
- target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.s.CRS(r)))
+ target := coreTypes.NewDKGSetTarget(coreCommon.Hash(g.s.CRS()))
ns := coreTypes.NewNodeSet()
for _, x := range g.s.QualifiedNodes() {
@@ -1129,6 +1147,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
}
dkgSet := ns.GetSubSet(int(g.s.DKGSetSize().Uint64()), target)
g.Require().Len(dkgSet, int(g.config.DKGSetSize))
+ dkgSets[round] = dkgSet
for id := range dkgSet {
offset := g.s.NodesOffsetByID(Bytes32(id.Hash))
@@ -1137,66 +1156,69 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
}
node := g.s.Node(offset)
// Prepare MPK.
- g.s.PushDKGMasterPublicKey(r, randomBytes(32, 64))
+ g.s.PushDKGMasterPublicKey(randomBytes(32, 64))
// Prepare Complaint.
- g.s.PushDKGComplaint(r, randomBytes(32, 64))
+ g.s.PushDKGComplaint(randomBytes(32, 64))
addr := node.Owner
addrs[round] = append(addrs[round], addr)
// Prepare MPK Ready.
- g.s.PutDKGMPKReady(r, addr, true)
- g.s.IncDKGMPKReadysCount(r)
+ g.s.PutDKGMPKReady(addr, true)
+ g.s.IncDKGMPKReadysCount()
if final {
// Prepare Finalized.
- g.s.PutDKGFinalized(r, addr, true)
- g.s.IncDKGFinalizedsCount(r)
+ g.s.PutDKGFinalized(addr, true)
+ g.s.IncDKGFinalizedsCount()
}
}
dkgSetSize := len(dkgSet)
- g.Require().Len(g.s.DKGMasterPublicKeys(r), dkgSetSize)
- g.Require().Len(g.s.DKGComplaints(r), dkgSetSize)
- g.Require().Equal(0, g.s.DKGMPKReadysCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ g.Require().Len(g.s.DKGMasterPublicKeys(), dkgSetSize)
+ g.Require().Len(g.s.DKGComplaints(), dkgSetSize)
+ g.Require().Equal(int64(dkgSetSize), g.s.DKGMPKReadysCount().Int64())
for _, addr := range addrs[round] {
- g.Require().True(g.s.DKGMPKReady(r, addr))
+ g.Require().True(g.s.DKGMPKReady(addr))
}
+
if final {
- g.Require().Equal(0, g.s.DKGFinalizedsCount(r).Cmp(big.NewInt(int64(dkgSetSize))))
+ g.Require().Equal(int64(dkgSetSize), g.s.DKGFinalizedsCount().Int64())
for _, addr := range addrs[round] {
- g.Require().True(g.s.DKGFinalized(r, addr))
+ g.Require().True(g.s.DKGFinalized(addr))
}
}
+
}
+ mock := &testCoreMock{
+ tsigReturn: true,
+ }
+ OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = mock
+
// Fill data for previous rounds.
roundHeight := int64(g.config.RoundLength)
- round := 3
+ round := int(dexCore.DKGDelayRound) + 3
for i := 0; i <= round; i++ {
- // Prepare CRS.
- crs := common.BytesToHash(randomBytes(common.HashLength, common.HashLength))
- g.s.PushCRS(crs)
+ g.context.Round = big.NewInt(int64(i))
+
// Prepare Round Height
if i != 0 {
g.s.PushRoundHeight(big.NewInt(int64(i) * roundHeight))
}
- g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(i+2))))
- g.Require().Equal(crs, g.s.CurrentCRS())
- }
- for i := 0; i <= round; i++ {
- addDKG(i, true)
- }
- mock := &testCoreMock{
- tsigReturn: true,
+ addDKG(i+1, true, true)
}
- OracleContracts[GovernanceContractAddress].(*GovernanceContract).coreDKGUtils = mock
+
+ round++
+ g.s.PushRoundHeight(big.NewInt(int64(round) * roundHeight))
+ g.context.Round = big.NewInt(int64(round))
+ addDKG(round+1, false, true)
repeat := 3
for r := 0; r < repeat; r++ {
- addDKG(round+1, false)
// Add one finalized for test.
roundPlusOne := big.NewInt(int64(round + 1))
- g.s.PutDKGFinalized(roundPlusOne, addrs[round+1][0], true)
- g.s.IncDKGFinalizedsCount(roundPlusOne)
+ g.s.PutDKGFinalized(addrs[round+1][0], true)
+ g.s.IncDKGFinalizedsCount()
- g.context.BlockNumber = big.NewInt(roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
+ g.context.BlockNumber = big.NewInt(
+ roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100)
_, addr := g.newPrefundAccount()
newCRS := randomBytes(common.HashLength, common.HashLength)
input, err := GovernanceABI.ABI.Pack("resetDKG", newCRS)
@@ -1206,29 +1228,26 @@ func (g *OracleContractsTestSuite) TestResetDKG() {
// Test if CRS is reset.
newCRSHash := crypto.Keccak256Hash(newCRS)
- g.Require().Equal(0, g.s.LenCRS().Cmp(big.NewInt(int64(round+2))))
- g.Require().Equal(newCRSHash, g.s.CurrentCRS())
- g.Require().Equal(newCRSHash, g.s.CRS(big.NewInt(int64(round+1))))
+ g.Require().Equal(newCRSHash, g.s.CRS())
// Test if MPK is purged.
- g.Require().Len(g.s.DKGMasterPublicKeys(big.NewInt(int64(round+1))), 0)
+ g.Require().Len(g.s.DKGMasterPublicKeys(), 0)
// Test if MPKReady is purged.
- g.Require().Equal(0,
- g.s.DKGMPKReadysCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ g.Require().Equal(int64(0), g.s.DKGMPKReadysCount().Int64())
for _, addr := range addrs[round+1] {
- g.Require().False(g.s.DKGMPKReady(big.NewInt(int64(round+1)), addr))
+ g.Require().False(g.s.DKGMPKReady(addr))
}
// Test if Complaint is purged.
- g.Require().Len(g.s.DKGComplaints(big.NewInt(int64(round+1))), 0)
+ g.Require().Len(g.s.DKGComplaints(), 0)
// Test if Finalized is purged.
- g.Require().Equal(0,
- g.s.DKGFinalizedsCount(big.NewInt(int64(round+1))).Cmp(big.NewInt(0)))
+ g.Require().Equal(int64(0), g.s.DKGFinalizedsCount().Int64())
for _, addr := range addrs[round+1] {
- g.Require().False(g.s.DKGFinalized(big.NewInt(int64(round+1)), addr))
+ g.Require().False(g.s.DKGFinalized(addr))
}
- g.Require().Equal(0,
- g.s.DKGResetCount(roundPlusOne).Cmp(big.NewInt(int64(r+1))))
+ g.Require().Equal(int64(r+1), g.s.DKGResetCount(roundPlusOne).Int64())
+
+ addDKG(round+1, false, false)
}
}
diff --git a/dex/downloader/downloader.go b/dex/downloader/downloader.go
index e15844668..3d3a78e18 100644
--- a/dex/downloader/downloader.go
+++ b/dex/downloader/downloader.go
@@ -496,17 +496,6 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, number ui
}
d.verifierCache = dexCore.NewTSigVerifierCache(d.gov, 5)
-
- // warm up verifierCache
- if originHeader.Round > 0 {
- ok, err := d.verifierCache.Update(originHeader.Round - 1)
- if err != nil {
- return err
- }
- if !ok {
- return fmt.Errorf("can not update verifier cache")
- }
- }
}
// Initiate the sync using a concurrent header and content retrieval algorithm
diff --git a/dex/downloader/testchain_test.go b/dex/downloader/testchain_test.go
index 73d4863a5..722159bc0 100644
--- a/dex/downloader/testchain_test.go
+++ b/dex/downloader/testchain_test.go
@@ -21,6 +21,9 @@ import (
"fmt"
"math/big"
+ dexCore "github.com/dexon-foundation/dexon-consensus/core"
+ coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
+
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/consensus/dexcon"
"github.com/dexon-foundation/dexon/core"
@@ -66,23 +69,23 @@ func genesisBlockForTesting(db ethdb.Database,
Staked: new(big.Int),
},
nodeaddr1: {
- Balance: new(big.Int).Mul(big.NewInt(1000), ether),
- Staked: new(big.Int).Mul(big.NewInt(500), ether),
+ Balance: new(big.Int).Mul(big.NewInt(2e6), ether),
+ Staked: new(big.Int).Mul(big.NewInt(1e6), ether),
PublicKey: crypto.FromECDSAPub(&nodekey1.PublicKey),
},
nodeaddr2: {
- Balance: new(big.Int).Mul(big.NewInt(1000), ether),
- Staked: new(big.Int).Mul(big.NewInt(500), ether),
+ Balance: new(big.Int).Mul(big.NewInt(2e6), ether),
+ Staked: new(big.Int).Mul(big.NewInt(1e6), ether),
PublicKey: crypto.FromECDSAPub(&nodekey2.PublicKey),
},
nodeaddr3: {
- Balance: new(big.Int).Mul(big.NewInt(1000), ether),
- Staked: new(big.Int).Mul(big.NewInt(500), ether),
+ Balance: new(big.Int).Mul(big.NewInt(2e6), ether),
+ Staked: new(big.Int).Mul(big.NewInt(1e6), ether),
PublicKey: crypto.FromECDSAPub(&nodekey3.PublicKey),
},
nodeaddr4: {
- Balance: new(big.Int).Mul(big.NewInt(1000), ether),
- Staked: new(big.Int).Mul(big.NewInt(500), ether),
+ Balance: new(big.Int).Mul(big.NewInt(2e6), ether),
+ Staked: new(big.Int).Mul(big.NewInt(1e6), ether),
PublicKey: crypto.FromECDSAPub(&nodekey4.PublicKey),
},
},
@@ -166,50 +169,23 @@ func (tc *testChain) generate(n int, seed byte, parent *types.Block, nodes *dexc
blocks, receipts := core.GenerateDexonChain(params.TestnetChainConfig, parent, engine, testDB, n, func(i int, block *core.DexonBlockGen) {
block.SetCoinbase(common.Address{seed})
- if round == 0 {
- switch i {
- case 1:
- testNodes.RunDKG(round, 2)
- // Add DKG MasterPublicKeys
- for _, node := range testNodes.Nodes(round) {
- data, err := vm.PackAddDKGMasterPublicKey(round, node.MasterPublicKey(round))
- if err != nil {
- panic(err)
- }
- addTx(block, node, data)
- }
- case 2:
- // Add DKG MPKReady
- for _, node := range testNodes.Nodes(round) {
- data, err := vm.PackAddDKGMPKReady(round, node.DKGMPKReady(round))
- if err != nil {
- panic(err)
- }
- addTx(block, node, data)
- }
- case 3:
- // Add DKG Finalize
- for _, node := range testNodes.Nodes(round) {
- data, err := vm.PackAddDKGFinalize(round, node.DKGFinalize(round))
- if err != nil {
- panic(err)
- }
- addTx(block, node, data)
- }
- }
- }
-
+ block.SetPosition(coreTypes.Position{
+ Round: round,
+ Height: uint64(i),
+ })
half := roundInterval / 2
switch i % roundInterval {
case half:
- // Sign current CRS to geneate the next round CRS and propose it.
- testNodes.SignCRS(round)
- node := testNodes.Nodes(round)[0]
- data, err := vm.PackProposeCRS(round, testNodes.SignedCRS(round+1))
- if err != nil {
- panic(err)
+ if round >= dexCore.DKGDelayRound {
+ // Sign current CRS to geneate the next round CRS and propose it.
+ testNodes.SignCRS(round)
+ node := testNodes.Nodes(round)[0]
+ data, err := vm.PackProposeCRS(round, testNodes.SignedCRS(round+1))
+ if err != nil {
+ panic(err)
+ }
+ addTx(block, node, data)
}
- addTx(block, node, data)
case half + 1:
// Run the DKG for next round.
testNodes.RunDKG(round+1, 2)
@@ -356,13 +332,13 @@ func (g *govStateFetcher) SnapshotRound(round uint64, root common.Hash) {
g.rootByRound[round] = root
}
-func (g *govStateFetcher) GetGovStateHelperAtRound(round uint64) *vm.GovernanceStateHelper {
+func (g *govStateFetcher) GetStateForConfigAtRound(round uint64) *vm.GovernanceState {
if root, ok := g.rootByRound[round]; ok {
s, err := state.New(root, g.db)
if err != nil {
panic(err)
}
- return &vm.GovernanceStateHelper{s}
+ return &vm.GovernanceState{s}
}
return nil
}
diff --git a/dex/governance.go b/dex/governance.go
index 56d08975e..d9cf8fb65 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -67,7 +67,7 @@ func NewDexconGovernance(backend *DexAPIBackend, chainConfig *params.ChainConfig
// DexconConfiguration return raw config in state.
func (d *DexconGovernance) DexconConfiguration(round uint64) *params.DexconConfig {
- return d.GetGovStateHelperAtRound(round).Configuration()
+ return d.GetStateForConfigAtRound(round).Configuration()
}
func (d *DexconGovernance) sendGovTx(ctx context.Context, data []byte) error {
@@ -107,13 +107,32 @@ 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.GetHeadHelper()
- return coreCommon.Hash(s.CRS(big.NewInt(int64(round))))
+ 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) LenCRS() uint64 {
- s := d.GetHeadHelper()
- return s.LenCRS().Uint64()
+func (d *DexconGovernance) CRSRound() uint64 {
+ return d.GetHeadState().CRSRound().Uint64()
}
// ProposeCRS send proposals of a new CRS
@@ -132,7 +151,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.GetGovStateHelperAtRound(round)
+ s := d.GetStateForConfigAtRound(round)
var pks []coreCrypto.PublicKey
for _, n := range s.QualifiedNodes() {
diff --git a/dex/handler.go b/dex/handler.go
index 4ffa01244..5bd615c86 100644
--- a/dex/handler.go
+++ b/dex/handler.go
@@ -45,6 +45,7 @@ import (
"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"
coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
dkgTypes "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
@@ -1199,13 +1200,18 @@ func (pm *ProtocolManager) recordBroadcastLoop() {
// a loop keep building and maintaining peers in notary set.
// TODO: finish this
func (pm *ProtocolManager) peerSetLoop() {
- log.Debug("start peer set loop")
- round := pm.gov.LenCRS() - 1
- log.Trace("first len crs", "len", round+1, "round", round)
- if round >= 1 {
- pm.peers.BuildConnection(round - 1)
+ log.Debug("ProtocolManager: started peer set loop")
+
+ round := pm.gov.Round()
+ log.Trace("ProtocolManager: startup round", "round", round)
+
+ if round < dexCore.DKGDelayRound {
+ for i := round; i <= dexCore.DKGDelayRound; i++ {
+ pm.peers.BuildConnection(i)
+ }
+ } else {
+ pm.peers.BuildConnection(round)
}
- pm.peers.BuildConnection(round)
for {
select {
@@ -1216,11 +1222,16 @@ func (pm *ProtocolManager) peerSetLoop() {
break
}
- newRound := pm.gov.LenCRS() - 1
- log.Trace("new round", "round", newRound)
+ newRound := pm.gov.CRSRound()
+ if newRound == 0 {
+ break
+ }
+
+ log.Debug("ProtocolManager: new round", "round", newRound)
if newRound == round {
break
}
+
if newRound == round+1 {
pm.peers.BuildConnection(newRound)
if round >= 1 {
diff --git a/dex/helper_test.go b/dex/helper_test.go
index 3f901e6ec..c8bf62a6b 100644
--- a/dex/helper_test.go
+++ b/dex/helper_test.go
@@ -215,7 +215,11 @@ type testGovernance struct {
dkgSetFunc func(uint64) (map[string]struct{}, error)
}
-func (g *testGovernance) LenCRS() uint64 {
+func (g *testGovernance) Round() uint64 {
+ return g.lenCRSFunc()
+}
+
+func (g *testGovernance) CRSRound() uint64 {
return g.lenCRSFunc()
}
diff --git a/dex/protocol.go b/dex/protocol.go
index 0e3f50eba..d72e95478 100644
--- a/dex/protocol.go
+++ b/dex/protocol.go
@@ -152,7 +152,9 @@ type txPool interface {
type governance interface {
GetRoundHeight(uint64) uint64
- LenCRS() uint64
+ Round() uint64
+
+ CRSRound() uint64
NotarySet(uint64) (map[string]struct{}, error)
diff --git a/params/config.go b/params/config.go
index efcf0400a..c13a5e4bf 100644
--- a/params/config.go
+++ b/params/config.go
@@ -26,9 +26,9 @@ import (
// Genesis hashes to enforce below configs on.
var (
- MainnetGenesisHash = common.HexToHash("0xf80aae99a7c44bc54d7b0cc8a16645fa3ea65c01b180339f17b31a698b031271")
- TestnetGenesisHash = common.HexToHash("0x7f704c8d0a773d0fcca231d40bf39495553886bf8800b4a06920786a802103e1")
- YilanGenesisHash = common.HexToHash("0x394f057bc19b7762eaccd7e250afa213e9b0e60d1204a234fd11ed03eabfb90e")
+ MainnetGenesisHash = common.HexToHash("0x605d2850786a493b48c428dc447785c73912cf649d792196532412561058e390")
+ TestnetGenesisHash = common.HexToHash("0x376d2e79e046907c8947df0985d43574dbfd23bd82c4bc3e85fc5f0d0599590a")
+ YilanGenesisHash = common.HexToHash("0xd9b4eb0bfd7bbc8193ed5afd11adf9b9b34f09df7b1e0a0f17f580242e22bf76")
)
var (