aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-09-25 18:52:35 +0800
committermissionliao <38416648+missionliao@users.noreply.github.com>2018-09-25 18:52:35 +0800
commit0ffea9dadcfc0d8a740942a2d666eccc00613cd4 (patch)
tree7984fd6c5a58abc96b1a808efb89806d48612299 /core
parentd844c339a128322dff180a6ccc6e6b241e917546 (diff)
downloaddexon-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)
Diffstat (limited to 'core')
-rw-r--r--core/agreement-state_test.go2
-rw-r--r--core/agreement_test.go2
-rw-r--r--core/consensus.go122
-rw-r--r--core/consensus_test.go6
-rw-r--r--core/interfaces.go13
-rw-r--r--core/leader-selector.go4
-rw-r--r--core/leader-selector_test.go2
-rw-r--r--core/nonblocking.go4
-rw-r--r--core/test/app.go2
-rw-r--r--core/test/governance.go17
-rw-r--r--core/test/tcp-transport.go4
-rw-r--r--core/test/transport_test.go2
-rw-r--r--core/types/config.go8
13 files changed, 108 insertions, 80 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