diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2019-01-07 17:21:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-07 17:21:08 +0800 |
commit | 21c420db895b1aa48709982cd145a119c74de6fa (patch) | |
tree | a8cd9a9bc5e8c22a21812f0e00939f3fbd92db89 /core/utils | |
parent | 8d1069b61d847662d37f504937a346c56d6cb0eb (diff) | |
download | tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar.gz tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar.bz2 tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar.lz tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar.xz tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.tar.zst tangerine-consensus-21c420db895b1aa48709982cd145a119c74de6fa.zip |
core: BA 3.0 (#408)
* Add v3 enum
* Add BA leader calculation
* Fast BA
* Add unittest for Fast BA
* Add comment
* Select leader in notarySet
Diffstat (limited to 'core/utils')
-rw-r--r-- | core/utils/nodeset-cache.go | 41 | ||||
-rw-r--r-- | core/utils/nodeset-cache_test.go | 12 |
2 files changed, 50 insertions, 3 deletions
diff --git a/core/utils/nodeset-cache.go b/core/utils/nodeset-cache.go index 6d4f7b0..35828b7 100644 --- a/core/utils/nodeset-cache.go +++ b/core/utils/nodeset-cache.go @@ -38,9 +38,11 @@ var ( ) type sets struct { - nodeSet *types.NodeSet - notarySet []map[types.NodeID]struct{} - dkgSet map[types.NodeID]struct{} + crs common.Hash + nodeSet *types.NodeSet + notarySet []map[types.NodeID]struct{} + dkgSet map[types.NodeID]struct{} + leaderNode []map[uint64]types.NodeID } // NodeSetCacheInterface interface specifies interface used by NodeSetCache. @@ -146,6 +148,33 @@ func (cache *NodeSetCache) GetDKGSet( return cache.cloneMap(IDs.dkgSet), nil } +// GetLeaderNode returns the BA leader of the position. +func (cache *NodeSetCache) GetLeaderNode(pos types.Position) ( + types.NodeID, error) { + IDs, err := cache.getOrUpdate(pos.Round) + if err != nil { + return types.NodeID{}, err + } + if pos.ChainID >= uint32(len(IDs.leaderNode)) { + return types.NodeID{}, ErrInvalidChainID + } + cache.lock.Lock() + defer cache.lock.Unlock() + if _, exist := IDs.leaderNode[pos.ChainID][pos.Height]; !exist { + notarySet := types.NewNodeSetFromMap(IDs.notarySet[pos.ChainID]) + leader := + notarySet.GetSubSet(1, types.NewNodeLeaderTarget(IDs.crs, pos)) + if len(leader) != 1 { + panic(errors.New("length of leader is not one")) + } + for nID := range leader { + IDs.leaderNode[pos.ChainID][pos.Height] = nID + break + } + } + return IDs.leaderNode[pos.ChainID][pos.Height], nil +} + func (cache *NodeSetCache) cloneMap( nIDs map[types.NodeID]struct{}) map[types.NodeID]struct{} { nIDsCopy := make(map[types.NodeID]struct{}, len(nIDs)) @@ -207,15 +236,21 @@ func (cache *NodeSetCache) update( return } nIDs = &sets{ + crs: crs, nodeSet: nodeSet, notarySet: make([]map[types.NodeID]struct{}, cfg.NumChains), dkgSet: nodeSet.GetSubSet( int(cfg.DKGSetSize), types.NewDKGSetTarget(crs)), + leaderNode: make([]map[uint64]types.NodeID, cfg.NumChains), } for i := range nIDs.notarySet { nIDs.notarySet[i] = nodeSet.GetSubSet( int(cfg.NotarySetSize), types.NewNotarySetTarget(crs, uint32(i))) } + nodesPerChain := cfg.RoundInterval / (cfg.LambdaBA * 4) + for i := range nIDs.leaderNode { + nIDs.leaderNode[i] = make(map[uint64]types.NodeID, nodesPerChain) + } cache.rounds[round] = nIDs // Purge older rounds. diff --git a/core/utils/nodeset-cache_test.go b/core/utils/nodeset-cache_test.go index 27c8c83..9e6ceee 100644 --- a/core/utils/nodeset-cache_test.go +++ b/core/utils/nodeset-cache_test.go @@ -19,6 +19,7 @@ package utils import ( "testing" + "time" "github.com/dexon-foundation/dexon-consensus/common" "github.com/dexon-foundation/dexon-consensus/core/crypto" @@ -38,6 +39,8 @@ func (g *nsIntf) Configuration(round uint64) (cfg *types.Config) { NotarySetSize: 7, DKGSetSize: 7, NumChains: 4, + LambdaBA: 250 * time.Millisecond, + RoundInterval: 60 * time.Second, } } func (g *nsIntf) CRS(round uint64) (b common.Hash) { return g.crs } @@ -91,6 +94,15 @@ func (s *NodeSetCacheTestSuite) TestBasicUsage() { dkgSet, err := cache.GetDKGSet(0) req.NoError(err) chk(cache, 0, dkgSet) + leaderNode, err := cache.GetLeaderNode(types.Position{ + Round: uint64(0), + ChainID: uint32(3), + Height: uint64(10), + }) + req.NoError(err) + chk(cache, 0, map[types.NodeID]struct{}{ + leaderNode: struct{}{}, + }) // Try to get round 1. nodeSet1, err := cache.GetNodeSet(1) req.NoError(err) |