aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/blockchain.go2
-rw-r--r--core/governance.go15
-rw-r--r--core/vm/oracle_contracts.go10
-rw-r--r--dex/app.go75
-rw-r--r--dex/app_test.go18
-rw-r--r--dex/governance.go21
-rw-r--r--dex/handler.go15
-rw-r--r--dex/helper_test.go14
-rw-r--r--dex/peer.go37
-rw-r--r--dex/peer_test.go97
-rw-r--r--dex/protocol.go4
-rw-r--r--dex/protocol_test.go64
-rw-r--r--params/config.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/common/event.go75
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go158
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go4
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go65
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go267
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/constant.go12
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go6
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/round-based-config.go29
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go9
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go54
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/ticker.go56
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go36
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go33
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go23
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go9
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go11
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go34
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go7
-rw-r--r--vendor/vendor.json50
33 files changed, 555 insertions, 759 deletions
diff --git a/core/blockchain.go b/core/blockchain.go
index 5e3b4b30a..34235c10b 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -293,7 +293,7 @@ type blockInfo struct {
}
func (bc *BlockChain) AddConfirmedBlock(block *coreTypes.Block) error {
- chainID := block.Position.ChainID
+ chainID := uint32(0)
bc.confirmedBlockInitMu.Lock()
_, exist := bc.confirmedBlocks[chainID]
if !exist {
diff --git a/core/governance.go b/core/governance.go
index 9929867c9..03f53ae6b 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -91,12 +91,11 @@ func (g *Governance) Configuration(round uint64) *coreTypes.Config {
configHelper := g.GetGovStateHelperAtRound(round)
c := configHelper.Configuration()
return &coreTypes.Config{
- LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
- LambdaDKG: time.Duration(c.LambdaDKG) * time.Millisecond,
- NotarySetSize: c.NotarySetSize,
- DKGSetSize: c.DKGSetSize,
- // TODO(jimmyhu): remove MinBlockInterval after coreTypes.Config update.
- RoundInterval: time.Duration(c.RoundLength) * time.Duration(c.MinBlockInterval) * time.Millisecond,
+ LambdaBA: time.Duration(c.LambdaBA) * time.Millisecond,
+ LambdaDKG: time.Duration(c.LambdaDKG) * time.Millisecond,
+ NotarySetSize: c.NotarySetSize,
+ DKGSetSize: c.DKGSetSize,
+ RoundLength: c.RoundLength,
MinBlockInterval: time.Duration(c.MinBlockInterval) * time.Millisecond,
}
}
@@ -138,3 +137,7 @@ func (g *Governance) IsDKGFinal(round uint64) bool {
func (g *Governance) MinGasPrice(round uint64) *big.Int {
return g.GetGovStateHelperAtRound(round).MinGasPrice()
}
+
+func (g *Governance) DKGResetCount(round uint64) uint64 {
+ return g.GetHeadHelper().DKGResetCount(big.NewInt(int64(round))).Uint64()
+}
diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go
index 826e0396c..aa93c97fb 100644
--- a/core/vm/oracle_contracts.go
+++ b/core/vm/oracle_contracts.go
@@ -2469,6 +2469,16 @@ func PackReportForkBlock(block1, block2 *coreTypes.Block) ([]byte, error) {
return data, nil
}
+func PackResetDKG(newSignedCRS []byte) ([]byte, error) {
+ method := GovernanceABI.Name2Method["resetDKG"]
+ res, err := method.Inputs.Pack(newSignedCRS)
+ if err != nil {
+ return nil, err
+ }
+ data := append(method.Id(), res...)
+ return data, nil
+}
+
// NodeInfoOracleContract representing a oracle providing the node information.
type NodeInfoOracleContract struct {
}
diff --git a/dex/app.go b/dex/app.go
index ab4e80058..6ef20684f 100644
--- a/dex/app.go
+++ b/dex/app.go
@@ -29,7 +29,6 @@ import (
"github.com/dexon-foundation/dexon/common"
"github.com/dexon-foundation/dexon/core"
- "github.com/dexon-foundation/dexon/core/rawdb"
"github.com/dexon-foundation/dexon/core/types"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/event"
@@ -178,8 +177,8 @@ func (d *DexconApp) PreparePayload(position coreTypes.Position) (payload []byte,
func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Position) (
payload []byte, err error) {
- d.chainRLock(position.ChainID)
- defer d.chainRUnlock(position.ChainID)
+ d.chainRLock(uint32(0))
+ defer d.chainRUnlock(uint32(0))
select {
// This case will hit if previous RLock took too much time.
case <-ctx.Done():
@@ -187,25 +186,9 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit
default:
}
- if position.Round > 0 {
- // If round chain number changed but new round is not delivered yet, payload must be nil.
- previousNumChains := d.gov.Configuration(position.Round - 1).NumChains
- currentNumChains := d.gov.Configuration(position.Round).NumChains
- if previousNumChains != currentNumChains {
- deliveredRound, err := rawdb.ReadLastRoundNumber(d.chainDB)
- if err != nil {
- panic(fmt.Errorf("read current round error: %v", err))
- }
-
- if deliveredRound < position.Round {
- return nil, nil
- }
- }
- }
-
if position.Height != 0 {
// Check if chain block height is strictly increamental.
- chainLastHeight, ok := d.blockchain.GetChainLastConfirmedHeight(position.ChainID)
+ chainLastHeight, ok := d.blockchain.GetChainLastConfirmedHeight(uint32(0))
if !ok || chainLastHeight != position.Height-1 {
log.Debug("Previous confirmed block not exists", "current pos", position.String(),
"prev height", chainLastHeight, "ok", ok)
@@ -213,7 +196,7 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit
}
}
- root, exist := d.chainRoot.Load(position.ChainID)
+ root, exist := d.chainRoot.Load(uint32(0))
if !exist {
return nil, nil
}
@@ -222,14 +205,14 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit
if err != nil {
return nil, err
}
- log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height)
+ log.Debug("Prepare payload", "chain", uint32(0), "height", position.Height)
txsMap, err := d.txPool.Pending()
if err != nil {
return
}
- chainID := new(big.Int).SetUint64(uint64(position.ChainID))
+ chainID := new(big.Int).SetUint64(uint64(uint32(0)))
chainNums := new(big.Int).SetUint64(uint64(d.gov.GetNumChains(position.Round)))
blockGasLimit := new(big.Int).SetUint64(d.gov.DexconConfiguration(position.Round).BlockGasLimit)
blockGasUsed := new(big.Int)
@@ -248,13 +231,13 @@ addressMap:
}
balance := currentState.GetBalance(address)
- cost, exist := d.blockchain.GetCostInConfirmedBlocks(position.ChainID, address)
+ cost, exist := d.blockchain.GetCostInConfirmedBlocks(uint32(0), address)
if exist {
balance = new(big.Int).Sub(balance, cost)
}
var expectNonce uint64
- lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(position.ChainID, address)
+ lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(uint32(0), address)
if !exist {
expectNonce = currentState.GetNonce(address)
} else {
@@ -354,13 +337,13 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
return coreTypes.VerifyInvalidBlock
}
- d.chainRLock(block.Position.ChainID)
- defer d.chainRUnlock(block.Position.ChainID)
+ d.chainRLock(uint32(0))
+ defer d.chainRUnlock(uint32(0))
if block.Position.Height != 0 {
// Check if target block is the next height to be verified, we can only
// verify the next block in a given chain.
- chainLastHeight, ok := d.blockchain.GetChainLastConfirmedHeight(block.Position.ChainID)
+ chainLastHeight, ok := d.blockchain.GetChainLastConfirmedHeight(uint32(0))
if !ok || chainLastHeight != block.Position.Height-1 {
log.Debug("Previous confirmed block not exists", "current pos", block.Position.String(),
"prev height", chainLastHeight, "ok", ok)
@@ -368,34 +351,14 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
}
}
- if block.Position.Round > 0 {
- // If round chain number changed but new round is not delivered yet, payload must be nil.
- previousNumChains := d.gov.Configuration(block.Position.Round - 1).NumChains
- currentNumChains := d.gov.Configuration(block.Position.Round).NumChains
- if previousNumChains != currentNumChains {
- deliveredRound, err := rawdb.ReadLastRoundNumber(d.chainDB)
- if err != nil {
- panic(fmt.Errorf("read current round error: %v", err))
- }
-
- if deliveredRound < block.Position.Round {
- if len(block.Payload) > 0 {
- return coreTypes.VerifyInvalidBlock
- }
-
- return coreTypes.VerifyOK
- }
- }
- }
-
// Get latest state with current chain.
- root, exist := d.chainRoot.Load(block.Position.ChainID)
+ root, exist := d.chainRoot.Load(uint32(0))
if !exist {
return coreTypes.VerifyRetryLater
}
currentState, err := d.blockchain.StateAt(*root.(*common.Hash))
- log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height)
+ log.Debug("Verify block", "chain", uint32(0), "height", block.Position.Height)
if err != nil {
log.Debug("Invalid state root", "root", *root.(*common.Hash), "err", err)
return coreTypes.VerifyInvalidBlock
@@ -428,7 +391,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
}
// Check if nonce is strictly increasing for every address.
- chainID := big.NewInt(int64(block.Position.ChainID))
+ chainID := big.NewInt(int64(uint32(0)))
chainNums := big.NewInt(int64(d.gov.GetNumChains(block.Position.Round)))
for address, firstNonce := range addressNonce {
@@ -438,7 +401,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
}
var expectNonce uint64
- lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(block.Position.ChainID, address)
+ lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(uint32(0), address)
if exist {
expectNonce = lastConfirmedNonce + 1
} else {
@@ -454,7 +417,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta
// Calculate balance in last state (including pending state).
addressesBalance := map[common.Address]*big.Int{}
for address := range addressNonce {
- cost, exist := d.blockchain.GetCostInConfirmedBlocks(block.Position.ChainID, address)
+ cost, exist := d.blockchain.GetCostInConfirmedBlocks(uint32(0), address)
if exist {
addressesBalance[address] = new(big.Int).Sub(currentState.GetBalance(address), cost)
} else {
@@ -509,7 +472,7 @@ func (d *DexconApp) BlockDelivered(
log.Debug("DexconApp block deliver", "height", result.Height, "hash", blockHash, "position", blockPosition.String())
defer log.Debug("DexconApp block delivered", "height", result.Height, "hash", blockHash, "position", blockPosition.String())
- chainID := blockPosition.ChainID
+ chainID := uint32(0)
d.chainLock(chainID)
defer d.chainUnlock(chainID)
@@ -567,8 +530,8 @@ func (d *DexconApp) BlockDelivered(
// BlockConfirmed is called when a block is confirmed and added to lattice.
func (d *DexconApp) BlockConfirmed(block coreTypes.Block) {
- d.chainLock(block.Position.ChainID)
- defer d.chainUnlock(block.Position.ChainID)
+ d.chainLock(uint32(0))
+ defer d.chainUnlock(uint32(0))
log.Debug("DexconApp block confirmed", "block", block.String())
if err := d.blockchain.AddConfirmedBlock(&block); err != nil {
diff --git a/dex/app_test.go b/dex/app_test.go
index 73d952f31..221c55e0d 100644
--- a/dex/app_test.go
+++ b/dex/app_test.go
@@ -52,7 +52,7 @@ func TestPreparePayload(t *testing.T) {
chainNum := uint32(0)
root := dex.blockchain.CurrentBlock().Root()
dex.app.chainRoot.Store(chainNum, &root)
- payload, err := dex.app.PreparePayload(coreTypes.Position{ChainID: chainNum})
+ payload, err := dex.app.PreparePayload(coreTypes.Position{})
if err != nil {
t.Fatalf("prepare payload error: %v", err)
}
@@ -152,7 +152,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare normal block.
block := &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100)
@@ -169,7 +168,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare invalid nonce tx.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 1, 100)
@@ -186,7 +184,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare invalid block height.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 2
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100)
@@ -203,7 +200,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare reach block limit.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 10000)
@@ -220,7 +216,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare insufficient funds.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
@@ -255,7 +250,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare invalid intrinsic gas.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
@@ -290,7 +284,6 @@ func TestVerifyBlock(t *testing.T) {
// Prepare invalid transactions with nonce.
block = &coreTypes.Block{}
block.Hash = coreCommon.NewRandomHash()
- block.Position.ChainID = uint32(chainID.Uint64())
block.Position.Height = 1
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
_, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0)
@@ -398,7 +391,6 @@ func TestBlockConfirmed(t *testing.T) {
block.Witness = witness
block.Payload = payload
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
- block.Position.ChainID = uint32(chainID.Uint64())
dex.app.BlockConfirmed(*block)
expectCounter++
@@ -573,7 +565,6 @@ func addTx(dex *Dexon, nonce int, signer types.Signer, key *ecdsa.PrivateKey) (
func prepareData(dex *Dexon, key *ecdsa.PrivateKey, startNonce, txNum int) (
payload []byte, witness coreTypes.Witness, cost big.Int, nonce uint64, err error) {
signer := types.NewEIP155Signer(dex.chainConfig.ChainID)
- chainID := big.NewInt(0)
for n := startNonce; n < startNonce+txNum; n++ {
var tx *types.Transaction
@@ -586,7 +577,7 @@ func prepareData(dex *Dexon, key *ecdsa.PrivateKey, startNonce, txNum int) (
nonce = uint64(n)
}
- payload, err = dex.app.PreparePayload(coreTypes.Position{ChainID: uint32(chainID.Uint64())})
+ payload, err = dex.app.PreparePayload(coreTypes.Position{})
if err != nil {
return
}
@@ -624,7 +615,7 @@ func prepareConfirmedBlockWithTxAndData(dex *Dexon, key *ecdsa.PrivateKey, data
witness coreTypes.Witness
)
- payload, err = dex.app.PreparePayload(coreTypes.Position{Round: round, ChainID: uint32(0)})
+ payload, err = dex.app.PreparePayload(coreTypes.Position{Round: round})
if err != nil {
return
}
@@ -638,7 +629,6 @@ func prepareConfirmedBlockWithTxAndData(dex *Dexon, key *ecdsa.PrivateKey, data
block.Hash = coreCommon.NewRandomHash()
block.Witness = witness
block.Payload = payload
- block.Position.ChainID = uint32(0)
block.Position.Round = round
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
@@ -692,7 +682,6 @@ func prepareConfirmedBlocks(dex *Dexon, keys []*ecdsa.PrivateKey, txNum int) (bl
}, err error) {
for _, key := range keys {
address := crypto.PubkeyToAddress(key.PublicKey)
- chainID := big.NewInt(0)
// Prepare one block for pending.
var (
@@ -712,7 +701,6 @@ func prepareConfirmedBlocks(dex *Dexon, keys []*ecdsa.PrivateKey, txNum int) (bl
block.Hash = coreCommon.NewRandomHash()
block.Witness = witness
block.Payload = payload
- block.Position.ChainID = uint32(chainID.Uint64())
block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}}
status := dex.app.VerifyBlock(block)
diff --git a/dex/governance.go b/dex/governance.go
index 8b20cda19..56d08975e 100644
--- a/dex/governance.go
+++ b/dex/governance.go
@@ -229,12 +229,8 @@ func (d *DexconGovernance) ReportForkBlock(block1, block2 *coreTypes.Block) {
}
}
-func (d *DexconGovernance) GetNumChains(round uint64) uint32 {
- return 1
-}
-
-func (d *DexconGovernance) NotarySet(round uint64, chainID uint32) (map[string]struct{}, error) {
- notarySet, err := d.nodeSetCache.GetNotarySet(round, chainID)
+func (d *DexconGovernance) NotarySet(round uint64) (map[string]struct{}, error) {
+ notarySet, err := d.nodeSetCache.GetNotarySet(round)
if err != nil {
return nil, err
}
@@ -262,3 +258,16 @@ func (d *DexconGovernance) DKGSet(round uint64) (map[string]struct{}, error) {
}
return r, nil
}
+
+func (d *DexconGovernance) ResetDKG(newSignedCRS []byte) {
+ data, err := vm.PackResetDKG(newSignedCRS)
+ if err != nil {
+ log.Error("failed to pack resetDKG input", "err", err)
+ return
+ }
+
+ err = d.sendGovTx(context.Background(), data)
+ if err != nil {
+ log.Error("failed to send resetDKG tx", "err", err)
+ }
+}
diff --git a/dex/handler.go b/dex/handler.go
index 474852913..4ffa01244 100644
--- a/dex/handler.go
+++ b/dex/handler.go
@@ -1005,9 +1005,8 @@ func (pm *ProtocolManager) BroadcastVote(vote *coreTypes.Vote) {
pm.cache.addVote(vote)
}
label := peerLabel{
- set: notaryset,
- chainID: vote.Position.ChainID,
- round: vote.Position.Round,
+ set: notaryset,
+ round: vote.Position.Round,
}
for _, peer := range pm.peers.PeersWithLabel(label) {
peer.AsyncSendVotes([]*coreTypes.Vote{vote})
@@ -1038,9 +1037,8 @@ func (pm *ProtocolManager) BroadcastRandomnessResult(
pm.cache.addRandomness(randomness)
// send to notary nodes first (direct)
label := peerLabel{
- set: notaryset,
- chainID: randomness.Position.ChainID,
- round: randomness.Position.Round,
+ set: notaryset,
+ round: randomness.Position.Round,
}
randomnesses := []*coreTypes.BlockRandomnessResult{randomness}
for _, peer := range pm.peers.PeersWithLabel(label) {
@@ -1104,9 +1102,8 @@ func (pm *ProtocolManager) BroadcastPullBlocks(
func (pm *ProtocolManager) BroadcastPullVotes(
pos coreTypes.Position) {
label := peerLabel{
- set: notaryset,
- chainID: pos.ChainID,
- round: pos.Round,
+ set: notaryset,
+ round: pos.Round,
}
for idx, peer := range pm.peers.PeersWithLabel(label) {
if idx >= maxPullVotePeers {
diff --git a/dex/helper_test.go b/dex/helper_test.go
index e3d6aa3b7..3f901e6ec 100644
--- a/dex/helper_test.go
+++ b/dex/helper_test.go
@@ -130,10 +130,9 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
}
tgov := &testGovernance{
- numChainsFunc: func(uint64) uint32 { return 3 },
lenCRSFunc: func() uint64 { return 1 },
dkgSetFunc: func(uint64) (map[string]struct{}, error) { return nil, nil },
- notarySetFunc: func(uint64, uint32) (map[string]struct{}, error) { return nil, nil },
+ notarySetFunc: func(uint64) (map[string]struct{}, error) { return nil, nil },
}
pm, err := NewProtocolManager(gspec.Config, mode, DefaultConfig.NetworkId, dMoment, evmux, &testTxPool{added: newtx}, engine, blockchain, db, true, tgov, &testApp{})
@@ -211,23 +210,18 @@ func newTestTransaction(from *ecdsa.PrivateKey, nonce uint64, datasize int) *typ
// testGovernance is a fake, helper governance for testing purposes
type testGovernance struct {
- numChainsFunc func(uint64) uint32
lenCRSFunc func() uint64
- notarySetFunc func(uint64, uint32) (map[string]struct{}, error)
+ notarySetFunc func(uint64) (map[string]struct{}, error)
dkgSetFunc func(uint64) (map[string]struct{}, error)
}
-func (g *testGovernance) GetNumChains(round uint64) uint32 {
- return g.numChainsFunc(round)
-}
-
func (g *testGovernance) LenCRS() uint64 {
return g.lenCRSFunc()
}
func (g *testGovernance) NotarySet(
- round uint64, chainID uint32) (map[string]struct{}, error) {
- return g.notarySetFunc(round, chainID)
+ round uint64) (map[string]struct{}, error) {
+ return g.notarySetFunc(round)
}
func (g *testGovernance) DKGSet(round uint64) (map[string]struct{}, error) {
diff --git a/dex/peer.go b/dex/peer.go
index a157709f0..8ade9f152 100644
--- a/dex/peer.go
+++ b/dex/peer.go
@@ -119,9 +119,8 @@ const (
)
type peerLabel struct {
- set setType
- chainID uint32
- round uint64
+ set setType
+ round uint64
}
func (p peerLabel) String() string {
@@ -130,7 +129,7 @@ func (p peerLabel) String() string {
case dkgset:
t = fmt.Sprintf("DKGSet round: %d", p.round)
case notaryset:
- t = fmt.Sprintf("NotarySet round: %d chain: %d", p.round, p.chainID)
+ t = fmt.Sprintf("NotarySet round: %d", p.round)
}
return t
}
@@ -962,24 +961,22 @@ func (ps *peerSet) BuildConnection(round uint64) {
}
}
- for chainID := uint32(0); chainID < ps.gov.GetNumChains(round); chainID++ {
- notaryLabel := peerLabel{set: notaryset, chainID: chainID, round: round}
- if _, ok := ps.label2Nodes[notaryLabel]; !ok {
- notaryPKs, err := ps.gov.NotarySet(round, chainID)
- if err != nil {
- log.Error("get notary set fail",
- "round", round, "chainID", chainID, "err", err)
- continue
- }
+ notaryLabel := peerLabel{set: notaryset, round: round}
+ if _, ok := ps.label2Nodes[notaryLabel]; !ok {
+ notaryPKs, err := ps.gov.NotarySet(round)
+ if err != nil {
+ log.Error("get notary set fail",
+ "round", round, "err", err)
+ return
+ }
- nodes := ps.pksToNodes(notaryPKs)
- ps.label2Nodes[notaryLabel] = nodes
+ nodes := ps.pksToNodes(notaryPKs)
+ ps.label2Nodes[notaryLabel] = nodes
- if _, exists := nodes[ps.srvr.Self().ID().String()]; exists {
- ps.buildDirectConn(notaryLabel)
- } else {
- ps.buildGroupConn(notaryLabel)
- }
+ if _, exists := nodes[ps.srvr.Self().ID().String()]; exists {
+ ps.buildDirectConn(notaryLabel)
+ } else {
+ ps.buildGroupConn(notaryLabel)
}
}
}
diff --git a/dex/peer_test.go b/dex/peer_test.go
index 29b4971c5..76a28b1ef 100644
--- a/dex/peer_test.go
+++ b/dex/peer_test.go
@@ -19,41 +19,25 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
self := server.Self()
table := newNodeTable()
- gov := &testGovernance{
- numChainsFunc: func(uint64) uint32 {
- return 3
- },
- }
+ gov := &testGovernance{}
var nodes []*enode.Node
for i := 0; i < 9; i++ {
nodes = append(nodes, randomV4CompactNode())
}
- round10 := [][]*enode.Node{
- {self, nodes[1], nodes[2]},
- {nodes[1], nodes[3]},
- {nodes[2], nodes[4]},
- }
- round11 := [][]*enode.Node{
- {self, nodes[1], nodes[5]},
- {nodes[5], nodes[6]},
- {self, nodes[2], nodes[4]},
- }
- round12 := [][]*enode.Node{
- {self, nodes[3], nodes[5]},
- {self, nodes[7], nodes[8]},
- {self, nodes[2], nodes[6]},
- }
+ round10 := []*enode.Node{self, nodes[1], nodes[2]}
+ round11 := []*enode.Node{self, nodes[1], nodes[5]}
+ round12 := []*enode.Node{self, nodes[3], nodes[5]}
gov.notarySetFunc = func(
- round uint64, cid uint32) (map[string]struct{}, error) {
- m := map[uint64][][]*enode.Node{
+ round uint64) (map[string]struct{}, error) {
+ m := map[uint64][]*enode.Node{
10: round10,
11: round11,
12: round12,
}
- return newTestNodeSet(m[round][cid]), nil
+ return newTestNodeSet(m[round]), nil
}
gov.dkgSetFunc = func(round uint64) (map[string]struct{}, error) {
@@ -73,58 +57,31 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
ps.BuildConnection(12)
expectedlabel2Nodes := map[peerLabel]map[string]*enode.Node{
- {set: notaryset, round: 10, chainID: 0}: {
+ {set: notaryset, round: 10}: {
self.ID().String(): self,
nodes[1].ID().String(): nodes[1],
nodes[2].ID().String(): nodes[2],
},
- {set: notaryset, round: 10, chainID: 1}: {
- nodes[1].ID().String(): nodes[1],
- nodes[3].ID().String(): nodes[3],
- },
- {set: notaryset, round: 10, chainID: 2}: {
- nodes[2].ID().String(): nodes[2],
- nodes[4].ID().String(): nodes[4],
- },
{set: dkgset, round: 10}: {
self.ID().String(): self,
nodes[1].ID().String(): nodes[1],
nodes[3].ID().String(): nodes[3],
},
- {set: notaryset, round: 11, chainID: 0}: {
+ {set: notaryset, round: 11}: {
self.ID().String(): self,
nodes[1].ID().String(): nodes[1],
nodes[5].ID().String(): nodes[5],
},
- {set: notaryset, round: 11, chainID: 1}: {
- nodes[5].ID().String(): nodes[5],
- nodes[6].ID().String(): nodes[6],
- },
- {set: notaryset, round: 11, chainID: 2}: {
- self.ID().String(): self,
- nodes[2].ID().String(): nodes[2],
- nodes[4].ID().String(): nodes[4],
- },
{set: dkgset, round: 11}: {
nodes[1].ID().String(): nodes[1],
nodes[2].ID().String(): nodes[2],
nodes[5].ID().String(): nodes[5],
},
- {set: notaryset, round: 12, chainID: 0}: {
+ {set: notaryset, round: 12}: {
self.ID().String(): self,
nodes[3].ID().String(): nodes[3],
nodes[5].ID().String(): nodes[5],
},
- {set: notaryset, round: 12, chainID: 1}: {
- self.ID().String(): self,
- nodes[7].ID().String(): nodes[7],
- nodes[8].ID().String(): nodes[8],
- },
- {set: notaryset, round: 12, chainID: 2}: {
- self.ID().String(): self,
- nodes[2].ID().String(): nodes[2],
- nodes[6].ID().String(): nodes[6],
- },
{set: dkgset, round: 12}: {
self.ID().String(): self,
nodes[3].ID().String(): nodes[3],
@@ -137,14 +94,11 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
}
expectedDirectConn := map[peerLabel]struct{}{
- {set: notaryset, round: 10, chainID: 0}: {},
- {set: notaryset, round: 11, chainID: 0}: {},
- {set: notaryset, round: 11, chainID: 2}: {},
- {set: notaryset, round: 12, chainID: 0}: {},
- {set: notaryset, round: 12, chainID: 1}: {},
- {set: notaryset, round: 12, chainID: 2}: {},
- {set: dkgset, round: 10}: {},
- {set: dkgset, round: 12}: {},
+ {set: notaryset, round: 10}: {},
+ {set: notaryset, round: 11}: {},
+ {set: notaryset, round: 12}: {},
+ {set: dkgset, round: 10}: {},
+ {set: dkgset, round: 12}: {},
}
if !reflect.DeepEqual(ps.directConn, expectedDirectConn) {
@@ -152,9 +106,6 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
}
expectedGroupConn := []peerLabel{
- {set: notaryset, round: 10, chainID: 1},
- {set: notaryset, round: 10, chainID: 2},
- {set: notaryset, round: 11, chainID: 1},
{set: dkgset, round: 11},
}
@@ -196,21 +147,11 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
ps.ForgetConnection(11)
expectedlabel2Nodes = map[peerLabel]map[string]*enode.Node{
- {set: notaryset, round: 12, chainID: 0}: {
+ {set: notaryset, round: 12}: {
self.ID().String(): self,
nodes[3].ID().String(): nodes[3],
nodes[5].ID().String(): nodes[5],
},
- {set: notaryset, round: 12, chainID: 1}: {
- self.ID().String(): self,
- nodes[7].ID().String(): nodes[7],
- nodes[8].ID().String(): nodes[8],
- },
- {set: notaryset, round: 12, chainID: 2}: {
- self.ID().String(): self,
- nodes[2].ID().String(): nodes[2],
- nodes[6].ID().String(): nodes[6],
- },
{set: dkgset, round: 12}: {
self.ID().String(): self,
nodes[3].ID().String(): nodes[3],
@@ -223,10 +164,8 @@ func TestPeerSetBuildAndForgetConn(t *testing.T) {
}
expectedDirectConn = map[peerLabel]struct{}{
- {set: notaryset, round: 12, chainID: 0}: {},
- {set: notaryset, round: 12, chainID: 1}: {},
- {set: notaryset, round: 12, chainID: 2}: {},
- {set: dkgset, round: 12}: {},
+ {set: notaryset, round: 12}: {},
+ {set: dkgset, round: 12}: {},
}
if !reflect.DeepEqual(ps.directConn, expectedDirectConn) {
diff --git a/dex/protocol.go b/dex/protocol.go
index 6ee02959a..0e3f50eba 100644
--- a/dex/protocol.go
+++ b/dex/protocol.go
@@ -152,11 +152,9 @@ type txPool interface {
type governance interface {
GetRoundHeight(uint64) uint64
- GetNumChains(uint64) uint32
-
LenCRS() uint64
- NotarySet(uint64, uint32) (map[string]struct{}, error)
+ NotarySet(uint64) (map[string]struct{}, error)
DKGSet(uint64) (map[string]struct{}, error)
}
diff --git a/dex/protocol_test.go b/dex/protocol_test.go
index aa06d7293..fb414613e 100644
--- a/dex/protocol_test.go
+++ b/dex/protocol_test.go
@@ -327,15 +327,11 @@ func TestRecvLatticeBlocks(t *testing.T) {
ParentHash: coreCommon.Hash{1, 1, 1, 1, 1},
Hash: coreCommon.Hash{2, 2, 2, 2, 2},
Position: coreTypes.Position{
- ChainID: 11,
- Round: 12,
- Height: 13,
+ Round: 12,
+ Height: 13,
},
Timestamp: time.Now().UTC(),
- Acks: coreCommon.NewSortedHashes(coreCommon.Hashes([]coreCommon.Hash{
- {101}, {100}, {102},
- })),
- Payload: []byte{3, 3, 3, 3, 3},
+ Payload: []byte{3, 3, 3, 3, 3},
Witness: coreTypes.Witness{
Height: 13,
Data: []byte{4, 4, 4, 4, 4},
@@ -382,15 +378,11 @@ func TestSendLatticeBlocks(t *testing.T) {
ParentHash: coreCommon.Hash{1, 1, 1, 1, 1},
Hash: coreCommon.Hash{2, 2, 2, 2, 2},
Position: coreTypes.Position{
- ChainID: 11,
- Round: 12,
- Height: 13,
+ Round: 12,
+ Height: 13,
},
Timestamp: time.Now().UTC(),
- Acks: coreCommon.NewSortedHashes(coreCommon.Hashes([]coreCommon.Hash{
- {101}, {100}, {102},
- })),
- Payload: []byte{3, 3, 3, 3, 3},
+ Payload: []byte{3, 3, 3, 3, 3},
Witness: coreTypes.Witness{
Height: 13,
Data: []byte{4, 4, 4, 4, 4},
@@ -440,9 +432,8 @@ func TestRecvVotes(t *testing.T) {
ProposerID: coreTypes.NodeID{coreCommon.Hash{1, 2, 3}},
Period: 10,
Position: coreTypes.Position{
- ChainID: 11,
- Round: 12,
- Height: 13,
+ Round: 12,
+ Height: 13,
},
},
Signature: coreCrypto.Signature{
@@ -477,9 +468,8 @@ func TestSendVotes(t *testing.T) {
ProposerID: coreTypes.NodeID{coreCommon.Hash{1, 2, 3}},
Period: 10,
Position: coreTypes.Position{
- ChainID: 1,
- Round: 10,
- Height: 13,
+ Round: 10,
+ Height: 13,
},
},
Signature: coreCrypto.Signature{
@@ -528,11 +518,7 @@ func TestSendVotes(t *testing.T) {
isReceiver bool
}{
{
- label: &peerLabel{set: notaryset, chainID: 1, round: 10},
- isReceiver: true,
- },
- {
- label: &peerLabel{set: notaryset, chainID: 1, round: 10},
+ label: &peerLabel{set: notaryset, round: 10},
isReceiver: true,
},
{
@@ -540,15 +526,11 @@ func TestSendVotes(t *testing.T) {
isReceiver: false,
},
{
- label: &peerLabel{set: notaryset, chainID: 1, round: 11},
+ label: &peerLabel{set: notaryset, round: 11},
isReceiver: false,
},
{
- label: &peerLabel{set: notaryset, chainID: 2, round: 10},
- isReceiver: false,
- },
- {
- label: &peerLabel{set: dkgset, chainID: 1, round: 10},
+ label: &peerLabel{set: dkgset, round: 10},
isReceiver: false,
},
}
@@ -678,9 +660,8 @@ func TestRecvAgreement(t *testing.T) {
ProposerID: coreTypes.NodeID{coreCommon.Hash{1, 2, 3}},
Period: 10,
Position: coreTypes.Position{
- ChainID: 1,
- Round: 10,
- Height: 13,
+ Round: 10,
+ Height: 13,
},
},
Signature: coreCrypto.Signature{
@@ -723,9 +704,8 @@ func TestSendAgreement(t *testing.T) {
ProposerID: coreTypes.NodeID{coreCommon.Hash{1, 2, 3}},
Period: 10,
Position: coreTypes.Position{
- ChainID: 1,
- Round: 10,
- Height: 13,
+ Round: 10,
+ Height: 13,
},
},
Signature: coreCrypto.Signature{
@@ -769,9 +749,8 @@ func TestRecvRandomnesses(t *testing.T) {
randomness := coreTypes.BlockRandomnessResult{
BlockHash: coreCommon.Hash{8, 8, 8},
Position: coreTypes.Position{
- ChainID: 1,
- Round: 10,
- Height: 13,
+ Round: 10,
+ Height: 13,
},
Randomness: []byte{7, 7, 7, 7},
}
@@ -802,9 +781,8 @@ func TestSendRandomnesses(t *testing.T) {
randomness := coreTypes.BlockRandomnessResult{
BlockHash: coreCommon.Hash{8, 8, 8},
Position: coreTypes.Position{
- ChainID: 1,
- Round: 10,
- Height: 13,
+ Round: 10,
+ Height: 13,
},
Randomness: []byte{7, 7, 7, 7},
}
diff --git a/params/config.go b/params/config.go
index 8e20a15a4..33b9a5ec2 100644
--- a/params/config.go
+++ b/params/config.go
@@ -149,7 +149,7 @@ var (
LambdaDKG: 10000,
NotarySetSize: 4,
DKGSetSize: 4,
- RoundLength: 1200000,
+ RoundLength: 1200,
MinBlockInterval: 1000,
FineValues: []*big.Int{
new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e4)),
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/common/event.go b/vendor/github.com/dexon-foundation/dexon-consensus/common/event.go
index 6c6bf49d4..4e4e23bf3 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/common/event.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/common/event.go
@@ -20,26 +20,25 @@ package common
import (
"container/heap"
"sync"
- "time"
)
-type timeEventFn func(time.Time)
+type heightEventFn func(uint64)
-type timeEvent struct {
- t time.Time
- fn timeEventFn
+type heightEvent struct {
+ h uint64
+ fn heightEventFn
}
-// timeEvents implements a Min-Heap structure.
-type timeEvents []timeEvent
+// heightEvents implements a Min-Heap structure.
+type heightEvents []heightEvent
-func (h timeEvents) Len() int { return len(h) }
-func (h timeEvents) Less(i, j int) bool { return h[i].t.Before(h[j].t) }
-func (h timeEvents) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
-func (h *timeEvents) Push(x interface{}) {
- *h = append(*h, x.(timeEvent))
+func (h heightEvents) Len() int { return len(h) }
+func (h heightEvents) Less(i, j int) bool { return h[i].h < h[j].h }
+func (h heightEvents) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
+func (h *heightEvents) Push(x interface{}) {
+ *h = append(*h, x.(heightEvent))
}
-func (h *timeEvents) Pop() interface{} {
+func (h *heightEvents) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
@@ -49,54 +48,54 @@ func (h *timeEvents) Pop() interface{} {
// Event implements the Observer pattern.
type Event struct {
- timeEvents timeEvents
- timeEventsLock sync.Mutex
+ heightEvents heightEvents
+ heightEventsLock sync.Mutex
}
// NewEvent creates a new event instance.
func NewEvent() *Event {
- te := timeEvents{}
- heap.Init(&te)
+ he := heightEvents{}
+ heap.Init(&he)
return &Event{
- timeEvents: te,
+ heightEvents: he,
}
}
-// RegisterTime to get notified on and after specific time.
-func (e *Event) RegisterTime(t time.Time, fn timeEventFn) {
- e.timeEventsLock.Lock()
- defer e.timeEventsLock.Unlock()
- heap.Push(&e.timeEvents, timeEvent{
- t: t,
+// RegisterHeight to get notified on a specific height.
+func (e *Event) RegisterHeight(h uint64, fn heightEventFn) {
+ e.heightEventsLock.Lock()
+ defer e.heightEventsLock.Unlock()
+ heap.Push(&e.heightEvents, heightEvent{
+ h: h,
fn: fn,
})
}
-// NotifyTime and trigger function callback.
-func (e *Event) NotifyTime(t time.Time) {
- fns := func() (fns []timeEventFn) {
- e.timeEventsLock.Lock()
- defer e.timeEventsLock.Unlock()
- if len(e.timeEvents) == 0 {
+// NotifyHeight and trigger function callback.
+func (e *Event) NotifyHeight(h uint64) {
+ fns := func() (fns []heightEventFn) {
+ e.heightEventsLock.Lock()
+ defer e.heightEventsLock.Unlock()
+ if len(e.heightEvents) == 0 {
return
}
- for !t.Before(e.timeEvents[0].t) {
- te := heap.Pop(&e.timeEvents).(timeEvent)
- fns = append(fns, te.fn)
- if len(e.timeEvents) == 0 {
+ for h >= e.heightEvents[0].h {
+ he := heap.Pop(&e.heightEvents).(heightEvent)
+ fns = append(fns, he.fn)
+ if len(e.heightEvents) == 0 {
return
}
}
return
}()
for _, fn := range fns {
- fn(t)
+ fn(h)
}
}
// Reset clears all pending event
func (e *Event) Reset() {
- e.timeEventsLock.Lock()
- defer e.timeEventsLock.Unlock()
- e.timeEvents = timeEvents{}
+ e.heightEventsLock.Lock()
+ defer e.heightEventsLock.Unlock()
+ e.heightEvents = heightEvents{}
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
index 5f5b9ae5f..88cc432ff 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
@@ -65,13 +65,29 @@ func genValidLeader(
}
type agreementMgrConfig struct {
- beginTime time.Time
- roundInterval time.Duration
+ roundBasedConfig
+
notarySetSize uint32
lambdaBA time.Duration
crs common.Hash
}
+func (c *agreementMgrConfig) from(
+ round uint64, config *types.Config, crs common.Hash) {
+ c.notarySetSize = config.NotarySetSize
+ c.lambdaBA = config.LambdaBA
+ c.crs = crs
+ c.setupRoundBasedFields(round, config)
+}
+
+func newAgreementMgrConfig(prev agreementMgrConfig, config *types.Config,
+ crs common.Hash) (c agreementMgrConfig) {
+ c = agreementMgrConfig{}
+ c.from(prev.roundID+1, config, crs)
+ c.setRoundBeginHeight(prev.roundEndHeight)
+ return
+}
+
type baRoundSetting struct {
notarySet map[types.NodeID]struct{}
agr *agreement
@@ -92,9 +108,8 @@ type agreementMgr struct {
signer *utils.Signer
bcModule *blockChain
ctx context.Context
- lastEndTime time.Time
initRound uint64
- configs []*agreementMgrConfig
+ configs []agreementMgrConfig
baModule *agreement
processedBAResult map[types.Position]struct{}
voteFilter *utils.VoteFilter
@@ -104,8 +119,8 @@ type agreementMgr struct {
}
func newAgreementMgr(con *Consensus, initRound uint64,
- initRoundBeginTime time.Time) *agreementMgr {
- return &agreementMgr{
+ initConfig agreementMgrConfig) (mgr *agreementMgr, err error) {
+ mgr = &agreementMgr{
con: con,
ID: con.ID,
app: con.app,
@@ -117,9 +132,33 @@ func newAgreementMgr(con *Consensus, initRound uint64,
bcModule: con.bcModule,
ctx: con.ctx,
initRound: initRound,
- lastEndTime: initRoundBeginTime,
processedBAResult: make(map[types.Position]struct{}, maxResultCache),
+ configs: []agreementMgrConfig{initConfig},
+ voteFilter: utils.NewVoteFilter(),
}
+ recv := &consensusBAReceiver{
+ consensus: con,
+ restartNotary: make(chan types.Position, 1),
+ roundValue: &atomic.Value{},
+ }
+ recv.roundValue.Store(uint64(0))
+ agr := newAgreement(
+ mgr.ID,
+ recv,
+ newLeaderSelector(genValidLeader(mgr), mgr.logger),
+ mgr.signer,
+ mgr.logger)
+ // Hacky way to initialize first notarySet.
+ nodes, err := mgr.cache.GetNodeSet(initRound)
+ if err != nil {
+ return
+ }
+ agr.notarySet = nodes.GetSubSet(
+ int(initConfig.notarySetSize), types.NewNotarySetTarget(initConfig.crs))
+ // Hacky way to make agreement module self contained.
+ recv.agreementModule = agr
+ mgr.baModule = agr
+ return
}
func (mgr *agreementMgr) run() {
@@ -136,7 +175,7 @@ func (mgr *agreementMgr) run() {
}()
}
-func (mgr *agreementMgr) getConfig(round uint64) *agreementMgrConfig {
+func (mgr *agreementMgr) config(round uint64) *agreementMgrConfig {
mgr.lock.RLock()
defer mgr.lock.RUnlock()
if round < mgr.initRound {
@@ -146,7 +185,7 @@ func (mgr *agreementMgr) getConfig(round uint64) *agreementMgrConfig {
if roundIndex >= uint64(len(mgr.configs)) {
return nil
}
- return mgr.configs[roundIndex]
+ return &mgr.configs[roundIndex]
}
func (mgr *agreementMgr) appendConfig(
@@ -156,52 +195,12 @@ func (mgr *agreementMgr) appendConfig(
if round != uint64(len(mgr.configs))+mgr.initRound {
return ErrRoundNotIncreasing
}
- newConfig := &agreementMgrConfig{
- beginTime: mgr.lastEndTime,
- roundInterval: config.RoundInterval,
- notarySetSize: config.NotarySetSize,
- lambdaBA: config.LambdaBA,
- crs: crs,
- }
- mgr.configs = append(mgr.configs, newConfig)
- mgr.lastEndTime = mgr.lastEndTime.Add(config.RoundInterval)
- // Prepare modules.
- if mgr.baModule != nil {
- return nil
- }
- recv := &consensusBAReceiver{
- consensus: mgr.con,
- restartNotary: make(chan types.Position, 1),
- roundValue: &atomic.Value{},
- }
- recv.roundValue.Store(uint64(0))
- agrModule := newAgreement(
- mgr.con.ID,
- recv,
- newLeaderSelector(genValidLeader(mgr), mgr.logger),
- mgr.signer,
- mgr.logger)
- // Hacky way to initialize first notarySet.
- nodes, err := mgr.cache.GetNodeSet(round)
- if err != nil {
- return err
- }
- agrModule.notarySet = nodes.GetSubSet(
- int(config.NotarySetSize), types.NewNotarySetTarget(crs))
- // Hacky way to make agreement module self contained.
- recv.agreementModule = agrModule
- mgr.baModule = agrModule
- mgr.voteFilter = utils.NewVoteFilter()
+ mgr.configs = append(mgr.configs, newAgreementMgrConfig(
+ mgr.configs[len(mgr.configs)-1], config, crs))
return nil
}
func (mgr *agreementMgr) processVote(v *types.Vote) (err error) {
- if v.Position.ChainID > 0 {
- mgr.logger.Error("Process vote for unknown chain to BA",
- "position", v.Position,
- "initRound", mgr.initRound)
- return utils.ErrInvalidChainID
- }
if mgr.voteFilter.Filter(v) {
return nil
}
@@ -212,13 +211,6 @@ func (mgr *agreementMgr) processVote(v *types.Vote) (err error) {
}
func (mgr *agreementMgr) processBlock(b *types.Block) error {
- if b.Position.ChainID > 0 {
- mgr.logger.Error("Process block for unknown chain to BA",
- "position", b.Position,
- "baRound", len(mgr.configs),
- "initRound", mgr.initRound)
- return utils.ErrInvalidChainID
- }
return mgr.baModule.processBlock(b)
}
@@ -247,13 +239,6 @@ func (mgr *agreementMgr) untouchAgreementResult(
func (mgr *agreementMgr) processAgreementResult(
result *types.AgreementResult) error {
- if result.Position.ChainID > 0 {
- mgr.logger.Error("Process unknown result for unknown chain to BA",
- "position", result.Position,
- "baRound", len(mgr.configs),
- "initRound", mgr.initRound)
- return utils.ErrInvalidChainID
- }
aID := mgr.baModule.agreementID()
if isStop(aID) {
return nil
@@ -310,13 +295,12 @@ func (mgr *agreementMgr) runBA(initRound uint64) {
var (
currentRound uint64
nextRound = initRound
+ curConfig = mgr.config(initRound)
setting = baRoundSetting{
agr: mgr.baModule,
recv: mgr.baModule.data.recv.(*consensusBAReceiver),
}
- roundBeginTime time.Time
- roundEndTime time.Time
- tickDuration time.Duration
+ tickDuration time.Duration
)
// Check if this routine needs to awake in this round and prepare essential
@@ -327,24 +311,20 @@ func (mgr *agreementMgr) runBA(initRound uint64) {
nextRound++
}()
// Wait until the configuartion for next round is ready.
- var config *agreementMgrConfig
for {
- if config = mgr.getConfig(nextRound); config != nil {
+ if curConfig = mgr.config(nextRound); curConfig != nil {
break
} else {
mgr.logger.Debug("round is not ready", "round", nextRound)
time.Sleep(1 * time.Second)
}
}
- // Set next checkpoint.
- roundBeginTime = config.beginTime
- roundEndTime = config.beginTime.Add(config.roundInterval)
// Check if this node in notary set of this chain in this round.
- notarySet, err := mgr.cache.GetNotarySet(nextRound, 0)
+ notarySet, err := mgr.cache.GetNotarySet(nextRound)
if err != nil {
panic(err)
}
- setting.crs = config.crs
+ setting.crs = curConfig.crs
setting.notarySet = notarySet
_, isNotary = setting.notarySet[mgr.ID]
if isNotary {
@@ -357,12 +337,12 @@ func (mgr *agreementMgr) runBA(initRound uint64) {
"round", nextRound)
}
// Setup ticker
- if tickDuration != config.lambdaBA {
+ if tickDuration != curConfig.lambdaBA {
if setting.ticker != nil {
setting.ticker.Stop()
}
setting.ticker = newTicker(mgr.gov, nextRound, TickerBA)
- tickDuration = config.lambdaBA
+ tickDuration = curConfig.lambdaBA
}
return
}
@@ -373,29 +353,13 @@ Loop:
break Loop
default:
}
- now := time.Now().UTC()
setting.recv.isNotary = checkRound()
- // Sleep until round begin. Here a biased round begin time would be
- // used instead of the one in config. The reason it to disperse the load
- // of fullnodes to verify confirmed blocks from each chain.
- if now.Before(pickBiasedTime(roundBeginTime, 4*tickDuration)) {
- select {
- case <-mgr.ctx.Done():
- break Loop
- case <-time.After(roundBeginTime.Sub(now)):
- }
- // Clean the tick channel after awake: the tick would be queued in
- // channel, thus the first few ticks would not tick on expected
- // interval.
- <-setting.ticker.Tick()
- <-setting.ticker.Tick()
- }
// Run BA for this round.
setting.recv.roundValue.Store(currentRound)
- setting.recv.changeNotaryTime = roundEndTime
+ setting.recv.changeNotaryHeight = curConfig.roundEndHeight
setting.recv.restartNotary <- types.Position{
- Round: setting.recv.round(),
- ChainID: math.MaxUint32,
+ Round: setting.recv.round(),
+ Height: math.MaxUint64,
}
mgr.voteFilter = utils.NewVoteFilter()
if err := mgr.baRoutineForOneRound(&setting); err != nil {
@@ -450,7 +414,7 @@ func (mgr *agreementMgr) baRoutineForOneRound(
if isStop(oldPos) && nextHeight == 0 {
break
}
- if isStop(restartPos) && nextHeight == 0 {
+ if isStop(restartPos) {
break
}
if nextHeight > restartPos.Height {
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
index 579cea8c3..43fddd0a0 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
@@ -254,12 +254,12 @@ func (a *agreement) restart(
func (a *agreement) stop() {
a.restart(make(map[types.NodeID]struct{}), types.Position{
- ChainID: math.MaxUint32,
+ Height: math.MaxUint64,
}, types.NodeID{}, common.Hash{})
}
func isStop(aID types.Position) bool {
- return aID.ChainID == math.MaxUint32
+ return aID.Height == math.MaxUint64
}
// clocks returns how many time this state is required.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
index d1aa644a5..03c8561c5 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
@@ -110,7 +110,7 @@ func newBlockChainConfig(prev blockChainConfig, config *types.Config) (
c blockChainConfig) {
c = blockChainConfig{}
c.fromConfig(prev.roundID+1, config)
- c.setRoundBeginTime(prev.roundEndTime)
+ c.setRoundBeginHeight(prev.roundEndHeight)
return
}
@@ -131,9 +131,10 @@ type blockChain struct {
configs []blockChainConfig
pendingBlocks pendingBlockRecords
confirmedBlocks types.BlocksByPosition
+ dMoment time.Time
}
-func newBlockChain(nID types.NodeID, initBlock *types.Block,
+func newBlockChain(nID types.NodeID, dMoment time.Time, initBlock *types.Block,
initConfig blockChainConfig, app Application, vGetter tsigVerifierGetter,
signer *utils.Signer, logger common.Logger) *blockChain {
if initBlock != nil {
@@ -156,6 +157,7 @@ func newBlockChain(nID types.NodeID, initBlock *types.Block,
app: app,
logger: logger,
configs: []blockChainConfig{initConfig},
+ dMoment: dMoment,
pendingRandomnesses: make(
map[types.Position]*types.BlockRandomnessResult),
}
@@ -186,7 +188,7 @@ func (bc *blockChain) extractBlocks() (ret []*types.Block) {
defer bc.lock.Unlock()
for len(bc.confirmedBlocks) > 0 {
c := bc.confirmedBlocks[0]
- if c.Position.Round > 0 && len(c.Finalization.Randomness) == 0 {
+ if c.Position.Round >= DKGDelayRound && len(c.Finalization.Randomness) == 0 {
break
}
c, bc.confirmedBlocks = bc.confirmedBlocks[0], bc.confirmedBlocks[1:]
@@ -203,9 +205,6 @@ func (bc *blockChain) extractBlocks() (ret []*types.Block) {
}
func (bc *blockChain) sanityCheck(b *types.Block) error {
- if b.Position.ChainID != 0 {
- panic(fmt.Errorf("attempt to process block from non-zero chainID"))
- }
if b.IsEmpty() {
panic(fmt.Errorf("pass empty block to sanity check: %s", b))
}
@@ -228,7 +227,7 @@ func (bc *blockChain) sanityCheck(b *types.Block) error {
}
return ErrInvalidBlockHeight
}
- tipConfig := bc.getTipConfig()
+ tipConfig := bc.tipConfig()
if tipConfig.isLastBlock(bc.lastConfirmed) {
if b.Position.Round != bc.lastConfirmed.Position.Round+1 {
return ErrRoundNotSwitch
@@ -250,9 +249,6 @@ func (bc *blockChain) sanityCheck(b *types.Block) error {
// addEmptyBlock is called when an empty block is confirmed by BA.
func (bc *blockChain) addEmptyBlock(position types.Position) (
*types.Block, error) {
- if position.ChainID != 0 {
- panic(fmt.Errorf("attempt to process block from non-zero chainID"))
- }
bc.lock.Lock()
defer bc.lock.Unlock()
add := func() *types.Block {
@@ -286,9 +282,6 @@ func (bc *blockChain) addEmptyBlock(position types.Position) (
// addBlock should be called when the block is confirmed by BA, we won't perform
// sanity check against this block, it's ok to add block with skipping height.
func (bc *blockChain) addBlock(b *types.Block) error {
- if b.Position.ChainID != 0 {
- panic(fmt.Errorf("attempt to process block from non-zero chainID"))
- }
bc.lock.Lock()
defer bc.lock.Unlock()
confirmed := false
@@ -314,9 +307,6 @@ func (bc *blockChain) addBlock(b *types.Block) error {
}
func (bc *blockChain) addRandomness(r *types.BlockRandomnessResult) error {
- if r.Position.ChainID != 0 {
- panic(fmt.Errorf("attempt to process block from non-zero chainID"))
- }
if func() bool {
bc.lock.RLock()
defer bc.lock.RUnlock()
@@ -361,8 +351,8 @@ func (bc *blockChain) tipRound() uint64 {
if bc.lastConfirmed == nil {
return 0
}
- offset := uint64(0)
- if bc.lastConfirmed.Timestamp.After(bc.getTipConfig().roundEndTime) {
+ offset, tipConfig := uint64(0), bc.tipConfig()
+ if tipConfig.isLastBlock(bc.lastConfirmed) {
offset++
}
return bc.lastConfirmed.Position.Round + offset
@@ -392,7 +382,7 @@ func (bc *blockChain) nextBlock() (uint64, time.Time) {
// lastConfirmed block in the scenario of "nextBlock" method.
tip, config := bc.lastConfirmed, bc.configs[0]
if tip == nil {
- return 0, config.roundBeginTime
+ return 0, bc.dMoment
}
return tip.Position.Height + 1, tip.Timestamp.Add(config.minBlockInterval)
}
@@ -461,6 +451,11 @@ func (bc *blockChain) findPendingBlock(p types.Position) *types.Block {
func (bc *blockChain) addPendingBlockRecord(p pendingBlockRecord) {
if err := bc.pendingBlocks.insert(p); err != nil {
+ if err == ErrDuplicatedPendingBlock {
+ // TODO(mission): panic directly once our BA can confirm blocks
+ // uniquely and in sequence.
+ return
+ }
panic(err)
}
if p.block != nil {
@@ -507,7 +502,7 @@ func (bc *blockChain) purgeConfig() {
func (bc *blockChain) verifyRandomness(
blockHash common.Hash, round uint64, randomness []byte) (bool, error) {
- if round == 0 {
+ if round < DKGDelayRound {
return len(randomness) == 0, nil
}
v, ok, err := bc.vGetter.UpdateAndGet(round)
@@ -528,26 +523,31 @@ func (bc *blockChain) prepareBlock(position types.Position,
b = &types.Block{Position: position, Timestamp: proposeTime}
tip := bc.lastConfirmed
// Make sure we can propose a block at expected position for callers.
- expectedPosition := types.Position{}
if tip == nil {
// The case for genesis block.
- if !position.Equal(expectedPosition) {
+ if !position.Equal(types.Position{}) {
b, err = nil, ErrNotGenesisBlock
+ return
} else if empty {
- b.Timestamp = bc.configs[0].roundBeginTime
+ b.Timestamp = bc.dMoment
}
} else {
- expectedPosition.Height = tip.Position.Height + 1
- tipConfig := bc.getTipConfig()
- if tipConfig.isLastBlock(tip) {
- expectedPosition.Round = tip.Position.Round + 1
- } else {
- expectedPosition.Round = tip.Position.Round
- }
- if !expectedPosition.Equal(position) {
+ tipConfig := bc.tipConfig()
+ if tip.Position.Height+1 != position.Height {
b, err = nil, ErrNotFollowTipPosition
return
}
+ if tipConfig.isLastBlock(tip) {
+ if tip.Position.Round+1 != position.Round {
+ b, err = nil, ErrRoundNotSwitch
+ return
+ }
+ } else {
+ if tip.Position.Round != position.Round {
+ b, err = nil, ErrInvalidRoundID
+ return
+ }
+ }
b.ParentHash = tip.Hash
if !empty {
bc.logger.Debug("Calling Application.PreparePayload",
@@ -564,7 +564,6 @@ func (bc *blockChain) prepareBlock(position types.Position,
if !b.Timestamp.After(tip.Timestamp) {
b.Timestamp = tip.Timestamp.Add(tipConfig.minBlockInterval)
}
-
} else {
b.Witness.Height = tip.Witness.Height
b.Witness.Data = make([]byte, len(tip.Witness.Data))
@@ -585,7 +584,7 @@ func (bc *blockChain) prepareBlock(position types.Position,
return
}
-func (bc *blockChain) getTipConfig() blockChainConfig {
+func (bc *blockChain) tipConfig() blockChainConfig {
if bc.lastConfirmed == nil {
panic(fmt.Errorf("attempting to access config without tip"))
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
index f4c0a372d..370df72cf 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
@@ -58,12 +58,12 @@ var (
// consensusBAReceiver implements agreementReceiver.
type consensusBAReceiver struct {
// TODO(mission): consensus would be replaced by blockChain and network.
- consensus *Consensus
- agreementModule *agreement
- changeNotaryTime time.Time
- roundValue *atomic.Value
- isNotary bool
- restartNotary chan types.Position
+ consensus *Consensus
+ agreementModule *agreement
+ changeNotaryHeight uint64
+ roundValue *atomic.Value
+ isNotary bool
+ restartNotary chan types.Position
}
func (recv *consensusBAReceiver) round() uint64 {
@@ -241,10 +241,17 @@ CleanChannelLoop:
}
}
newPos := block.Position
- if block.Timestamp.After(recv.changeNotaryTime) {
+ if block.Position.Height+1 == recv.changeNotaryHeight {
newPos.Round++
recv.roundValue.Store(newPos.Round)
}
+ currentRound := recv.round()
+ if block.Position.Height > recv.changeNotaryHeight &&
+ block.Position.Round <= currentRound {
+ panic(fmt.Errorf(
+ "round not switch when confirmig: %s, %d, should switch at %d",
+ block, currentRound, recv.changeNotaryHeight))
+ }
recv.restartNotary <- newPos
}
@@ -383,7 +390,6 @@ type Consensus struct {
bcModule *blockChain
dMoment time.Time
nodeSetCache *utils.NodeSetCache
- round uint64
roundForNewConfig uint64
lock sync.RWMutex
ctx context.Context
@@ -412,7 +418,7 @@ func NewConsensus(
prv crypto.PrivateKey,
logger common.Logger) *Consensus {
return newConsensusForRound(
- nil, dMoment, app, gov, db, network, prv, logger, true)
+ nil, 0, dMoment, app, gov, db, network, prv, logger, true)
}
// NewConsensusForSimulation creates an instance of Consensus for simulation,
@@ -426,7 +432,7 @@ func NewConsensusForSimulation(
prv crypto.PrivateKey,
logger common.Logger) *Consensus {
return newConsensusForRound(
- nil, dMoment, app, gov, db, network, prv, logger, false)
+ nil, 0, dMoment, app, gov, db, network, prv, logger, false)
}
// NewConsensusFromSyncer constructs an Consensus instance from information
@@ -440,7 +446,8 @@ func NewConsensusForSimulation(
// their positions, in ascending order.
func NewConsensusFromSyncer(
initBlock *types.Block,
- initRoundBeginTime time.Time,
+ initRoundBeginHeight uint64,
+ dMoment time.Time,
app Application,
gov Governance,
db db.Database,
@@ -451,8 +458,8 @@ func NewConsensusFromSyncer(
cachedMessages []interface{},
logger common.Logger) (*Consensus, error) {
// Setup Consensus instance.
- con := newConsensusForRound(initBlock, initRoundBeginTime, app, gov, db,
- networkModule, prv, logger, true)
+ con := newConsensusForRound(initBlock, initRoundBeginHeight, dMoment, app,
+ gov, db, networkModule, prv, logger, true)
// Launch a dummy receiver before we start receiving from network module.
con.dummyMsgBuffer = cachedMessages
con.dummyCancel, con.dummyFinished = utils.LaunchDummyReceiver(
@@ -486,9 +493,11 @@ func NewConsensusFromSyncer(
}
// newConsensusForRound creates a Consensus instance.
+// TODO(mission): remove dMoment, it's no longer one part of consensus.
func newConsensusForRound(
initBlock *types.Block,
- initRoundBeginTime time.Time,
+ initRoundBeginHeight uint64,
+ dMoment time.Time,
app Application,
gov Governance,
db db.Database,
@@ -511,6 +520,7 @@ func newConsensusForRound(
initRound = initBlock.Position.Round
}
initConfig := utils.GetConfigWithPanic(gov, initRound, logger)
+ initCRS := utils.GetCRSWithPanic(gov, initRound, logger)
// Init configuration chain.
ID := types.NewNodeID(prv.PublicKey())
recv := &consensusDKGReceiver{
@@ -529,8 +539,8 @@ func newConsensusForRound(
}
bcConfig := blockChainConfig{}
bcConfig.fromConfig(initRound, initConfig)
- bcConfig.setRoundBeginTime(initRoundBeginTime)
- bcModule := newBlockChain(ID, initBlock, bcConfig, appModule,
+ bcConfig.setRoundBeginHeight(initRoundBeginHeight)
+ bcModule := newBlockChain(ID, dMoment, initBlock, bcConfig, appModule,
NewTSigVerifierCache(gov, 7), signer, logger)
// Construct Consensus instance.
con := &Consensus{
@@ -544,7 +554,7 @@ func newConsensusForRound(
dkgReady: sync.NewCond(&sync.Mutex{}),
cfgModule: cfgModule,
bcModule: bcModule,
- dMoment: initRoundBeginTime,
+ dMoment: dMoment,
nodeSetCache: nodeSetCache,
signer: signer,
event: common.NewEvent(),
@@ -555,8 +565,15 @@ func newConsensusForRound(
processBlockChan: make(chan *types.Block, 1024),
}
con.ctx, con.ctxCancel = context.WithCancel(context.Background())
- con.baMgr = newAgreementMgr(con, initRound, initRoundBeginTime)
- if err := con.prepare(initBlock); err != nil {
+ baConfig := agreementMgrConfig{}
+ baConfig.from(initRound, initConfig, initCRS)
+ baConfig.setRoundBeginHeight(initRoundBeginHeight)
+ var err error
+ con.baMgr, err = newAgreementMgr(con, initRound, baConfig)
+ if err != nil {
+ panic(err)
+ }
+ if err = con.prepare(initRoundBeginHeight, initBlock); err != nil {
panic(err)
}
return con
@@ -566,53 +583,28 @@ func newConsensusForRound(
// 'initBlock' could be either:
// - nil
// - the last finalized block
-func (con *Consensus) prepare(initBlock *types.Block) (err error) {
+func (con *Consensus) prepare(
+ initRoundBeginHeight uint64, initBlock *types.Block) (err error) {
// The block past from full node should be delivered already or known by
// full node. We don't have to notify it.
initRound := uint64(0)
if initBlock != nil {
initRound = initBlock.Position.Round
}
+ // Setup blockChain module.
con.roundForNewConfig = initRound + 1
initConfig := utils.GetConfigWithPanic(con.gov, initRound, con.logger)
- // Setup context.
- con.logger.Debug("Calling Governance.CRS", "round", initRound)
- initCRS := con.gov.CRS(initRound)
- if (initCRS == common.Hash{}) {
- err = ErrCRSNotReady
- return
- }
- if err = con.baMgr.appendConfig(initRound, initConfig, initCRS); err != nil {
- return
- }
- // Setup blockChain module.
initPlusOneCfg := utils.GetConfigWithPanic(con.gov, initRound+1, con.logger)
if err = con.bcModule.appendConfig(initRound+1, initPlusOneCfg); err != nil {
return
}
if initRound == 0 {
- dkgSet, err := con.nodeSetCache.GetDKGSet(initRound)
- if err != nil {
- return err
- }
- if _, exist := dkgSet[con.ID]; exist {
- con.logger.Info("Selected as DKG set", "round", initRound)
- go func() {
- // Sleep until dMoment come.
- time.Sleep(con.dMoment.Sub(time.Now().UTC()))
- // Network is not stable upon starting. Wait some time to ensure first
- // DKG would success. Three is a magic number.
- time.Sleep(initConfig.MinBlockInterval * 3)
- con.cfgModule.registerDKG(initRound, getDKGThreshold(initConfig))
- con.event.RegisterTime(con.dMoment.Add(initConfig.RoundInterval/4),
- func(time.Time) {
- con.runDKG(initRound, initConfig)
- })
- }()
+ if DKGDelayRound == 0 {
+ panic("not implemented yet")
}
}
// Register events.
- con.initialRound(con.dMoment, initRound, initConfig)
+ con.initialRound(initRoundBeginHeight, initRound, initConfig)
return
}
@@ -672,18 +664,11 @@ func (con *Consensus) runDKG(round uint64, config *types.Config) {
}
con.dkgRunning = 1
go func() {
- startTime := time.Now().UTC()
defer func() {
con.dkgReady.L.Lock()
defer con.dkgReady.L.Unlock()
con.dkgReady.Broadcast()
con.dkgRunning = 2
- DKGTime := time.Now().Sub(startTime)
- if DKGTime.Nanoseconds() >=
- config.RoundInterval.Nanoseconds()/2 {
- con.logger.Warn("Your computer cannot finish DKG on time!",
- "nodeID", con.ID.String())
- }
}()
if err := con.cfgModule.runDKG(round); err != nil {
con.logger.Error("Failed to runDKG", "error", err)
@@ -739,25 +724,28 @@ func (con *Consensus) runCRS(round uint64) {
}
func (con *Consensus) initialRound(
- startTime time.Time, round uint64, config *types.Config) {
+ startHeight uint64, round uint64, config *types.Config) {
select {
case <-con.ctx.Done():
return
default:
}
- curDkgSet, err := con.nodeSetCache.GetDKGSet(round)
- if err != nil {
- con.logger.Error("Error getting DKG set", "round", round, "error", err)
- curDkgSet = make(map[types.NodeID]struct{})
- }
- // Initiate CRS routine.
- if _, exist := curDkgSet[con.ID]; exist {
- con.event.RegisterTime(startTime.Add(config.RoundInterval/2),
- func(time.Time) {
- go func() {
- con.runCRS(round)
- }()
- })
+ if round >= DKGDelayRound {
+ curDkgSet, err := con.nodeSetCache.GetDKGSet(round)
+ if err != nil {
+ con.logger.Error("Error getting DKG set", "round", round, "error", err)
+ curDkgSet = make(map[types.NodeID]struct{})
+ }
+ // Initiate CRS routine.
+ if _, exist := curDkgSet[con.ID]; exist {
+ con.event.RegisterHeight(
+ startHeight+config.RoundLength/2,
+ func(uint64) {
+ go func() {
+ con.runCRS(round)
+ }()
+ })
+ }
}
// checkCRS is a generator of checker to check if CRS for that round is
// ready or not.
@@ -774,76 +762,75 @@ func (con *Consensus) initialRound(
}
}
// Initiate BA modules.
- con.event.RegisterTime(
- startTime.Add(config.RoundInterval/2+config.LambdaDKG),
- func(time.Time) {
- go func(nextRound uint64) {
- if !checkWithCancel(
- con.ctx, 500*time.Millisecond, checkCRS(nextRound)) {
- con.logger.Debug("unable to prepare CRS for baMgr",
- "round", nextRound)
- return
- }
- // Notify BA for new round.
- nextConfig := utils.GetConfigWithPanic(
- con.gov, nextRound, con.logger)
- nextCRS := utils.GetCRSWithPanic(
- con.gov, nextRound, con.logger)
- con.logger.Info("appendConfig for baMgr", "round", nextRound)
- if err := con.baMgr.appendConfig(
- nextRound, nextConfig, nextCRS); err != nil {
- panic(err)
- }
- }(round + 1)
- })
+ con.event.RegisterHeight(startHeight+config.RoundLength/2, func(uint64) {
+ go func(nextRound uint64) {
+ if !checkWithCancel(
+ con.ctx, 500*time.Millisecond, checkCRS(nextRound)) {
+ con.logger.Debug("unable to prepare CRS for baMgr",
+ "round", nextRound)
+ return
+ }
+ // Notify BA for new round.
+ nextConfig := utils.GetConfigWithPanic(
+ con.gov, nextRound, con.logger)
+ nextCRS := utils.GetCRSWithPanic(
+ con.gov, nextRound, con.logger)
+ con.logger.Info("appendConfig for baMgr", "round", nextRound)
+ if err := con.baMgr.appendConfig(
+ nextRound, nextConfig, nextCRS); err != nil {
+ panic(err)
+ }
+ }(round + 1)
+ })
// Initiate DKG for this round.
- con.event.RegisterTime(startTime.Add(config.RoundInterval/2+config.LambdaDKG),
- func(time.Time) {
- go func(nextRound uint64) {
- // Normally, gov.CRS would return non-nil. Use this for in case of
- // unexpected network fluctuation and ensure the robustness.
- if !checkWithCancel(
- con.ctx, 500*time.Millisecond, checkCRS(nextRound)) {
- con.logger.Debug("unable to prepare CRS for DKG set",
- "round", nextRound)
- return
- }
- nextDkgSet, err := con.nodeSetCache.GetDKGSet(nextRound)
- if err != nil {
- con.logger.Error("Error getting DKG set",
- "round", nextRound,
- "error", err)
- return
- }
- if _, exist := nextDkgSet[con.ID]; !exist {
- return
- }
- con.logger.Info("Selected as DKG set", "round", nextRound)
- con.cfgModule.registerDKG(nextRound, getDKGThreshold(config))
- con.event.RegisterTime(
- startTime.Add(config.RoundInterval*2/3),
- func(time.Time) {
- func() {
- con.dkgReady.L.Lock()
- defer con.dkgReady.L.Unlock()
- con.dkgRunning = 0
- }()
- nextConfig := utils.GetConfigWithPanic(
- con.gov, nextRound, con.logger)
- con.runDKG(nextRound, nextConfig)
- })
- }(round + 1)
- })
+ con.event.RegisterHeight(startHeight+config.RoundLength/2, func(uint64) {
+ go func(nextRound uint64) {
+ if nextRound < DKGDelayRound {
+ con.logger.Info("Skip runDKG for round", "round", nextRound)
+ return
+ }
+ // Normally, gov.CRS would return non-nil. Use this for in case of
+ // unexpected network fluctuation and ensure the robustness.
+ if !checkWithCancel(
+ con.ctx, 500*time.Millisecond, checkCRS(nextRound)) {
+ con.logger.Debug("unable to prepare CRS for DKG set",
+ "round", nextRound)
+ return
+ }
+ nextDkgSet, err := con.nodeSetCache.GetDKGSet(nextRound)
+ if err != nil {
+ con.logger.Error("Error getting DKG set",
+ "round", nextRound,
+ "error", err)
+ return
+ }
+ if _, exist := nextDkgSet[con.ID]; !exist {
+ return
+ }
+ con.logger.Info("Selected as DKG set", "round", nextRound)
+ con.cfgModule.registerDKG(nextRound, getDKGThreshold(config))
+ con.event.RegisterHeight(startHeight+config.RoundLength*2/3,
+ func(uint64) {
+ func() {
+ con.dkgReady.L.Lock()
+ defer con.dkgReady.L.Unlock()
+ con.dkgRunning = 0
+ }()
+ nextConfig := utils.GetConfigWithPanic(
+ con.gov, nextRound, con.logger)
+ con.runDKG(nextRound, nextConfig)
+ })
+ }(round + 1)
+ })
// Prepare blockChain module for next round and next "initialRound" routine.
- con.event.RegisterTime(startTime.Add(config.RoundInterval),
- func(time.Time) {
- // Change round.
- // Get configuration for next round.
- nextRound := round + 1
- nextConfig := utils.GetConfigWithPanic(con.gov, nextRound, con.logger)
- con.initialRound(
- startTime.Add(config.RoundInterval), nextRound, nextConfig)
- })
+ con.event.RegisterHeight(startHeight+config.RoundLength, func(uint64) {
+ // Change round.
+ // Get configuration for next round.
+ nextRound := round + 1
+ nextConfig := utils.GetConfigWithPanic(con.gov, nextRound, con.logger)
+ con.initialRound(
+ startHeight+config.RoundLength, nextRound, nextConfig)
+ })
}
// Stop the Consensus core.
@@ -1194,7 +1181,7 @@ func (con *Consensus) deliverFinalizedBlocksWithoutLock() (err error) {
"pending", con.bcModule.lastPendingBlock())
for _, b := range deliveredBlocks {
con.deliverBlock(b)
- go con.event.NotifyTime(b.Finalization.Timestamp)
+ go con.event.NotifyHeight(b.Finalization.Height)
}
return
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/constant.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/constant.go
index 563a321f5..f80e1b9d8 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/constant.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/constant.go
@@ -17,9 +17,21 @@
package core
+import "github.com/dexon-foundation/dexon-consensus/core/utils"
+
// ConfigRoundShift refers to the difference between block's round and config
// round derived from its state.
//
// For example, when round shift is 2, a block in round 0 should derive config
// for round 2.
const ConfigRoundShift uint64 = 2
+
+// DKGDelayRound refers to the round that first DKG is run.
+//
+// For example, when delay round is 1, new DKG will run at round 1. Round 0 will
+// have neither DKG nor CRS.
+const DKGDelayRound uint64 = 1
+
+func init() {
+ utils.SetDKGDelayRound(DKGDelayRound)
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
index 3879e36a5..b7e000ae6 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go
@@ -143,6 +143,12 @@ type Governance interface {
// ReportForkBlock reports a node for forking blocks.
ReportForkBlock(block1, block2 *types.Block)
+
+ // ResetDKG resets latest DKG data and propose new CRS.
+ ResetDKG(newSignedCRS []byte)
+
+ // DKGResetCount returns the reset count for DKG of given round.
+ DKGResetCount(round uint64) uint64
}
// Ticker define the capability to tick by interval.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/round-based-config.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/round-based-config.go
index 67779a63c..4f3a4cbf9 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/round-based-config.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/round-based-config.go
@@ -18,35 +18,34 @@
package core
import (
- "time"
+ "fmt"
"github.com/dexon-foundation/dexon-consensus/core/types"
)
type roundBasedConfig struct {
- roundID uint64
-
- // roundBeginTime is the beginning of round, as local time.
- roundBeginTime time.Time
- roundInterval time.Duration
-
- // roundEndTime is a cache for begin + interval.
- roundEndTime time.Time
+ roundID uint64
+ roundBeginHeight uint64
+ roundEndHeight uint64
+ roundInterval uint64
}
func (config *roundBasedConfig) setupRoundBasedFields(
roundID uint64, cfg *types.Config) {
config.roundID = roundID
- config.roundInterval = cfg.RoundInterval
+ config.roundInterval = cfg.RoundLength
}
-func (config *roundBasedConfig) setRoundBeginTime(begin time.Time) {
- config.roundBeginTime = begin
- config.roundEndTime = begin.Add(config.roundInterval)
+func (config *roundBasedConfig) setRoundBeginHeight(begin uint64) {
+ config.roundBeginHeight = begin
+ config.roundEndHeight = begin + config.roundInterval
}
// isLastBlock checks if a block is the last block of this round.
func (config *roundBasedConfig) isLastBlock(b *types.Block) bool {
- return b.Position.Round == config.roundID &&
- b.Timestamp.After(config.roundEndTime)
+ if b.Position.Round != config.roundID {
+ panic(fmt.Errorf("attempt to compare by different round: %s, %d",
+ b, config.roundID))
+ }
+ return b.Position.Height+1 == config.roundEndHeight
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
index acc4f1c6c..9f1abcaf5 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go
@@ -160,8 +160,10 @@ func (a *agreement) processNewCRS(round uint64) {
if round <= a.latestCRSRound {
return
}
+ prevRound := a.latestCRSRound + 1
+ a.latestCRSRound = round
// Verify all pending results.
- for r := a.latestCRSRound + 1; r <= round; r++ {
+ for r := prevRound; r <= a.latestCRSRound; r++ {
pendingsForRound := a.pendings[r]
if pendingsForRound == nil {
continue
@@ -169,7 +171,9 @@ func (a *agreement) processNewCRS(round uint64) {
delete(a.pendings, r)
for _, res := range pendingsForRound {
if err := core.VerifyAgreementResult(res, a.cache); err != nil {
- a.logger.Error("invalid agreement result", "result", res)
+ a.logger.Error("invalid agreement result",
+ "result", res,
+ "error", err)
continue
}
a.logger.Error("flush agreement result", "result", res)
@@ -177,7 +181,6 @@ func (a *agreement) processNewCRS(round uint64) {
break
}
}
- a.latestCRSRound = round
}
// confirm notifies consensus the confirmation of a block in BA.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
index 618d90e8c..7ba659f27 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/consensus.go
@@ -67,12 +67,13 @@ type Consensus struct {
blocks types.BlocksByPosition
agreementModule *agreement
configs []*types.Config
- roundBeginTimes []time.Time
+ roundBeginHeights []uint64
agreementRoundCut uint64
// lock for accessing all fields.
lock sync.RWMutex
duringBuffering bool
+ latestCRSRound uint64
moduleWaitGroup sync.WaitGroup
agreementWaitGroup sync.WaitGroup
pullChan chan common.Hash
@@ -109,7 +110,7 @@ func NewConsensus(
configs: []*types.Config{
utils.GetConfigWithPanic(gov, 0, logger),
},
- roundBeginTimes: []time.Time{dMoment},
+ roundBeginHeights: []uint64{0},
receiveChan: make(chan *types.Block, 1000),
pullChan: make(chan common.Hash, 1000),
randomnessResults: make(map[common.Hash]*types.BlockRandomnessResult),
@@ -280,7 +281,8 @@ func (con *Consensus) GetSyncedConsensus() (*core.Consensus, error) {
var err error
con.syncedConsensus, err = core.NewConsensusFromSyncer(
con.syncedLastBlock,
- con.roundBeginTimes[con.syncedLastBlock.Position.Round],
+ con.roundBeginHeights[con.syncedLastBlock.Position.Round],
+ con.dMoment,
con.app,
con.gov,
con.db,
@@ -336,7 +338,6 @@ func (con *Consensus) buildEmptyBlock(b *types.Block, parent *types.Block) {
b.Witness.Height = parent.Witness.Height
b.Witness.Data = make([]byte, len(parent.Witness.Data))
copy(b.Witness.Data, parent.Witness.Data)
- b.Acks = common.NewSortedHashes(common.Hashes{parent.Hash})
}
// setupConfigs is called by SyncBlocks with blocks from compaction chain. In
@@ -368,9 +369,9 @@ func (con *Consensus) setupConfigsUntilRound(round uint64) {
for r := uint64(len(con.configs)); r <= round; r++ {
cfg := utils.GetConfigWithPanic(con.gov, r, con.logger)
con.configs = append(con.configs, cfg)
- con.roundBeginTimes = append(
- con.roundBeginTimes,
- con.roundBeginTimes[r-1].Add(con.configs[r-1].RoundInterval))
+ con.roundBeginHeights = append(
+ con.roundBeginHeights,
+ con.roundBeginHeights[r-1]+con.configs[r-1].RoundLength)
}
}
@@ -416,6 +417,11 @@ func (con *Consensus) cacheRandomnessResult(r *types.BlockRandomnessResult) {
if len(con.blocks) > 0 && r.Position.Older(con.blocks[0].Position) {
return true
}
+ if r.Position.Round > con.latestCRSRound {
+ // We can't process randomness from rounds that its CRS is still
+ // unknown.
+ return true
+ }
_, exists := con.randomnessResults[r.BlockHash]
return exists
}() {
@@ -453,41 +459,22 @@ func (con *Consensus) startNetwork() {
con.moduleWaitGroup.Add(1)
go func() {
defer con.moduleWaitGroup.Done()
- Loop:
+ loop:
for {
select {
case val := <-con.network.ReceiveChan():
- var pos types.Position
switch v := val.(type) {
case *types.Block:
- pos = v.Position
case *types.AgreementResult:
- pos = v.Position
case *types.BlockRandomnessResult:
con.cacheRandomnessResult(v)
- continue Loop
+ continue loop
default:
- continue Loop
- }
- if func() bool {
- con.lock.RLock()
- defer con.lock.RUnlock()
- if pos.ChainID > 0 {
- // This error might be easily encountered when the
- // "latest" parameter of SyncBlocks is turned on too
- // early.
- con.logger.Error(
- "Unknown chainID message received (syncer)",
- "position", pos,
- )
- return false
- }
- return true
- }() {
- con.agreementModule.inputChan <- val
+ continue loop
}
+ con.agreementModule.inputChan <- val
case <-con.ctx.Done():
- return
+ break loop
}
}
}()
@@ -505,6 +492,11 @@ func (con *Consensus) startCRSMonitor() {
}
con.logger.Debug("CRS is ready", "round", round)
lastNotifiedRound = round
+ func() {
+ con.lock.Lock()
+ defer con.lock.Unlock()
+ con.latestCRSRound = round
+ }()
for func() bool {
con.lock.RLock()
defer con.lock.RUnlock()
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/ticker.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/ticker.go
index ffd5ab45d..636fb8c49 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/ticker.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/ticker.go
@@ -18,6 +18,9 @@
package core
import (
+ "context"
+ "fmt"
+ "sync"
"time"
"github.com/dexon-foundation/dexon-consensus/core/utils"
@@ -36,32 +39,65 @@ const (
// defaultTicker is a wrapper to implement ticker interface based on
// time.Ticker.
type defaultTicker struct {
- ticker *time.Ticker
- duration time.Duration
+ ticker *time.Ticker
+ tickerChan chan time.Time
+ duration time.Duration
+ ctx context.Context
+ ctxCancel context.CancelFunc
+ waitGroup sync.WaitGroup
}
// newDefaultTicker constructs an defaultTicker instance by giving an interval.
func newDefaultTicker(lambda time.Duration) *defaultTicker {
- return &defaultTicker{
- ticker: time.NewTicker(lambda),
- duration: lambda,
- }
+ ticker := &defaultTicker{duration: lambda}
+ ticker.init()
+ return ticker
}
// Tick implements Tick method of ticker interface.
func (t *defaultTicker) Tick() <-chan time.Time {
- return t.ticker.C
+ return t.tickerChan
}
// Stop implements Stop method of ticker interface.
func (t *defaultTicker) Stop() {
t.ticker.Stop()
+ t.ctxCancel()
+ t.waitGroup.Wait()
+ t.ctx = nil
+ t.ctxCancel = nil
+ close(t.tickerChan)
+ t.tickerChan = nil
}
// Restart implements Stop method of ticker interface.
func (t *defaultTicker) Restart() {
- t.ticker.Stop()
+ t.Stop()
+ t.init()
+}
+
+func (t *defaultTicker) init() {
t.ticker = time.NewTicker(t.duration)
+ t.tickerChan = make(chan time.Time)
+ t.ctx, t.ctxCancel = context.WithCancel(context.Background())
+ t.waitGroup.Add(1)
+ go t.monitor()
+}
+
+func (t *defaultTicker) monitor() {
+ defer t.waitGroup.Done()
+loop:
+ for {
+ select {
+ case <-t.ctx.Done():
+ break loop
+ case v := <-t.ticker.C:
+ select {
+ case t.tickerChan <- v:
+ default:
+ }
+ }
+ }
}
// newTicker is a helper to setup a ticker by giving an Governance. If
@@ -82,8 +118,8 @@ func newTicker(gov Governance, round uint64, tickerType TickerType) (t Ticker) {
duration = utils.GetConfigWithPanic(gov, round, nil).LambdaBA
case TickerDKG:
duration = utils.GetConfigWithPanic(gov, round, nil).LambdaDKG
- case TickerCRS:
- duration = utils.GetConfigWithPanic(gov, round, nil).RoundInterval / 2
+ default:
+ panic(fmt.Errorf("unknown ticker type: %d", tickerType))
}
t = newDefaultTicker(duration)
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
index a2b697ce0..2b23e96e3 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
@@ -23,7 +23,6 @@ import (
"bytes"
"fmt"
"io"
- "sort"
"time"
"github.com/dexon-foundation/dexon/rlp"
@@ -125,17 +124,16 @@ type Witness struct {
// Block represents a single event broadcasted on the network.
type Block struct {
- ProposerID NodeID `json:"proposer_id"`
- ParentHash common.Hash `json:"parent_hash"`
- Hash common.Hash `json:"hash"`
- Position Position `json:"position"`
- Timestamp time.Time `json:"timestamp"`
- Acks common.SortedHashes `json:"acks"`
- Payload []byte `json:"payload"`
- PayloadHash common.Hash `json:"payload_hash"`
- Witness Witness `json:"witness"`
- Finalization FinalizationResult `json:"finalization"`
- Signature crypto.Signature `json:"signature"`
+ ProposerID NodeID `json:"proposer_id"`
+ ParentHash common.Hash `json:"parent_hash"`
+ Hash common.Hash `json:"hash"`
+ Position Position `json:"position"`
+ Timestamp time.Time `json:"timestamp"`
+ Payload []byte `json:"payload"`
+ PayloadHash common.Hash `json:"payload_hash"`
+ Witness Witness `json:"witness"`
+ Finalization FinalizationResult `json:"finalization"`
+ Signature crypto.Signature `json:"signature"`
CRSSignature crypto.Signature `json:"crs_signature"`
}
@@ -146,7 +144,6 @@ type rlpBlock struct {
Hash common.Hash
Position Position
Timestamp *rlpTimestamp
- Acks common.SortedHashes
Payload []byte
PayloadHash common.Hash
Witness *Witness
@@ -164,7 +161,6 @@ func (b *Block) EncodeRLP(w io.Writer) error {
Hash: b.Hash,
Position: b.Position,
Timestamp: &rlpTimestamp{b.Timestamp},
- Acks: b.Acks,
Payload: b.Payload,
PayloadHash: b.PayloadHash,
Witness: &b.Witness,
@@ -185,7 +181,6 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
Hash: dec.Hash,
Position: dec.Position,
Timestamp: dec.Timestamp.Time,
- Acks: dec.Acks,
Payload: dec.Payload,
PayloadHash: dec.PayloadHash,
Witness: *dec.Witness,
@@ -208,7 +203,6 @@ func (b *Block) Clone() (bcopy *Block) {
bcopy.ParentHash = b.ParentHash
bcopy.Hash = b.Hash
bcopy.Position.Round = b.Position.Round
- bcopy.Position.ChainID = b.Position.ChainID
bcopy.Position.Height = b.Position.Height
bcopy.Signature = b.Signature.Clone()
bcopy.CRSSignature = b.CRSSignature.Clone()
@@ -217,8 +211,6 @@ func (b *Block) Clone() (bcopy *Block) {
bcopy.Witness.Data = make([]byte, len(b.Witness.Data))
copy(bcopy.Witness.Data, b.Witness.Data)
bcopy.Timestamp = b.Timestamp
- bcopy.Acks = make(common.SortedHashes, len(b.Acks))
- copy(bcopy.Acks, b.Acks)
bcopy.Payload = make([]byte, len(b.Payload))
copy(bcopy.Payload, b.Payload)
bcopy.PayloadHash = b.PayloadHash
@@ -240,14 +232,6 @@ func (b *Block) IsEmpty() bool {
return b.ProposerID.Hash == common.Hash{}
}
-// IsAcking checks if a block acking another by it's hash.
-func (b *Block) IsAcking(hash common.Hash) bool {
- idx := sort.Search(len(b.Acks), func(i int) bool {
- return bytes.Compare(b.Acks[i][:], hash[:]) >= 0
- })
- return !(idx == len(b.Acks) || b.Acks[idx] != hash)
-}
-
// ByHash is the helper type for sorting slice of blocks by hash.
type ByHash []*Block
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go
index c9d31f8c4..eda09f06e 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/config.go
@@ -19,52 +19,38 @@ package types
import (
"encoding/binary"
- "math"
"time"
)
// Config stands for Current Configuration Parameters.
type Config struct {
- // Network related.
- NumChains uint32
-
// Lambda related.
LambdaBA time.Duration
LambdaDKG time.Duration
- // Total ordering related.
- K int
- PhiRatio float32
-
// Set related.
NotarySetSize uint32
DKGSetSize uint32
// Time related.
- RoundInterval time.Duration
+ RoundLength uint64
MinBlockInterval time.Duration
}
// Clone return a copied configuration.
func (c *Config) Clone() *Config {
return &Config{
- NumChains: c.NumChains,
LambdaBA: c.LambdaBA,
LambdaDKG: c.LambdaDKG,
- K: c.K,
- PhiRatio: c.PhiRatio,
NotarySetSize: c.NotarySetSize,
DKGSetSize: c.DKGSetSize,
- RoundInterval: c.RoundInterval,
+ RoundLength: c.RoundLength,
MinBlockInterval: c.MinBlockInterval,
}
}
// Bytes returns []byte representation of Config.
func (c *Config) Bytes() []byte {
- binaryNumChains := make([]byte, 4)
- binary.LittleEndian.PutUint32(binaryNumChains, c.NumChains)
-
binaryLambdaBA := make([]byte, 8)
binary.LittleEndian.PutUint64(
binaryLambdaBA, uint64(c.LambdaBA.Nanoseconds()))
@@ -72,32 +58,23 @@ func (c *Config) Bytes() []byte {
binary.LittleEndian.PutUint64(
binaryLambdaDKG, uint64(c.LambdaDKG.Nanoseconds()))
- binaryK := make([]byte, 4)
- binary.LittleEndian.PutUint32(binaryK, uint32(c.K))
- binaryPhiRatio := make([]byte, 4)
- binary.LittleEndian.PutUint32(binaryPhiRatio, math.Float32bits(c.PhiRatio))
-
binaryNotarySetSize := make([]byte, 4)
binary.LittleEndian.PutUint32(binaryNotarySetSize, c.NotarySetSize)
binaryDKGSetSize := make([]byte, 4)
binary.LittleEndian.PutUint32(binaryDKGSetSize, c.DKGSetSize)
- binaryRoundInterval := make([]byte, 8)
- binary.LittleEndian.PutUint64(binaryRoundInterval,
- uint64(c.RoundInterval.Nanoseconds()))
+ binaryRoundLength := make([]byte, 8)
+ binary.LittleEndian.PutUint64(binaryRoundLength, c.RoundLength)
binaryMinBlockInterval := make([]byte, 8)
binary.LittleEndian.PutUint64(binaryMinBlockInterval,
uint64(c.MinBlockInterval.Nanoseconds()))
enc := make([]byte, 0, 40)
- enc = append(enc, binaryNumChains...)
enc = append(enc, binaryLambdaBA...)
enc = append(enc, binaryLambdaDKG...)
- enc = append(enc, binaryK...)
- enc = append(enc, binaryPhiRatio...)
enc = append(enc, binaryNotarySetSize...)
enc = append(enc, binaryDKGSetSize...)
- enc = append(enc, binaryRoundInterval...)
+ enc = append(enc, binaryRoundLength...)
enc = append(enc, binaryMinBlockInterval...)
return enc
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go
index 902a55fec..81d23c266 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/position.go
@@ -23,33 +23,22 @@ import (
// Position describes the position in the block lattice of an entity.
type Position struct {
- ChainID uint32 `json:"chain_id"`
- Round uint64 `json:"round"`
- Height uint64 `json:"height"`
+ Round uint64 `json:"round"`
+ Height uint64 `json:"height"`
}
func (pos Position) String() string {
- return fmt.Sprintf("Position{Round:%d Chain:%d Height:%d}",
- pos.Round, pos.ChainID, pos.Height)
+ return fmt.Sprintf("Position{Round:%d Height:%d}", pos.Round, pos.Height)
}
-// Equal checks if two positions are equal, it panics when their chainIDs
-// are different.
+// Equal checks if two positions are equal.
func (pos Position) Equal(other Position) bool {
- if pos.ChainID != other.ChainID {
- panic(fmt.Errorf("unexpected chainID %d, should be %d",
- other.ChainID, pos.ChainID))
- }
return pos.Round == other.Round && pos.Height == other.Height
}
// Newer checks if one block is newer than another one on the same chain.
// If two blocks on different chain compared by this function, it would panic.
func (pos Position) Newer(other Position) bool {
- if pos.ChainID != other.ChainID {
- panic(fmt.Errorf("unexpected chainID %d, should be %d",
- other.ChainID, pos.ChainID))
- }
return pos.Round > other.Round ||
(pos.Round == other.Round && pos.Height > other.Height)
}
@@ -57,10 +46,6 @@ func (pos Position) Newer(other Position) bool {
// Older checks if one block is older than another one on the same chain.
// If two blocks on different chain compared by this function, it would panic.
func (pos Position) Older(other Position) bool {
- if pos.ChainID != other.ChainID {
- panic(fmt.Errorf("unexpected chainID %d, should be %d",
- other.ChainID, pos.ChainID))
- }
return pos.Round < other.Round ||
(pos.Round == other.Round && pos.Height < other.Height)
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go
index 6481eb46d..c4a625edd 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/vote.go
@@ -66,7 +66,7 @@ type Vote struct {
}
func (v *Vote) String() string {
- return fmt.Sprintf("Vote{BP:%s %s Period:%d Type:%d Hash:%s}",
+ return fmt.Sprintf("Vote{VP:%s %s Period:%d Type:%d Hash:%s}",
v.ProposerID.String()[:6],
v.Position, v.Period, v.Type, v.BlockHash.String()[:6])
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
index 14780e73b..46aa77a6b 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils.go
@@ -21,7 +21,6 @@ import (
"context"
"errors"
"fmt"
- "math/rand"
"os"
"sort"
"time"
@@ -130,11 +129,6 @@ func removeFromSortedUint32Slice(xs []uint32, x uint32) []uint32 {
return append(xs[:indexToRemove], xs[indexToRemove+1:]...)
}
-// pickBiasedTime returns a biased time based on a given range.
-func pickBiasedTime(base time.Time, biasedRange time.Duration) time.Time {
- return base.Add(time.Duration(rand.Intn(int(biasedRange))))
-}
-
// HashConfigurationBlock returns the hash value of configuration block.
func HashConfigurationBlock(
notarySet map[types.NodeID]struct{},
@@ -165,8 +159,7 @@ func HashConfigurationBlock(
// instance.
func VerifyAgreementResult(
res *types.AgreementResult, cache *utils.NodeSetCache) error {
- notarySet, err := cache.GetNotarySet(
- res.Position.Round, res.Position.ChainID)
+ notarySet, err := cache.GetNotarySet(res.Position.Round)
if err != nil {
return err
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
index 43bbde13d..f5343ca38 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go
@@ -37,12 +37,6 @@ func hashWitness(witness *types.Witness) (common.Hash, error) {
// HashBlock generates hash of a types.Block.
func HashBlock(block *types.Block) (common.Hash, error) {
hashPosition := hashPosition(block.Position)
- // Handling Block.Acks.
- binaryAcks := make([][]byte, len(block.Acks))
- for idx, ack := range block.Acks {
- binaryAcks[idx] = ack[:]
- }
- hashAcks := crypto.Keccak256Hash(binaryAcks...)
binaryTimestamp, err := block.Timestamp.UTC().MarshalBinary()
if err != nil {
return common.Hash{}, err
@@ -56,7 +50,6 @@ func HashBlock(block *types.Block) (common.Hash, error) {
block.ProposerID.Hash[:],
block.ParentHash[:],
hashPosition[:],
- hashAcks[:],
binaryTimestamp[:],
block.PayloadHash[:],
binaryWitness[:])
@@ -140,9 +133,6 @@ func VerifyCRSSignature(block *types.Block, crs common.Hash) (
}
func hashPosition(position types.Position) common.Hash {
- binaryChainID := make([]byte, 4)
- binary.LittleEndian.PutUint32(binaryChainID, position.ChainID)
-
binaryRound := make([]byte, 8)
binary.LittleEndian.PutUint64(binaryRound, position.Round)
@@ -150,7 +140,6 @@ func hashPosition(position types.Position) common.Hash {
binary.LittleEndian.PutUint64(binaryHeight, position.Height)
return crypto.Keccak256Hash(
- binaryChainID,
binaryRound,
binaryHeight,
)
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
index 83541283b..6249665ac 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
@@ -19,7 +19,6 @@ package utils
import (
"errors"
- "fmt"
"sync"
"github.com/dexon-foundation/dexon-consensus/common"
@@ -34,8 +33,6 @@ var (
ErrCRSNotReady = errors.New("crs is not ready")
// ErrConfigurationNotReady means we go nil configuration.
ErrConfigurationNotReady = errors.New("configuration is not ready")
- // ErrInvalidChainID means the chain ID is unexpected.
- ErrInvalidChainID = errors.New("invalid chain id")
)
type sets struct {
@@ -125,12 +122,8 @@ func (cache *NodeSetCache) GetNodeSet(round uint64) (*types.NodeSet, error) {
}
// GetNotarySet returns of notary set of this round.
-// TODO(mission): remove chainID parameter.
func (cache *NodeSetCache) GetNotarySet(
- round uint64, chainID uint32) (map[types.NodeID]struct{}, error) {
- if chainID != 0 {
- panic(fmt.Errorf("non-zero chainID found: %d", chainID))
- }
+ round uint64) (map[types.NodeID]struct{}, error) {
IDs, err := cache.getOrUpdate(round)
if err != nil {
return nil, err
@@ -196,12 +189,9 @@ func (cache *NodeSetCache) getOrUpdate(round uint64) (nIDs *sets, err error) {
//
// This cache would maintain 10 rounds before the updated round and purge
// rounds not in this range.
-func (cache *NodeSetCache) update(
- round uint64) (nIDs *sets, err error) {
-
+func (cache *NodeSetCache) update(round uint64) (nIDs *sets, err error) {
cache.lock.Lock()
defer cache.lock.Unlock()
-
// Get information for the requested round.
keySet := cache.nsIntf.NodeSet(round)
if keySet == nil {
@@ -232,14 +222,15 @@ func (cache *NodeSetCache) update(
err = ErrConfigurationNotReady
return
}
- nodesPerChain := cfg.RoundInterval / cfg.MinBlockInterval
nIDs = &sets{
- crs: crs,
- nodeSet: nodeSet,
- notarySet: make(map[types.NodeID]struct{}),
- dkgSet: nodeSet.GetSubSet(
- int(cfg.DKGSetSize), types.NewDKGSetTarget(crs)),
- leaderNode: make(map[uint64]types.NodeID, nodesPerChain),
+ crs: crs,
+ nodeSet: nodeSet,
+ notarySet: make(map[types.NodeID]struct{}),
+ leaderNode: make(map[uint64]types.NodeID, cfg.RoundLength),
+ }
+ if round >= dkgDelayRound {
+ nIDs.dkgSet = nodeSet.GetSubSet(
+ int(cfg.DKGSetSize), types.NewDKGSetTarget(crs))
}
nIDs.notarySet = nodeSet.GetSubSet(
int(cfg.NotarySetSize), types.NewNotarySetTarget(crs))
@@ -261,12 +252,9 @@ func (cache *NodeSetCache) update(
return
}
-func (cache *NodeSetCache) get(
- round uint64) (nIDs *sets, exists bool) {
-
+func (cache *NodeSetCache) get(round uint64) (nIDs *sets, exists bool) {
cache.lock.RLock()
defer cache.lock.RUnlock()
-
nIDs, exists = cache.rounds[round]
return
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
index 8486d2854..203f57fc2 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
@@ -26,6 +26,13 @@ import (
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
)
+var dkgDelayRound uint64
+
+// SetDKGDelayRound sets the variable.
+func SetDKGDelayRound(delay uint64) {
+ dkgDelayRound = delay
+}
+
type configAccessor interface {
Configuration(round uint64) *types.Config
}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index f424fa691..0955ef4dd 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -139,18 +139,18 @@
"versionExact": "dev"
},
{
- "checksumSHA1": "pnv6DaNi8uUdtYFqNdLjgpeCp6A=",
+ "checksumSHA1": "8EuKVkP1v/w5fRuuvUaXX5k/F+I=",
"path": "github.com/dexon-foundation/dexon-consensus/common",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "VI5+nQ9e4RiSE4JBOc92UU65eVY=",
+ "checksumSHA1": "RD3L08SnpZty2qH5mNERxYxB7gg=",
"path": "github.com/dexon-foundation/dexon-consensus/core",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
@@ -165,64 +165,64 @@
{
"checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "Nlv7pi1DIBftY+r6CFP8LBIQA3U=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "zpuCdMT8MGsy4pLgHKpg/Wd4izU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/db",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "KYpliqwnJejH8V/GqygKSiQETbo=",
+ "checksumSHA1": "T9TNx0oUpaRdlbCuy7AvkK1eQ18=",
"path": "github.com/dexon-foundation/dexon-consensus/core/syncer",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "g9eEP7SxpQf10C3wCsNN/Hn9XK0=",
+ "checksumSHA1": "id8imcgp3SqYhIx0k3Chd0VZrUQ=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "s28gYj+iji8oT7N7Su6HIFHMuwI=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "1z0CIfS1QRV9xoA9wrTyVUMmXjc=",
+ "checksumSHA1": "C8Q8sfOSs+FPw/5sPwAR04QFc3U=",
"path": "github.com/dexon-foundation/dexon-consensus/core/utils",
- "revision": "2cf18fd299ea0fc270b213343314cab652cac271",
- "revisionTime": "2019-02-18T10:44:35Z",
+ "revision": "d4b4c8a05e94f66c85e7b4238ae5947b26f13c40",
+ "revisionTime": "2019-03-04T10:30:03Z",
"version": "single-chain",
"versionExact": "single-chain"
},