diff options
author | Wei-Ning Huang <w@dexon.org> | 2018-09-25 18:52:35 +0800 |
---|---|---|
committer | missionliao <38416648+missionliao@users.noreply.github.com> | 2018-09-25 18:52:35 +0800 |
commit | 0ffea9dadcfc0d8a740942a2d666eccc00613cd4 (patch) | |
tree | 7984fd6c5a58abc96b1a808efb89806d48612299 | |
parent | d844c339a128322dff180a6ccc6e6b241e917546 (diff) | |
download | dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar.gz dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar.bz2 dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar.lz dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar.xz dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.tar.zst dexon-consensus-0ffea9dadcfc0d8a740942a2d666eccc00613cd4.zip |
core: update governance interface to consider genesis state (#136)
-rw-r--r-- | core/agreement-state_test.go | 2 | ||||
-rw-r--r-- | core/agreement_test.go | 2 | ||||
-rw-r--r-- | core/consensus.go | 122 | ||||
-rw-r--r-- | core/consensus_test.go | 6 | ||||
-rw-r--r-- | core/interfaces.go | 13 | ||||
-rw-r--r-- | core/leader-selector.go | 4 | ||||
-rw-r--r-- | core/leader-selector_test.go | 2 | ||||
-rw-r--r-- | core/nonblocking.go | 4 | ||||
-rw-r--r-- | core/test/app.go | 2 | ||||
-rw-r--r-- | core/test/governance.go | 17 | ||||
-rw-r--r-- | core/test/tcp-transport.go | 4 | ||||
-rw-r--r-- | core/test/transport_test.go | 2 | ||||
-rw-r--r-- | core/types/config.go | 8 | ||||
-rw-r--r-- | integration_test/node.go | 2 | ||||
-rw-r--r-- | integration_test/utils.go | 4 | ||||
-rw-r--r-- | simulation/app.go | 2 | ||||
-rw-r--r-- | simulation/governance.go | 21 |
17 files changed, 123 insertions, 94 deletions
diff --git a/core/agreement-state_test.go b/core/agreement-state_test.go index 79e4102..0142724 100644 --- a/core/agreement-state_test.go +++ b/core/agreement-state_test.go @@ -98,7 +98,7 @@ func (s *AgreementStateTestSuite) SetupTest() { } func (s *AgreementStateTestSuite) newAgreement(numNode int) *agreement { - leader := newGenesisLeaderSelector("I ❤️ DEXON", eth.SigToPub) + leader := newGenesisLeaderSelector([]byte("I ❤️ DEXON"), eth.SigToPub) blockProposer := func() *types.Block { return s.proposeBlock(leader) } diff --git a/core/agreement_test.go b/core/agreement_test.go index b344dd9..681d7b6 100644 --- a/core/agreement_test.go +++ b/core/agreement_test.go @@ -80,7 +80,7 @@ func (s *AgreementTestSuite) SetupTest() { } func (s *AgreementTestSuite) newAgreement(numNotarySet int) *agreement { - leader := newGenesisLeaderSelector("🖖👽", eth.SigToPub) + leader := newGenesisLeaderSelector([]byte("🖖👽"), eth.SigToPub) agreementIdx := len(s.agreement) blockProposer := func() *types.Block { return s.proposeBlock(agreementIdx) diff --git a/core/consensus.go b/core/consensus.go index 8ada7ae..fc7cd70 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -171,27 +171,41 @@ func (recv *consensusDKGReceiver) ProposeDKGAntiNackComplaint( // Consensus implements DEXON Consensus algorithm. type Consensus struct { - ID types.NodeID - nbModule *nonBlocking - gov Governance - config *types.Config - baModules []*agreement - receivers []*consensusReceiver - rbModule *reliableBroadcast - toModule *totalOrdering - ctModule *consensusTimestamp - ccModule *compactionChain - db blockdb.BlockDatabase - network Network - tickerObj Ticker - prvKey crypto.PrivateKey + // Node Info. + ID types.NodeID + prvKey crypto.PrivateKey + currentConfig *types.Config + + // Modules. + nbModule *nonBlocking + + // BA. + baModules []*agreement + receivers []*consensusReceiver + + // DKG. dkgRunning int32 dkgReady *sync.Cond dkgModule *dkgProtocol - sigToPub SigToPubFn - lock sync.RWMutex - ctx context.Context - ctxCancel context.CancelFunc + + // Dexon consensus modules. + rbModule *reliableBroadcast + toModule *totalOrdering + ctModule *consensusTimestamp + ccModule *compactionChain + + // Interfaces. + db blockdb.BlockDatabase + gov Governance + network Network + tickerObj Ticker + sigToPub SigToPubFn + + // Misc. + notarySet map[types.NodeID]struct{} + lock sync.RWMutex + ctx context.Context + ctxCancel context.CancelFunc } // NewConsensus construct an Consensus instance. @@ -203,8 +217,11 @@ func NewConsensus( prv crypto.PrivateKey, sigToPub SigToPubFn) *Consensus { - config := gov.GetConfiguration(0) - notarySet := gov.GetNotarySet() + // TODO(w): load latest blockHeight from DB, and use config at that height. + var blockHeight uint64 + config := gov.GetConfiguration(blockHeight) + notarySet := gov.GetNotarySet(blockHeight) + ID := types.NewNodeID(prv.PublicKey()) // Setup acking by information returned from Governace. @@ -236,34 +253,35 @@ func NewConsensus( network: network, }, 0, - len(gov.GetNotarySet())/3, + len(notarySet)/3, sigToPub) // Check if the application implement Debug interface. debug, _ := app.(Debug) con := &Consensus{ - ID: ID, - rbModule: rb, - toModule: to, - ctModule: newConsensusTimestamp(), - ccModule: newCompactionChain(db, sigToPub), - nbModule: newNonBlocking(app, debug), - gov: gov, - config: config, - db: db, - network: network, - tickerObj: newTicker(gov, TickerBA), - prvKey: prv, - dkgReady: sync.NewCond(&sync.Mutex{}), - dkgModule: dkgModule, - sigToPub: sigToPub, - ctx: ctx, - ctxCancel: ctxCancel, - } - - con.baModules = make([]*agreement, con.config.NumChains) - con.receivers = make([]*consensusReceiver, con.config.NumChains) - for i := uint32(0); i < con.config.NumChains; i++ { + ID: ID, + currentConfig: config, + rbModule: rb, + toModule: to, + ctModule: newConsensusTimestamp(), + ccModule: newCompactionChain(db, sigToPub), + nbModule: newNonBlocking(app, debug), + gov: gov, + db: db, + network: network, + tickerObj: newTicker(gov, TickerBA), + prvKey: prv, + dkgReady: sync.NewCond(&sync.Mutex{}), + dkgModule: dkgModule, + sigToPub: sigToPub, + notarySet: notarySet, + ctx: ctx, + ctxCancel: ctxCancel, + } + + con.baModules = make([]*agreement, config.NumChains) + con.receivers = make([]*consensusReceiver, config.NumChains) + for i := uint32(0); i < config.NumChains; i++ { chainID := i con.receivers[chainID] = &consensusReceiver{ consensus: con, @@ -279,7 +297,7 @@ func NewConsensus( con.ID, con.receivers[chainID], nodes, - newGenesisLeaderSelector(con.config.GenesisCRS, con.sigToPub), + newGenesisLeaderSelector(config.CRS, con.sigToPub), con.sigToPub, blockProposer, ) @@ -296,8 +314,8 @@ func (con *Consensus) Run() { for con.dkgRunning != 2 { con.dkgReady.Wait() } - ticks := make([]chan struct{}, 0, con.config.NumChains) - for i := uint32(0); i < con.config.NumChains; i++ { + ticks := make([]chan struct{}, 0, con.currentConfig.NumChains) + for i := uint32(0); i < con.currentConfig.NumChains; i++ { tick := make(chan struct{}) ticks = append(ticks, tick) go con.runBA(i, tick) @@ -317,9 +335,9 @@ func (con *Consensus) Run() { func (con *Consensus) runBA(chainID uint32, tick <-chan struct{}) { // TODO(jimmy-dexon): move this function inside agreement. - notarySet := con.gov.GetNotarySet() - nodes := make(types.NodeIDs, 0, len(notarySet)) - for nID := range notarySet { + + nodes := make(types.NodeIDs, 0, len(con.notarySet)) + for nID := range con.notarySet { nodes = append(nodes, nID) } agreement := con.baModules[chainID] @@ -414,8 +432,8 @@ func (con *Consensus) RunLegacy() { go con.processWitnessData() chainID := uint32(0) - hashes := make(common.Hashes, 0, len(con.gov.GetNotarySet())) - for nID := range con.gov.GetNotarySet() { + hashes := make(common.Hashes, 0, len(con.notarySet)) + for nID := range con.notarySet { hashes = append(hashes, nID.Hash) } sort.Sort(hashes) @@ -727,7 +745,7 @@ func (con *Consensus) PrepareGenesisBlock(b *types.Block, // ProcessWitnessAck is the entry point to submit one witness ack. func (con *Consensus) ProcessWitnessAck(witnessAck *types.WitnessAck) (err error) { witnessAck = witnessAck.Clone() - if _, exists := con.gov.GetNotarySet()[witnessAck.ProposerID]; !exists { + if _, exists := con.notarySet[witnessAck.ProposerID]; !exists { err = ErrProposerNotInNotarySet return } diff --git a/core/consensus_test.go b/core/consensus_test.go index bd95a00..2b71d6b 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -112,7 +112,7 @@ func (s *ConsensusTestSuite) TestSimpleDeliverBlock() { ) s.Require().Nil(err) - for nID := range gov.GetNotarySet() { + for nID := range gov.GetNotarySet(0) { nodes = append(nodes, nID) } @@ -328,7 +328,7 @@ func (s *ConsensusTestSuite) TestPrepareBlock() { nodes []types.NodeID ) s.Require().Nil(err) - for nID := range gov.GetNotarySet() { + for nID := range gov.GetNotarySet(0) { nodes = append(nodes, nID) } // Setup core.Consensus and test.App. @@ -375,7 +375,7 @@ func (s *ConsensusTestSuite) TestPrepareGenesisBlock() { nodes []types.NodeID ) s.Require().Nil(err) - for nID := range gov.GetNotarySet() { + for nID := range gov.GetNotarySet(0) { nodes = append(nodes, nID) } _, con := s.prepareConsensus(gov, nodes[0]) diff --git a/core/interfaces.go b/core/interfaces.go index 4e0b4cc..940d9b5 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -30,8 +30,8 @@ type Application interface { // PreparePayload is called when consensus core is preparing a block. PreparePayload(position types.Position) []byte - // VerifyPayload verifies if the payloads are valid. - VerifyPayload(payloads []byte) bool + // VerifyPayload verifies if the payload is valid. + VerifyPayload(payload []byte) bool // BlockDelivered is called when a block is add to the compaction chain. BlockDelivered(block types.Block) @@ -85,10 +85,12 @@ type Network interface { // interface only define those that are required to run the consensus algorithm. type Governance interface { // GetConfiguration returns the configuration at a given block height. + // Return the genesis configuration if blockHeight == 0. GetConfiguration(blockHeight uint64) *types.Config // Get the current notary set. - GetNotarySet() map[types.NodeID]struct{} + // Return the genesis notary set if blockHeight == 0. + GetNotarySet(blockHeight uint64) map[types.NodeID]struct{} //// DKG-related methods. @@ -109,6 +111,7 @@ type Governance interface { type Ticker interface { // Tick would return a channel, which would be triggered until next tick. Tick() <-chan time.Time + // Stop the ticker. Stop() } @@ -117,8 +120,10 @@ type Ticker interface { type Signer interface { // SignBlock signs a block. SignBlock(b *types.Block) error + // SignVote signs a vote. SignVote(v *types.Vote) error + // SignCRS sign a block's CRS signature. SignCRS(b *types.Block, crs common.Hash) error } @@ -127,8 +132,10 @@ type Signer interface { type CryptoVerifier interface { // VerifyBlock verifies if a block is properly signed or not. VerifyBlock(b *types.Block) (ok bool, err error) + // VerifyVote verfies if a vote is properly signed or not. VerifyVote(v *types.Vote) (ok bool, err error) + // VerifyCRS verifies if a CRS signature of one block is valid or not. VerifyCRS(b *types.Block, crs common.Hash) (ok bool, err error) } diff --git a/core/leader-selector.go b/core/leader-selector.go index d96de4e..ce5134a 100644 --- a/core/leader-selector.go +++ b/core/leader-selector.go @@ -56,9 +56,9 @@ type leaderSelector struct { } func newGenesisLeaderSelector( - crs string, + crs []byte, sigToPub SigToPubFn) *leaderSelector { - hash := crypto.Keccak256Hash([]byte(crs[:])) + hash := crypto.Keccak256Hash(crs) return newLeaderSelector(hash, sigToPub) } diff --git a/core/leader-selector_test.go b/core/leader-selector_test.go index 7eb9b3c..211680d 100644 --- a/core/leader-selector_test.go +++ b/core/leader-selector_test.go @@ -32,7 +32,7 @@ type LeaderSelectorTestSuite struct { } func (s *LeaderSelectorTestSuite) newLeader() *leaderSelector { - return newGenesisLeaderSelector("DEXON 🚀", eth.SigToPub) + return newGenesisLeaderSelector([]byte("DEXON 🚀"), eth.SigToPub) } func (s *LeaderSelectorTestSuite) TestDistance() { diff --git a/core/nonblocking.go b/core/nonblocking.go index 7c685dc..1dd1ded 100644 --- a/core/nonblocking.go +++ b/core/nonblocking.go @@ -130,8 +130,8 @@ func (nb *nonBlocking) PreparePayload( } // VerifyPayload cannot be non-blocking. -func (nb *nonBlocking) VerifyPayload(payloads []byte) bool { - return nb.app.VerifyPayload(payloads) +func (nb *nonBlocking) VerifyPayload(payload []byte) bool { + return nb.app.VerifyPayload(payload) } // BlockConfirmed is called when a block is confirmed and added to lattice. diff --git a/core/test/app.go b/core/test/app.go index cc2bbe6..4cac36c 100644 --- a/core/test/app.go +++ b/core/test/app.go @@ -110,7 +110,7 @@ func (app *App) PreparePayload(position types.Position) []byte { } // VerifyPayload implements Application. -func (app *App) VerifyPayload(payloads []byte) bool { +func (app *App) VerifyPayload(payload []byte) bool { return true } diff --git a/core/test/governance.go b/core/test/governance.go index e486afe..0bcb39a 100644 --- a/core/test/governance.go +++ b/core/test/governance.go @@ -67,7 +67,8 @@ func NewGovernance(nodeCount int, lambda time.Duration) ( // GetNotarySet implements Governance interface to return current // notary set. -func (g *Governance) GetNotarySet() (ret map[types.NodeID]struct{}) { +func (g *Governance) GetNotarySet(blockHeight uint64) ( + ret map[types.NodeID]struct{}) { // Return a cloned map. ret = make(map[types.NodeID]struct{}) for k := range g.notarySet { @@ -79,13 +80,13 @@ func (g *Governance) GetNotarySet() (ret map[types.NodeID]struct{}) { // GetConfiguration returns the configuration at a given block height. func (g *Governance) GetConfiguration(blockHeight uint64) *types.Config { return &types.Config{ - NumShards: 1, - NumChains: uint32(len(g.notarySet)), - GenesisCRS: "__ DEXON", - LambdaBA: g.lambdaBA, - LambdaDKG: g.lambdaDKG, - K: 0, - PhiRatio: 0.667, + CRS: []byte("__ DEXON"), + NumShards: 1, + NumChains: uint32(len(g.notarySet)), + LambdaBA: g.lambdaBA, + LambdaDKG: g.lambdaDKG, + K: 0, + PhiRatio: 0.667, } } diff --git a/core/test/tcp-transport.go b/core/test/tcp-transport.go index 8bbaf9c..0f9bd73 100644 --- a/core/test/tcp-transport.go +++ b/core/test/tcp-transport.go @@ -447,7 +447,7 @@ func (t *TCPTransportClient) Join( conn string ) for { - addr = net.JoinHostPort("0.0.0.0", strconv.Itoa(t.localPort)) + addr = net.JoinHostPort("127.0.0.1", strconv.Itoa(t.localPort)) ln, err = net.Listen("tcp", addr) if err == nil { break @@ -564,7 +564,7 @@ func (t *TCPTransportServer) Host() (chan *TransportEnvelope, error) { // if we can listen on the pre-defiend part, we don't have to // retry with other random ports. ln, err := net.Listen( - "tcp", net.JoinHostPort("0.0.0.0", strconv.Itoa(t.localPort))) + "tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(t.localPort))) if err != nil { return nil, err } diff --git a/core/test/transport_test.go b/core/test/transport_test.go index 1d4b53d..4d71fc8 100644 --- a/core/test/transport_test.go +++ b/core/test/transport_test.go @@ -242,7 +242,7 @@ func (s *TransportTestSuite) TestTCPLocal() { wg sync.WaitGroup latency = &FixedLatencyModel{Latency: 300} serverPort = 8080 - serverAddr = net.JoinHostPort("0.0.0.0", strconv.Itoa(serverPort)) + serverAddr = net.JoinHostPort("127.0.0.1", strconv.Itoa(serverPort)) server = &testPeerServer{ trans: NewTCPTransportServer(&testMarshaller{}, serverPort)} ) diff --git a/core/types/config.go b/core/types/config.go index 4f5bd6e..3c0bced 100644 --- a/core/types/config.go +++ b/core/types/config.go @@ -21,10 +21,12 @@ import "time" // Config stands for Current Configuration Parameters. type Config struct { + // CRS. + CRS []byte + // Network related. - NumShards uint32 - NumChains uint32 - GenesisCRS string + NumShards uint32 + NumChains uint32 // Lambda related. LambdaBA time.Duration diff --git a/integration_test/node.go b/integration_test/node.go index dff662e..118a38f 100644 --- a/integration_test/node.go +++ b/integration_test/node.go @@ -89,7 +89,7 @@ func NewNode( shardID = uint32(0) chainID = uint32(math.MaxUint32) governanceConfig = gov.GetConfiguration(0) - broadcastTargets = gov.GetNotarySet() + broadcastTargets = gov.GetNotarySet(0) nodeID = types.NewNodeID(privateKey.PublicKey()) ) hashes := common.Hashes{} diff --git a/integration_test/utils.go b/integration_test/utils.go index 7259ced..6a94a17 100644 --- a/integration_test/utils.go +++ b/integration_test/utils.go @@ -31,7 +31,7 @@ func PrepareNodes( if err != nil { return } - for nID := range gov.GetNotarySet() { + for nID := range gov.GetNotarySet(0) { apps[nID] = test.NewApp() if db, err = blockdb.NewMemBackedBlockDB(); err != nil { @@ -39,7 +39,7 @@ func PrepareNodes( } dbs[nID] = db } - for nID := range gov.GetNotarySet() { + for nID := range gov.GetNotarySet(0) { if key, err = gov.GetPrivateKey(nID); err != nil { return } diff --git a/simulation/app.go b/simulation/app.go index ab0bfcd..cb8c129 100644 --- a/simulation/app.go +++ b/simulation/app.go @@ -61,7 +61,7 @@ func (a *simApp) BlockConfirmed(_ common.Hash) { } // VerifyPayload implements core.Application. -func (a *simApp) VerifyPayload(payloads []byte) bool { +func (a *simApp) VerifyPayload(payload []byte) bool { return true } diff --git a/simulation/governance.go b/simulation/governance.go index 613205d..643c181 100644 --- a/simulation/governance.go +++ b/simulation/governance.go @@ -36,7 +36,7 @@ type simGovernance struct { k int phiRatio float32 chainNum uint32 - crs string + crs []byte dkgComplaint map[uint64][]*types.DKGComplaint dkgMasterPublicKey map[uint64][]*types.DKGMasterPublicKey lambdaBA time.Duration @@ -55,7 +55,7 @@ func newSimGovernance( k: consensusConfig.K, phiRatio: consensusConfig.PhiRatio, chainNum: consensusConfig.ChainNum, - crs: consensusConfig.GenesisCRS, + crs: []byte(consensusConfig.GenesisCRS), dkgComplaint: make(map[uint64][]*types.DKGComplaint), dkgMasterPublicKey: make(map[uint64][]*types.DKGMasterPublicKey), lambdaBA: time.Duration(consensusConfig.LambdaBA) * time.Millisecond, @@ -68,7 +68,8 @@ func (g *simGovernance) setNetwork(network *network) { } // GetNotarySet returns the current notary set. -func (g *simGovernance) GetNotarySet() map[types.NodeID]struct{} { +func (g *simGovernance) GetNotarySet( + blockHeight uint64) map[types.NodeID]struct{} { g.lock.RLock() defer g.lock.RUnlock() @@ -83,13 +84,13 @@ func (g *simGovernance) GetNotarySet() map[types.NodeID]struct{} { // GetConfiguration returns the configuration at a given block height. func (g *simGovernance) GetConfiguration(blockHeight uint64) *types.Config { return &types.Config{ - NumShards: 1, - NumChains: g.chainNum, - GenesisCRS: g.crs, - LambdaBA: g.lambdaBA, - LambdaDKG: g.lambdaDKG, - K: g.k, - PhiRatio: g.phiRatio, + NumShards: 1, + NumChains: g.chainNum, + CRS: g.crs, + LambdaBA: g.lambdaBA, + LambdaDKG: g.lambdaDKG, + K: g.k, + PhiRatio: g.phiRatio, } } |