aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/configuration-chain.go63
-rw-r--r--core/configuration-chain_test.go14
-rw-r--r--core/consensus.go6
-rw-r--r--core/crypto.go4
4 files changed, 68 insertions, 19 deletions
diff --git a/core/configuration-chain.go b/core/configuration-chain.go
index 5e5a587..bda2fdf 100644
--- a/core/configuration-chain.go
+++ b/core/configuration-chain.go
@@ -39,18 +39,22 @@ var (
)
type configurationChain struct {
- ID types.NodeID
- recv dkgReceiver
- gov Governance
- dkg *dkgProtocol
- logger common.Logger
- dkgLock sync.RWMutex
- dkgSigner map[uint64]*dkgShareSecret
- gpk map[uint64]*DKGGroupPublicKey
- dkgResult sync.RWMutex
- tsig map[common.Hash]*tsigProtocol
- tsigTouched map[common.Hash]struct{}
- tsigReady *sync.Cond
+ ID types.NodeID
+ recv dkgReceiver
+ gov Governance
+ dkg *dkgProtocol
+ logger common.Logger
+ dkgLock sync.RWMutex
+ dkgSigner map[uint64]*dkgShareSecret
+ gpk map[uint64]*DKGGroupPublicKey
+ dkgResult sync.RWMutex
+ tsig map[common.Hash]*tsigProtocol
+ tsigTouched map[common.Hash]struct{}
+ tsigReady *sync.Cond
+ cache *NodeSetCache
+ dkgSet map[types.NodeID]struct{}
+ mpkReady bool
+ pendingPrvShare map[types.NodeID]*typesDKG.PrivateShare
// TODO(jimmy-dexon): add timeout to pending psig.
pendingPsig map[common.Hash][]*typesDKG.PartialSignature
prevHash common.Hash
@@ -60,6 +64,7 @@ func newConfigurationChain(
ID types.NodeID,
recv dkgReceiver,
gov Governance,
+ cache *NodeSetCache,
logger common.Logger) *configurationChain {
return &configurationChain{
ID: ID,
@@ -71,6 +76,7 @@ func newConfigurationChain(
tsig: make(map[common.Hash]*tsigProtocol),
tsigTouched: make(map[common.Hash]struct{}),
tsigReady: sync.NewCond(&sync.Mutex{}),
+ cache: cache,
pendingPsig: make(map[common.Hash][]*typesDKG.PartialSignature),
}
}
@@ -78,6 +84,17 @@ func newConfigurationChain(
func (cc *configurationChain) registerDKG(round uint64, threshold int) {
cc.dkgLock.Lock()
defer cc.dkgLock.Unlock()
+ if cc.dkg != nil {
+ cc.logger.Error("Previous DKG is not finished")
+ }
+ dkgSet, err := cc.cache.GetDKGSet(round)
+ if err != nil {
+ cc.logger.Error("Error getting DKG set from cache", "error", err)
+ return
+ }
+ cc.dkgSet = dkgSet
+ cc.pendingPrvShare = make(map[types.NodeID]*typesDKG.PrivateShare)
+ cc.mpkReady = false
cc.dkg = newDKGProtocol(
cc.ID,
cc.recv,
@@ -107,6 +124,13 @@ func (cc *configurationChain) runDKG(round uint64) error {
// Phase 2(T = 0): Exchange DKG secret key share.
cc.logger.Debug("Calling Governance.DKGMasterPublicKeys", "round", round)
cc.dkg.processMasterPublicKeys(cc.gov.DKGMasterPublicKeys(round))
+ cc.mpkReady = true
+ for _, prvShare := range cc.pendingPrvShare {
+ if err := cc.dkg.processPrivateShare(prvShare); err != nil {
+ cc.logger.Error("Failed to process private share",
+ "error", err)
+ }
+ }
// Phase 3(T = 0~λ): Propose complaint.
// Propose complaint is done in `processMasterPublicKeys`.
cc.dkgLock.Unlock()
@@ -286,6 +310,21 @@ func (cc *configurationChain) processPrivateShare(
if cc.dkg == nil {
return nil
}
+ if _, exist := cc.dkgSet[prvShare.ProposerID]; !exist {
+ return ErrNotDKGParticipant
+ }
+ if !cc.mpkReady {
+ // TODO(jimmy-dexon): remove duplicated signature check in dkg module.
+ ok, err := verifyDKGPrivateShareSignature(prvShare)
+ if err != nil {
+ return err
+ }
+ if !ok {
+ return ErrIncorrectPrivateShareSignature
+ }
+ cc.pendingPrvShare[prvShare.ProposerID] = prvShare
+ return nil
+ }
return cc.dkg.processPrivateShare(prvShare)
}
diff --git a/core/configuration-chain_test.go b/core/configuration-chain_test.go
index e39afd5..6ddfeb9 100644
--- a/core/configuration-chain_test.go
+++ b/core/configuration-chain_test.go
@@ -166,11 +166,17 @@ func (s *ConfigurationChainTestSuite) runDKG(
cfgChains := make(map[types.NodeID]*configurationChain)
recv := newTestCCReceiver(s)
+ pks := make([]crypto.PublicKey, 0, len(s.prvKeys))
+ for _, prv := range s.prvKeys {
+ pks = append(pks, prv.PublicKey())
+ }
+
for _, nID := range s.nIDs {
- gov, err := test.NewGovernance(nil, 50*time.Millisecond)
+ gov, err := test.NewGovernance(pks, 50*time.Millisecond)
s.Require().NoError(err)
+ cache := NewNodeSetCache(gov)
cfgChains[nID] = newConfigurationChain(
- nID, recv, gov, &common.NullLogger{})
+ nID, recv, gov, cache, &common.NullLogger{})
recv.nodes[nID] = cfgChains[nID]
recv.govs[nID] = gov
}
@@ -225,7 +231,7 @@ func (s *ConfigurationChainTestSuite) preparePartialSignature(
// recovering threshold signature.
// All participants are good people in this test.
func (s *ConfigurationChainTestSuite) TestConfigurationChain() {
- k := 3
+ k := 4
n := 10
round := uint64(1)
cfgChains := s.runDKG(k, n, round)
@@ -253,7 +259,7 @@ func (s *ConfigurationChainTestSuite) TestConfigurationChain() {
}
for nID, cc := range cfgChains {
if _, exist := cc.gpk[round].qualifyNodeIDs[nID]; !exist {
- continue
+ s.FailNow("Should be qualifyied")
}
s.Require().NoError(<-errs)
tsig := <-tsigChan
diff --git a/core/consensus.go b/core/consensus.go
index 5c9823b..04dfe57 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -336,6 +336,7 @@ func NewConsensus(
ID,
recv,
gov,
+ nodeSetCache,
logger)
recv.cfgModule = cfgModule
// Construct Consensus instance.
@@ -1005,10 +1006,9 @@ func (con *Consensus) prepareBlock(b *types.Block,
if err = con.lattice.PrepareBlock(b, proposeTime); err != nil {
return
}
- // TODO(mission): decide CRS by block's round, which could be determined by
- // block's info (ex. position, timestamp).
con.logger.Debug("Calling Governance.CRS", "round", 0)
- if err = con.authModule.SignCRS(b, con.gov.CRS(0)); err != nil {
+ if err =
+ con.authModule.SignCRS(b, con.gov.CRS(b.Position.Round)); err != nil {
return
}
return
diff --git a/core/crypto.go b/core/crypto.go
index 2b7f7a7..914ca08 100644
--- a/core/crypto.go
+++ b/core/crypto.go
@@ -121,11 +121,15 @@ 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)
+
binaryHeight := make([]byte, 8)
binary.LittleEndian.PutUint64(binaryHeight, position.Height)
return crypto.Keccak256Hash(
binaryChainID,
+ binaryRound,
binaryHeight,
)
}