aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-12-22 12:54:03 +0800
committerGitHub <noreply@github.com>2018-12-22 12:54:03 +0800
commit6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6 (patch)
tree1895248f011a356fcd2a28c03dbda9d93fd46fd8
parent146ed32cf841151b826eafd7d6ade188c56865bf (diff)
downloaddexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.gz
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.bz2
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.lz
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.xz
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.tar.zst
dexon-consensus-6d1c1aeea0d3e75d10cbb2712c68b4c422ba8ba6.zip
utils: move authenticator to utils package (#378)
-rw-r--r--core/agreement-mgr.go6
-rw-r--r--core/agreement-state_test.go17
-rw-r--r--core/agreement.go11
-rw-r--r--core/agreement_test.go23
-rw-r--r--core/authenticator.go156
-rw-r--r--core/configuration-chain.go4
-rw-r--r--core/configuration-chain_test.go250
-rw-r--r--core/consensus.go42
-rw-r--r--core/consensus_test.go15
-rw-r--r--core/dkg-tsig-protocol.go14
-rw-r--r--core/dkg-tsig-protocol_test.go45
-rw-r--r--core/lattice-data_test.go4
-rw-r--r--core/lattice.go45
-rw-r--r--core/lattice_test.go12
-rw-r--r--core/leader-selector.go3
-rw-r--r--core/leader-selector_test.go7
-rw-r--r--core/syncer/consensus.go2
-rw-r--r--core/test/block-revealer_test.go2
-rw-r--r--core/test/blocks-generator.go29
-rw-r--r--core/test/blocks-generator_test.go16
-rw-r--r--core/test/state-change-request.go8
-rw-r--r--core/test/state.go12
-rw-r--r--core/test/state_test.go32
-rw-r--r--core/test/utils.go33
-rw-r--r--core/total-ordering-syncer_test.go2
-rw-r--r--core/total-ordering_test.go8
-rw-r--r--core/utils.go23
-rw-r--r--core/utils/crypto.go (renamed from core/crypto.go)49
-rw-r--r--core/utils/crypto_test.go (renamed from core/crypto_test.go)35
-rw-r--r--core/utils/signer.go126
-rw-r--r--core/utils/signer_test.go (renamed from core/authenticator_test.go)30
-rw-r--r--core/utils_test.go22
-rw-r--r--integration_test/node.go2
33 files changed, 487 insertions, 598 deletions
diff --git a/core/agreement-mgr.go b/core/agreement-mgr.go
index fb65364..a9fa21d 100644
--- a/core/agreement-mgr.go
+++ b/core/agreement-mgr.go
@@ -86,7 +86,7 @@ type agreementMgr struct {
network Network
logger common.Logger
cache *utils.NodeSetCache
- auth *Authenticator
+ signer *utils.Signer
lattice *Lattice
ctx context.Context
lastEndTime time.Time
@@ -119,7 +119,7 @@ func newAgreementMgr(con *Consensus, initRound uint64,
network: con.network,
logger: con.logger,
cache: con.nodeSetCache,
- auth: con.authModule,
+ signer: con.signer,
lattice: con.lattice,
ctx: con.ctx,
initRound: initRound,
@@ -181,7 +181,7 @@ func (mgr *agreementMgr) appendConfig(
mgr.con.ID,
recv,
newLeaderSelector(genValidLeader(mgr), mgr.logger),
- mgr.auth)
+ mgr.signer)
// Hacky way to make agreement module self contained.
recv.agreementModule = agrModule
mgr.baModules = append(mgr.baModules, agrModule)
diff --git a/core/agreement-state_test.go b/core/agreement-state_test.go
index 6537d1b..bb624ea 100644
--- a/core/agreement-state_test.go
+++ b/core/agreement-state_test.go
@@ -25,12 +25,13 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
type AgreementStateTestSuite struct {
suite.Suite
ID types.NodeID
- auths map[types.NodeID]*Authenticator
+ signers map[types.NodeID]*utils.Signer
voteChan chan *types.Vote
blockChan chan common.Hash
confirmChan chan common.Hash
@@ -65,7 +66,7 @@ func (s *AgreementStateTestSuite) proposeBlock(
ProposerID: s.ID,
Hash: common.NewRandomHash(),
}
- s.Require().NoError(s.auths[s.ID].SignCRS(block, leader.hashCRS))
+ s.Require().NoError(s.signers[s.ID].SignCRS(block, leader.hashCRS))
s.block[block.Hash] = block
return block
}
@@ -75,7 +76,7 @@ func (s *AgreementStateTestSuite) prepareVote(
period uint64) (
vote *types.Vote) {
vote = types.NewVote(voteType, blockHash, period)
- s.Require().NoError(s.auths[nID].SignVote(vote))
+ s.Require().NoError(s.signers[nID].SignVote(vote))
return
}
@@ -83,8 +84,8 @@ func (s *AgreementStateTestSuite) SetupTest() {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
s.ID = types.NewNodeID(prvKey.PublicKey())
- s.auths = map[types.NodeID]*Authenticator{
- s.ID: NewAuthenticator(prvKey),
+ s.signers = map[types.NodeID]*utils.Signer{
+ s.ID: utils.NewSigner(prvKey),
}
s.voteChan = make(chan *types.Vote, 100)
s.blockChan = make(chan common.Hash, 100)
@@ -102,7 +103,7 @@ func (s *AgreementStateTestSuite) newAgreement(numNode int) *agreement {
s.Require().NoError(err)
nID := types.NewNodeID(prvKey.PublicKey())
notarySet[nID] = struct{}{}
- s.auths[nID] = NewAuthenticator(prvKey)
+ s.signers[nID] = utils.NewSigner(prvKey)
}
notarySet[s.ID] = struct{}{}
agreement := newAgreement(
@@ -112,7 +113,7 @@ func (s *AgreementStateTestSuite) newAgreement(numNode int) *agreement {
leader: leader,
},
leader,
- s.auths[s.ID],
+ s.signers[s.ID],
)
agreement.restart(notarySet, types.Position{}, common.NewRandomHash())
return agreement
@@ -147,7 +148,7 @@ func (s *AgreementStateTestSuite) TestPreCommitState() {
prv, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
blocks[i].ProposerID = types.NewNodeID(prv.PublicKey())
- s.Require().NoError(NewAuthenticator(prv).SignCRS(
+ s.Require().NoError(utils.NewSigner(prv).SignCRS(
blocks[i], a.data.leader.hashCRS))
s.Require().NoError(a.processBlock(blocks[i]))
}
diff --git a/core/agreement.go b/core/agreement.go
index 4fb0dea..eead462 100644
--- a/core/agreement.go
+++ b/core/agreement.go
@@ -26,6 +26,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
// Errors for agreement module.
@@ -112,7 +113,7 @@ type agreement struct {
pendingVote []pendingVote
candidateBlock map[common.Hash]*types.Block
fastForward chan uint64
- authModule *Authenticator
+ signer *utils.Signer
}
// newAgreement creates a agreement instance.
@@ -120,7 +121,7 @@ func newAgreement(
ID types.NodeID,
recv agreementReceiver,
leader *leaderSelector,
- authModule *Authenticator) *agreement {
+ signer *utils.Signer) *agreement {
agreement := &agreement{
data: &agreementData{
recv: recv,
@@ -130,7 +131,7 @@ func newAgreement(
aID: &atomic.Value{},
candidateBlock: make(map[common.Hash]*types.Block),
fastForward: make(chan uint64, 1),
- authModule: authModule,
+ signer: signer,
}
agreement.stop()
return agreement
@@ -268,7 +269,7 @@ func (a *agreement) sanityCheck(vote *types.Vote) error {
if _, exist := a.notarySet[vote.ProposerID]; !exist {
return ErrNotInNotarySet
}
- ok, err := verifyVoteSignature(vote)
+ ok, err := utils.VerifyVoteSignature(vote)
if err != nil {
return err
}
@@ -299,7 +300,7 @@ func (a *agreement) checkForkVote(vote *types.Vote) error {
// prepareVote prepares a vote.
func (a *agreement) prepareVote(vote *types.Vote) (err error) {
vote.Position = a.agreementID()
- err = a.authModule.SignVote(vote)
+ err = a.signer.SignVote(vote)
return
}
diff --git a/core/agreement_test.go b/core/agreement_test.go
index 52c9e4d..9bdc4f8 100644
--- a/core/agreement_test.go
+++ b/core/agreement_test.go
@@ -23,6 +23,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
"github.com/stretchr/testify/suite"
)
@@ -61,7 +62,7 @@ func (s *AgreementTestSuite) proposeBlock(
Hash: common.NewRandomHash(),
}
s.block[block.Hash] = block
- s.Require().NoError(s.auths[s.ID].SignCRS(
+ s.Require().NoError(s.signers[s.ID].SignCRS(
block, s.agreement[agreementIdx].data.leader.hashCRS))
return block
}
@@ -69,7 +70,7 @@ func (s *AgreementTestSuite) proposeBlock(
type AgreementTestSuite struct {
suite.Suite
ID types.NodeID
- auths map[types.NodeID]*Authenticator
+ signers map[types.NodeID]*utils.Signer
voteChan chan *types.Vote
blockChan chan common.Hash
confirmChan chan common.Hash
@@ -82,8 +83,8 @@ func (s *AgreementTestSuite) SetupTest() {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
s.ID = types.NewNodeID(prvKey.PublicKey())
- s.auths = map[types.NodeID]*Authenticator{
- s.ID: NewAuthenticator(prvKey),
+ s.signers = map[types.NodeID]*utils.Signer{
+ s.ID: utils.NewSigner(prvKey),
}
s.voteChan = make(chan *types.Vote, 100)
s.blockChan = make(chan common.Hash, 100)
@@ -103,7 +104,7 @@ func (s *AgreementTestSuite) newAgreement(numNotarySet int) *agreement {
s.Require().NoError(err)
nID := types.NewNodeID(prvKey.PublicKey())
notarySet[nID] = struct{}{}
- s.auths[nID] = NewAuthenticator(prvKey)
+ s.signers[nID] = utils.NewSigner(prvKey)
}
notarySet[s.ID] = struct{}{}
agreement := newAgreement(
@@ -113,7 +114,7 @@ func (s *AgreementTestSuite) newAgreement(numNotarySet int) *agreement {
agreementIndex: agreementIdx,
},
leader,
- s.auths[s.ID],
+ s.signers[s.ID],
)
agreement.restart(notarySet, types.Position{}, common.NewRandomHash())
s.agreement = append(s.agreement, agreement)
@@ -123,7 +124,7 @@ func (s *AgreementTestSuite) newAgreement(numNotarySet int) *agreement {
func (s *AgreementTestSuite) copyVote(
vote *types.Vote, proposer types.NodeID) *types.Vote {
v := vote.Clone()
- s.auths[proposer].SignVote(v)
+ s.signers[proposer].SignVote(v)
return v
}
@@ -132,7 +133,7 @@ func (s *AgreementTestSuite) prepareVote(
period uint64) (
vote *types.Vote) {
vote = types.NewVote(voteType, blockHash, period)
- s.Require().NoError(s.auths[nID].SignVote(vote))
+ s.Require().NoError(s.signers[nID].SignVote(vote))
return
}
@@ -156,7 +157,7 @@ func (s *AgreementTestSuite) TestSimpleConfirm() {
vote = <-s.voteChan
s.Equal(types.VotePreCom, vote.Type)
s.Equal(blockHash, vote.BlockHash)
- for nID := range s.auths {
+ for nID := range s.signers {
v := s.copyVote(vote, nID)
s.Require().NoError(a.processVote(v))
}
@@ -168,7 +169,7 @@ func (s *AgreementTestSuite) TestSimpleConfirm() {
s.Equal(blockHash, vote.BlockHash)
s.Equal(blockHash, a.data.lockValue)
s.Equal(uint64(1), a.data.lockRound)
- for nID := range s.auths {
+ for nID := range s.signers {
v := s.copyVote(vote, nID)
s.Require().NoError(a.processVote(v))
}
@@ -198,7 +199,7 @@ func (s *AgreementTestSuite) TestPartitionOnCommitVote() {
vote = <-s.voteChan
s.Equal(types.VotePreCom, vote.Type)
s.Equal(blockHash, vote.BlockHash)
- for nID := range s.auths {
+ for nID := range s.signers {
v := s.copyVote(vote, nID)
s.Require().NoError(a.processVote(v))
}
diff --git a/core/authenticator.go b/core/authenticator.go
deleted file mode 100644
index 8e57f71..0000000
--- a/core/authenticator.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2018 The dexon-consensus Authors
-// This file is part of the dexon-consensus library.
-//
-// The dexon-consensus library is free software: you can redistribute it
-// and/or modify it under the terms of the GNU Lesser General Public License as
-// published by the Free Software Foundation, either version 3 of the License,
-// or (at your option) any later version.
-//
-// The dexon-consensus library is distributed in the hope that it will be
-// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
-// General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the dexon-consensus library. If not, see
-// <http://www.gnu.org/licenses/>.
-
-package core
-
-import (
- "github.com/dexon-foundation/dexon-consensus/common"
- "github.com/dexon-foundation/dexon-consensus/core/crypto"
- "github.com/dexon-foundation/dexon-consensus/core/types"
- typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
-)
-
-// Authenticator verify data owner.
-type Authenticator struct {
- prvKey crypto.PrivateKey
- pubKey crypto.PublicKey
- proposerID types.NodeID
-}
-
-// NewAuthenticator constructs an Authenticator instance.
-func NewAuthenticator(prvKey crypto.PrivateKey) (auth *Authenticator) {
- auth = &Authenticator{
- prvKey: prvKey,
- pubKey: prvKey.PublicKey(),
- }
- auth.proposerID = types.NewNodeID(auth.pubKey)
- return
-}
-
-// SignBlock signs a types.Block.
-func (au *Authenticator) SignBlock(b *types.Block) (err error) {
- b.ProposerID = au.proposerID
- b.PayloadHash = crypto.Keccak256Hash(b.Payload)
- if b.Hash, err = hashBlock(b); err != nil {
- return
- }
- if b.Signature, err = au.prvKey.Sign(b.Hash); err != nil {
- return
- }
- return
-}
-
-// SignVote signs a types.Vote.
-func (au *Authenticator) SignVote(v *types.Vote) (err error) {
- v.ProposerID = au.proposerID
- v.Signature, err = au.prvKey.Sign(hashVote(v))
- return
-}
-
-// SignCRS signs CRS signature of types.Block.
-func (au *Authenticator) SignCRS(b *types.Block, crs common.Hash) (err error) {
- if b.ProposerID != au.proposerID {
- err = ErrInvalidProposerID
- return
- }
- b.CRSSignature, err = au.prvKey.Sign(hashCRS(b, crs))
- return
-}
-
-// SignDKGComplaint signs a DKG complaint.
-func (au *Authenticator) SignDKGComplaint(
- complaint *typesDKG.Complaint) (err error) {
- complaint.ProposerID = au.proposerID
- complaint.Signature, err = au.prvKey.Sign(hashDKGComplaint(complaint))
- return
-}
-
-// SignDKGMasterPublicKey signs a DKG master public key.
-func (au *Authenticator) SignDKGMasterPublicKey(
- mpk *typesDKG.MasterPublicKey) (err error) {
- mpk.ProposerID = au.proposerID
- mpk.Signature, err = au.prvKey.Sign(hashDKGMasterPublicKey(mpk))
- return
-}
-
-// SignDKGPrivateShare signs a DKG private share.
-func (au *Authenticator) SignDKGPrivateShare(
- prvShare *typesDKG.PrivateShare) (err error) {
- prvShare.ProposerID = au.proposerID
- prvShare.Signature, err = au.prvKey.Sign(hashDKGPrivateShare(prvShare))
- return
-}
-
-// SignDKGPartialSignature signs a DKG partial signature.
-func (au *Authenticator) SignDKGPartialSignature(
- pSig *typesDKG.PartialSignature) (err error) {
- pSig.ProposerID = au.proposerID
- pSig.Signature, err = au.prvKey.Sign(hashDKGPartialSignature(pSig))
- return
-}
-
-// SignDKGMPKReady signs a DKG ready message.
-func (au *Authenticator) SignDKGMPKReady(
- ready *typesDKG.MPKReady) (err error) {
- ready.ProposerID = au.proposerID
- ready.Signature, err = au.prvKey.Sign(hashDKGMPKReady(ready))
- return
-}
-
-// SignDKGFinalize signs a DKG finalize message.
-func (au *Authenticator) SignDKGFinalize(
- final *typesDKG.Finalize) (err error) {
- final.ProposerID = au.proposerID
- final.Signature, err = au.prvKey.Sign(hashDKGFinalize(final))
- return
-}
-
-// VerifyBlock verifies the signature of types.Block.
-func (au *Authenticator) VerifyBlock(b *types.Block) (err error) {
- payloadHash := crypto.Keccak256Hash(b.Payload)
- if payloadHash != b.PayloadHash {
- err = ErrIncorrectHash
- return
- }
- hash, err := hashBlock(b)
- if err != nil {
- return
- }
- if hash != b.Hash {
- err = ErrIncorrectHash
- return
- }
- pubKey, err := crypto.SigToPub(b.Hash, b.Signature)
- if err != nil {
- return
- }
- if !b.ProposerID.Equal(types.NewNodeID(pubKey)) {
- err = ErrIncorrectSignature
- return
- }
- return
-}
-
-// VerifyVote verifies the signature of types.Vote.
-func (au *Authenticator) VerifyVote(v *types.Vote) (bool, error) {
- return verifyVoteSignature(v)
-}
-
-// VerifyCRS verifies the CRS signature of types.Block.
-func (au *Authenticator) VerifyCRS(b *types.Block, crs common.Hash) (bool, error) {
- return verifyCRSSignature(b, crs)
-}
diff --git a/core/configuration-chain.go b/core/configuration-chain.go
index d341cb5..ad24e44 100644
--- a/core/configuration-chain.go
+++ b/core/configuration-chain.go
@@ -417,7 +417,7 @@ func (cc *configurationChain) processPrivateShare(
}
if !cc.mpkReady {
// TODO(jimmy-dexon): remove duplicated signature check in dkg module.
- ok, err := verifyDKGPrivateShareSignature(prvShare)
+ ok, err := utils.VerifyDKGPrivateShareSignature(prvShare)
if err != nil {
return err
}
@@ -435,7 +435,7 @@ func (cc *configurationChain) processPartialSignature(
cc.tsigReady.L.Lock()
defer cc.tsigReady.L.Unlock()
if _, exist := cc.tsig[psig.Hash]; !exist {
- ok, err := verifyDKGPartialSignatureSignature(psig)
+ ok, err := utils.VerifyDKGPartialSignatureSignature(psig)
if err != nil {
return err
}
diff --git a/core/configuration-chain_test.go b/core/configuration-chain_test.go
index 8becd25..1fe54bc 100644
--- a/core/configuration-chain_test.go
+++ b/core/configuration-chain_test.go
@@ -19,7 +19,6 @@ package core
import (
"bytes"
- "encoding/json"
"errors"
"sync"
"testing"
@@ -43,186 +42,152 @@ type ConfigurationChainTestSuite struct {
nIDs types.NodeIDs
dkgIDs map[types.NodeID]dkg.ID
- prvKeys map[types.NodeID]crypto.PrivateKey
+ signers map[types.NodeID]*utils.Signer
+ pubKeys []crypto.PublicKey
}
-type testCCReceiver struct {
+type testCCGlobalReceiver struct {
s *ConfigurationChainTestSuite
nodes map[types.NodeID]*configurationChain
govs map[types.NodeID]Governance
}
-func newTestCCReceiver(
- s *ConfigurationChainTestSuite) *testCCReceiver {
- return &testCCReceiver{
+func newTestCCGlobalReceiver(
+ s *ConfigurationChainTestSuite) *testCCGlobalReceiver {
+ return &testCCGlobalReceiver{
s: s,
nodes: make(map[types.NodeID]*configurationChain),
govs: make(map[types.NodeID]Governance),
}
}
-func (r *testCCReceiver) ProposeDKGComplaint(complaint *typesDKG.Complaint) {
- prvKey, exist := r.s.prvKeys[complaint.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
- }
- var err error
- complaint.Signature, err = prvKey.Sign(hashDKGComplaint(complaint))
- if err != nil {
- panic(err)
- }
+func (r *testCCGlobalReceiver) ProposeDKGComplaint(
+ complaint *typesDKG.Complaint) {
for _, gov := range r.govs {
- // Use Marshal/Unmarshal to do deep copy.
- data, err := json.Marshal(complaint)
- if err != nil {
- panic(err)
- }
- complaintCopy := &typesDKG.Complaint{}
- if err := json.Unmarshal(data, complaintCopy); err != nil {
- panic(err)
- }
- gov.AddDKGComplaint(complaintCopy.Round, complaintCopy)
+ gov.AddDKGComplaint(complaint.Round, test.CloneDKGComplaint(complaint))
}
}
-func (r *testCCReceiver) ProposeDKGMasterPublicKey(
+func (r *testCCGlobalReceiver) ProposeDKGMasterPublicKey(
mpk *typesDKG.MasterPublicKey) {
- prvKey, exist := r.s.prvKeys[mpk.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
- }
- var err error
- mpk.Signature, err = prvKey.Sign(hashDKGMasterPublicKey(mpk))
- if err != nil {
- panic(err)
- }
for _, gov := range r.govs {
- // Use Marshal/Unmarshal to do deep copy.
- data, err := json.Marshal(mpk)
- if err != nil {
- panic(err)
- }
- mpkCopy := typesDKG.NewMasterPublicKey()
- if err := json.Unmarshal(data, mpkCopy); err != nil {
- panic(err)
- }
- gov.AddDKGMasterPublicKey(mpkCopy.Round, mpkCopy)
+ gov.AddDKGMasterPublicKey(mpk.Round, test.CloneDKGMasterPublicKey(mpk))
}
}
-func (r *testCCReceiver) ProposeDKGPrivateShare(
+func (r *testCCGlobalReceiver) ProposeDKGPrivateShare(
prv *typesDKG.PrivateShare) {
go func() {
- prvKey, exist := r.s.prvKeys[prv.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
- }
- var err error
- prv.Signature, err = prvKey.Sign(hashDKGPrivateShare(prv))
- if err != nil {
- panic(err)
- }
receiver, exist := r.nodes[prv.ReceiverID]
if !exist {
panic(errors.New("should exist"))
}
- err = receiver.processPrivateShare(prv)
- if err != nil {
+ if err := receiver.processPrivateShare(prv); err != nil {
panic(err)
}
}()
}
-func (r *testCCReceiver) ProposeDKGAntiNackComplaint(
+func (r *testCCGlobalReceiver) ProposeDKGAntiNackComplaint(
prv *typesDKG.PrivateShare) {
go func() {
- prvKey, exist := r.s.prvKeys[prv.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
- }
- var err error
- prv.Signature, err = prvKey.Sign(hashDKGPrivateShare(prv))
- if err != nil {
- panic(err)
- }
for _, cc := range r.nodes {
- // Use Marshal/Unmarshal to do deep copy.
- data, err := json.Marshal(prv)
- if err != nil {
- panic(err)
- }
- prvCopy := &typesDKG.PrivateShare{}
- if err := json.Unmarshal(data, prvCopy); err != nil {
- panic(err)
- }
- err = cc.processPrivateShare(prvCopy)
- if err != nil {
+ if err := cc.processPrivateShare(
+ test.CloneDKGPrivateShare(prv)); err != nil {
panic(err)
}
}
}()
}
-func (r *testCCReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) {
- prvKey, exist := r.s.prvKeys[ready.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
- }
- var err error
- ready.Signature, err = prvKey.Sign(hashDKGMPKReady(ready))
- if err != nil {
- panic(err)
+func (r *testCCGlobalReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) {
+ for _, gov := range r.govs {
+ gov.AddDKGMPKReady(ready.Round, test.CloneDKGMPKReady(ready))
}
+}
+
+func (r *testCCGlobalReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
for _, gov := range r.govs {
- // Use Marshal/Unmarshal to do deep copy.
- data, err := json.Marshal(ready)
- if err != nil {
- panic(err)
- }
- readyCopy := &typesDKG.MPKReady{}
- if err := json.Unmarshal(data, readyCopy); err != nil {
- panic(err)
- }
- gov.AddDKGMPKReady(readyCopy.Round, readyCopy)
+ gov.AddDKGFinalize(final.Round, test.CloneDKGFinalize(final))
}
}
-func (r *testCCReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
- prvKey, exist := r.s.prvKeys[final.ProposerID]
- if !exist {
- panic(errors.New("should exist"))
+type testCCReceiver struct {
+ signer *utils.Signer
+ recv *testCCGlobalReceiver
+}
+
+func newTestCCReceiver(nID types.NodeID, recv *testCCGlobalReceiver) *testCCReceiver {
+ return &testCCReceiver{
+ signer: recv.s.signers[nID],
+ recv: recv,
}
- var err error
- final.Signature, err = prvKey.Sign(hashDKGFinalize(final))
- if err != nil {
+}
+
+func (r *testCCReceiver) ProposeDKGComplaint(
+ complaint *typesDKG.Complaint) {
+ if err := r.signer.SignDKGComplaint(complaint); err != nil {
panic(err)
}
- for _, gov := range r.govs {
- // Use Marshal/Unmarshal to do deep copy.
- data, err := json.Marshal(final)
- if err != nil {
- panic(err)
- }
- finalCopy := &typesDKG.Finalize{}
- if err := json.Unmarshal(data, finalCopy); err != nil {
+ r.recv.ProposeDKGComplaint(complaint)
+}
+
+func (r *testCCReceiver) ProposeDKGMasterPublicKey(
+ mpk *typesDKG.MasterPublicKey) {
+ if err := r.signer.SignDKGMasterPublicKey(mpk); err != nil {
+ panic(err)
+ }
+ r.recv.ProposeDKGMasterPublicKey(mpk)
+}
+
+func (r *testCCReceiver) ProposeDKGPrivateShare(
+ prv *typesDKG.PrivateShare) {
+ if err := r.signer.SignDKGPrivateShare(prv); err != nil {
+ panic(err)
+ }
+ r.recv.ProposeDKGPrivateShare(prv)
+}
+
+func (r *testCCReceiver) ProposeDKGAntiNackComplaint(
+ prv *typesDKG.PrivateShare) {
+ // We would need to propose anti nack complaint for private share from
+ // others. Only sign those private shares with zero length signature.
+ if len(prv.Signature.Signature) == 0 {
+ if err := r.signer.SignDKGPrivateShare(prv); err != nil {
panic(err)
}
- gov.AddDKGFinalize(finalCopy.Round, finalCopy)
}
+ r.recv.ProposeDKGAntiNackComplaint(prv)
+}
+
+func (r *testCCReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) {
+ if err := r.signer.SignDKGMPKReady(ready); err != nil {
+ panic(err)
+ }
+ r.recv.ProposeDKGMPKReady(ready)
+}
+
+func (r *testCCReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
+ if err := r.signer.SignDKGFinalize(final); err != nil {
+ panic(err)
+ }
+ r.recv.ProposeDKGFinalize(final)
}
func (s *ConfigurationChainTestSuite) setupNodes(n int) {
s.nIDs = make(types.NodeIDs, 0, n)
- s.prvKeys = make(map[types.NodeID]crypto.PrivateKey, n)
+ s.signers = make(map[types.NodeID]*utils.Signer, n)
s.dkgIDs = make(map[types.NodeID]dkg.ID)
+ s.pubKeys = nil
ids := make(dkg.IDs, 0, n)
for i := 0; i < n; i++ {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
nID := types.NewNodeID(prvKey.PublicKey())
s.nIDs = append(s.nIDs, nID)
- s.prvKeys[nID] = prvKey
+ s.signers[nID] = utils.NewSigner(prvKey)
+ s.pubKeys = append(s.pubKeys, prvKey.PublicKey())
id := dkg.NewID(nID.Hash[:])
ids = append(ids, id)
s.dkgIDs[nID] = id
@@ -234,22 +199,19 @@ func (s *ConfigurationChainTestSuite) runDKG(
s.setupNodes(n)
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())
- }
+ recv := newTestCCGlobalReceiver(s)
for _, nID := range s.nIDs {
gov, err := test.NewGovernance(test.NewState(
- pks, 100*time.Millisecond, &common.NullLogger{}, true), ConfigRoundShift)
+ s.pubKeys, 100*time.Millisecond, &common.NullLogger{}, true,
+ ), ConfigRoundShift)
s.Require().NoError(err)
cache := utils.NewNodeSetCache(gov)
dbInst, err := db.NewMemBackedDB()
s.Require().NoError(err)
- cfgChains[nID] = newConfigurationChain(
- nID, recv, gov, cache, dbInst, &common.NullLogger{})
+ cfgChains[nID] = newConfigurationChain(nID,
+ newTestCCReceiver(nID, recv), gov, cache, dbInst,
+ &common.NullLogger{})
recv.nodes[nID] = cfgChains[nID]
recv.govs[nID] = gov
}
@@ -293,9 +255,9 @@ func (s *ConfigurationChainTestSuite) preparePartialSignature(
}
psig, err := cc.preparePartialSignature(round, hash)
s.Require().NoError(err)
- prvKey, exist := s.prvKeys[cc.ID]
+ signer, exist := s.signers[cc.ID]
s.Require().True(exist)
- psig.Signature, err = prvKey.Sign(hashDKGPartialSignature(psig))
+ err = signer.SignDKGPartialSignature(psig)
s.Require().NoError(err)
psigs = append(psigs, psig)
}
@@ -359,18 +321,12 @@ func (s *ConfigurationChainTestSuite) TestDKGMasterPublicKeyDelayAdd() {
s.setupNodes(n)
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())
- }
-
+ recv := newTestCCGlobalReceiver(s)
delayNode := s.nIDs[0]
for _, nID := range s.nIDs {
state := test.NewState(
- pks, 100*time.Millisecond, &common.NullLogger{}, true)
+ s.pubKeys, 100*time.Millisecond, &common.NullLogger{}, true)
gov, err := test.NewGovernance(state, ConfigRoundShift)
s.Require().NoError(err)
s.Require().NoError(state.RequestChange(
@@ -379,7 +335,8 @@ func (s *ConfigurationChainTestSuite) TestDKGMasterPublicKeyDelayAdd() {
dbInst, err := db.NewMemBackedDB()
s.Require().NoError(err)
cfgChains[nID] = newConfigurationChain(
- nID, recv, gov, cache, dbInst, &common.NullLogger{})
+ nID, newTestCCReceiver(nID, recv), gov, cache, dbInst,
+ &common.NullLogger{})
recv.nodes[nID] = cfgChains[nID]
recv.govs[nID] = gov
}
@@ -430,16 +387,11 @@ func (s *ConfigurationChainTestSuite) TestDKGComplaintDelayAdd() {
s.setupNodes(n)
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())
- }
-
+ recv := newTestCCGlobalReceiver(s)
+ recvs := make(map[types.NodeID]*testCCReceiver)
for _, nID := range s.nIDs {
state := test.NewState(
- pks, 100*time.Millisecond, &common.NullLogger{}, true)
+ s.pubKeys, 100*time.Millisecond, &common.NullLogger{}, true)
gov, err := test.NewGovernance(state, ConfigRoundShift)
s.Require().NoError(err)
s.Require().NoError(state.RequestChange(
@@ -447,8 +399,9 @@ func (s *ConfigurationChainTestSuite) TestDKGComplaintDelayAdd() {
cache := utils.NewNodeSetCache(gov)
dbInst, err := db.NewMemBackedDB()
s.Require().NoError(err)
- cfgChains[nID] = newConfigurationChain(
- nID, recv, gov, cache, dbInst, &common.NullLogger{})
+ recvs[nID] = newTestCCReceiver(nID, recv)
+ cfgChains[nID] = newConfigurationChain(nID, recvs[nID], gov, cache,
+ dbInst, &common.NullLogger{})
recv.nodes[nID] = cfgChains[nID]
recv.govs[nID] = gov
}
@@ -479,9 +432,8 @@ func (s *ConfigurationChainTestSuite) TestDKGComplaintDelayAdd() {
if targetNode == nID {
continue
}
- recv.ProposeDKGComplaint(&typesDKG.Complaint{
- ProposerID: nID,
- Round: round,
+ recvs[nID].ProposeDKGComplaint(&typesDKG.Complaint{
+ Round: round,
PrivateShare: typesDKG.PrivateShare{
ProposerID: targetNode,
Round: round,
diff --git a/core/consensus.go b/core/consensus.go
index e45e4be..965a633 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -260,7 +260,7 @@ func (recv *consensusBAReceiver) PullBlocks(hashes common.Hashes) {
type consensusDKGReceiver struct {
ID types.NodeID
gov Governance
- authModule *Authenticator
+ signer *utils.Signer
nodeSetCache *utils.NodeSetCache
cfgModule *configurationChain
network Network
@@ -270,7 +270,7 @@ type consensusDKGReceiver struct {
// ProposeDKGComplaint proposes a DKGComplaint.
func (recv *consensusDKGReceiver) ProposeDKGComplaint(
complaint *typesDKG.Complaint) {
- if err := recv.authModule.SignDKGComplaint(complaint); err != nil {
+ if err := recv.signer.SignDKGComplaint(complaint); err != nil {
recv.logger.Error("Failed to sign DKG complaint", "error", err)
return
}
@@ -282,7 +282,7 @@ func (recv *consensusDKGReceiver) ProposeDKGComplaint(
// ProposeDKGMasterPublicKey propose a DKGMasterPublicKey.
func (recv *consensusDKGReceiver) ProposeDKGMasterPublicKey(
mpk *typesDKG.MasterPublicKey) {
- if err := recv.authModule.SignDKGMasterPublicKey(mpk); err != nil {
+ if err := recv.signer.SignDKGMasterPublicKey(mpk); err != nil {
recv.logger.Error("Failed to sign DKG master public key", "error", err)
return
}
@@ -293,7 +293,7 @@ func (recv *consensusDKGReceiver) ProposeDKGMasterPublicKey(
// ProposeDKGPrivateShare propose a DKGPrivateShare.
func (recv *consensusDKGReceiver) ProposeDKGPrivateShare(
prv *typesDKG.PrivateShare) {
- if err := recv.authModule.SignDKGPrivateShare(prv); err != nil {
+ if err := recv.signer.SignDKGPrivateShare(prv); err != nil {
recv.logger.Error("Failed to sign DKG private share", "error", err)
return
}
@@ -320,7 +320,7 @@ func (recv *consensusDKGReceiver) ProposeDKGPrivateShare(
func (recv *consensusDKGReceiver) ProposeDKGAntiNackComplaint(
prv *typesDKG.PrivateShare) {
if prv.ProposerID == recv.ID {
- if err := recv.authModule.SignDKGPrivateShare(prv); err != nil {
+ if err := recv.signer.SignDKGPrivateShare(prv); err != nil {
recv.logger.Error("Failed sign DKG private share", "error", err)
return
}
@@ -331,7 +331,7 @@ func (recv *consensusDKGReceiver) ProposeDKGAntiNackComplaint(
// ProposeDKGMPKReady propose a DKGMPKReady message.
func (recv *consensusDKGReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) {
- if err := recv.authModule.SignDKGMPKReady(ready); err != nil {
+ if err := recv.signer.SignDKGMPKReady(ready); err != nil {
recv.logger.Error("Failed to sign DKG ready", "error", err)
return
}
@@ -341,7 +341,7 @@ func (recv *consensusDKGReceiver) ProposeDKGMPKReady(ready *typesDKG.MPKReady) {
// ProposeDKGFinalize propose a DKGFinalize message.
func (recv *consensusDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
- if err := recv.authModule.SignDKGFinalize(final); err != nil {
+ if err := recv.signer.SignDKGFinalize(final); err != nil {
recv.logger.Error("Failed to sign DKG finalize", "error", err)
return
}
@@ -352,8 +352,8 @@ func (recv *consensusDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
// Consensus implements DEXON Consensus algorithm.
type Consensus struct {
// Node Info.
- ID types.NodeID
- authModule *Authenticator
+ ID types.NodeID
+ signer *utils.Signer
// BA.
baMgr *agreementMgr
@@ -401,8 +401,8 @@ func NewConsensus(
// TODO(w): load latest blockHeight from DB, and use config at that height.
nodeSetCache := utils.NewNodeSetCache(gov)
- // Setup auth module.
- authModule := NewAuthenticator(prv)
+ // Setup signer module.
+ signer := utils.NewSigner(prv)
// Check if the application implement Debug interface.
var debugApp Debug
if a, ok := app.(Debug); ok {
@@ -413,13 +413,13 @@ func NewConsensus(
config := utils.GetConfigWithPanic(gov, round, logger)
// Init lattice.
lattice := NewLattice(
- dMoment, round, config, authModule, app, debugApp, db, logger)
+ dMoment, round, config, signer, app, debugApp, db, logger)
// Init configuration chain.
ID := types.NewNodeID(prv.PublicKey())
recv := &consensusDKGReceiver{
ID: ID,
gov: gov,
- authModule: authModule,
+ signer: signer,
nodeSetCache: nodeSetCache,
network: network,
logger: logger,
@@ -447,7 +447,7 @@ func NewConsensus(
cfgModule: cfgModule,
dMoment: dMoment,
nodeSetCache: nodeSetCache,
- authModule: authModule,
+ signer: signer,
event: common.NewEvent(),
logger: logger,
}
@@ -479,14 +479,14 @@ func NewConsensusFromSyncer(
logger common.Logger) (*Consensus, error) {
// Setup the cache for node sets.
nodeSetCache := utils.NewNodeSetCache(gov)
- // Setup auth module.
- authModule := NewAuthenticator(prv)
+ // Setup signer module.
+ signer := utils.NewSigner(prv)
// Init configuration chain.
ID := types.NewNodeID(prv.PublicKey())
recv := &consensusDKGReceiver{
ID: ID,
gov: gov,
- authModule: authModule,
+ signer: signer,
nodeSetCache: nodeSetCache,
network: networkModule,
logger: logger,
@@ -518,7 +518,7 @@ func NewConsensusFromSyncer(
cfgModule: cfgModule,
dMoment: initRoundBeginTime,
nodeSetCache: nodeSetCache,
- authModule: authModule,
+ signer: signer,
event: common.NewEvent(),
logger: logger,
}
@@ -655,7 +655,7 @@ func (con *Consensus) runCRS(round uint64) {
round, utils.GetCRSWithPanic(con.gov, round, con.logger))
if err != nil {
con.logger.Error("Failed to prepare partial signature", "error", err)
- } else if err = con.authModule.SignDKGPartialSignature(psig); err != nil {
+ } else if err = con.signer.SignDKGPartialSignature(psig); err != nil {
con.logger.Error("Failed to sign DKG partial signature", "error", err)
} else if err = con.cfgModule.processPartialSignature(psig); err != nil {
con.logger.Error("Failed to process partial signature", "error", err)
@@ -933,7 +933,7 @@ func (con *Consensus) ProcessAgreementResult(
if err != nil {
return err
}
- if err = con.authModule.SignDKGPartialSignature(psig); err != nil {
+ if err = con.signer.SignDKGPartialSignature(psig); err != nil {
return err
}
if err = con.cfgModule.processPartialSignature(psig); err != nil {
@@ -1123,7 +1123,7 @@ func (con *Consensus) prepareBlock(b *types.Block,
err = ErrCRSNotReady
return
}
- if err = con.authModule.SignCRS(b, crs); err != nil {
+ if err = con.signer.SignCRS(b, crs); err != nil {
return
}
return
diff --git a/core/consensus_test.go b/core/consensus_test.go
index 7a87d12..40ee34b 100644
--- a/core/consensus_test.go
+++ b/core/consensus_test.go
@@ -31,6 +31,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/core/test"
"github.com/dexon-foundation/dexon-consensus/core/types"
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
// network implements core.Network.
@@ -589,9 +590,9 @@ func (s *ConsensusTestSuite) TestSyncBA() {
_, con := s.prepareConsensus(time.Now().UTC(), gov, prvKey, conn)
go con.Run()
hash := common.NewRandomHash()
- auths := make([]*Authenticator, 0, len(prvKeys))
+ signers := make([]*utils.Signer, 0, len(prvKeys))
for _, prvKey := range prvKeys {
- auths = append(auths, NewAuthenticator(prvKey))
+ signers = append(signers, utils.NewSigner(prvKey))
}
pos := types.Position{
Round: 0,
@@ -602,10 +603,10 @@ func (s *ConsensusTestSuite) TestSyncBA() {
BlockHash: hash,
Position: pos,
}
- for _, auth := range auths {
+ for _, signer := range signers {
vote := types.NewVote(types.VoteCom, hash, 0)
vote.Position = pos
- s.Require().NoError(auth.SignVote(vote))
+ s.Require().NoError(signer.SignVote(vote))
baResult.Votes = append(baResult.Votes, *vote)
}
// Make sure each agreement module is running. ProcessAgreementResult only
@@ -637,12 +638,12 @@ func (s *ConsensusTestSuite) TestSyncBA() {
baResult.Votes[0].Signature, err = prvKeys[0].Sign(common.NewRandomHash())
s.Require().NoError(err)
s.Equal(ErrIncorrectVoteSignature, con.ProcessAgreementResult(baResult))
- s.Require().NoError(auths[0].SignVote(&baResult.Votes[0]))
+ s.Require().NoError(signers[0].SignVote(&baResult.Votes[0]))
- for _, auth := range auths {
+ for _, signer := range signers {
vote := types.NewVote(types.VoteCom, hash, 0)
vote.Position = pos
- s.Require().NoError(auth.SignVote(vote))
+ s.Require().NoError(signer.SignVote(vote))
baResult.Votes = append(baResult.Votes, *vote)
}
s.Equal(ErrIncorrectVoteProposer, con.ProcessAgreementResult(baResult))
diff --git a/core/dkg-tsig-protocol.go b/core/dkg-tsig-protocol.go
index ef12cf9..492271e 100644
--- a/core/dkg-tsig-protocol.go
+++ b/core/dkg-tsig-protocol.go
@@ -155,7 +155,6 @@ func newDKGProtocol(
prvShare, pubShare := dkg.NewPrivateKeyShares(threshold)
recv.ProposeDKGMasterPublicKey(&typesDKG.MasterPublicKey{
- ProposerID: ID,
Round: round,
DKGID: newDKGID(ID),
PublicKeyShares: *pubShare,
@@ -195,7 +194,6 @@ func (d *dkgProtocol) processMasterPublicKeys(
return ErrIDShareNotFound
}
d.recv.ProposeDKGPrivateShare(&typesDKG.PrivateShare{
- ProposerID: d.ID,
ReceiverID: mpk.ProposerID,
Round: d.round,
PrivateShare: *share,
@@ -210,8 +208,7 @@ func (d *dkgProtocol) proposeNackComplaints() {
continue
}
d.recv.ProposeDKGComplaint(&typesDKG.Complaint{
- ProposerID: d.ID,
- Round: d.round,
+ Round: d.round,
PrivateShare: typesDKG.PrivateShare{
ProposerID: nID,
Round: d.round,
@@ -240,7 +237,6 @@ func (d *dkgProtocol) processNackComplaints(complaints []*typesDKG.Complaint) (
continue
}
d.recv.ProposeDKGAntiNackComplaint(&typesDKG.PrivateShare{
- ProposerID: d.ID,
ReceiverID: complaint.ProposerID,
Round: d.round,
PrivateShare: *share,
@@ -267,8 +263,7 @@ func (d *dkgProtocol) enforceNackComplaints(complaints []*typesDKG.Complaint) {
if _, exist :=
d.antiComplaintReceived[from][to]; !exist {
d.recv.ProposeDKGComplaint(&typesDKG.Complaint{
- ProposerID: d.ID,
- Round: d.round,
+ Round: d.round,
PrivateShare: typesDKG.PrivateShare{
ProposerID: to,
Round: d.round,
@@ -282,7 +277,7 @@ func (d *dkgProtocol) sanityCheck(prvShare *typesDKG.PrivateShare) error {
if _, exist := d.idMap[prvShare.ProposerID]; !exist {
return ErrNotDKGParticipant
}
- ok, err := verifyDKGPrivateShareSignature(prvShare)
+ ok, err := utils.VerifyDKGPrivateShareSignature(prvShare)
if err != nil {
return err
}
@@ -318,7 +313,6 @@ func (d *dkgProtocol) processPrivateShare(
return nil
}
complaint := &typesDKG.Complaint{
- ProposerID: d.ID,
Round: d.round,
PrivateShare: *prvShare,
}
@@ -546,7 +540,7 @@ func (tsig *tsigProtocol) sanityCheck(psig *typesDKG.PartialSignature) error {
if !exist {
return ErrNotQualifyDKGParticipant
}
- ok, err := verifyDKGPartialSignatureSignature(psig)
+ ok, err := utils.VerifyDKGPartialSignatureSignature(psig)
if err != nil {
return err
}
diff --git a/core/dkg-tsig-protocol_test.go b/core/dkg-tsig-protocol_test.go
index 1f0ddca..54118f6 100644
--- a/core/dkg-tsig-protocol_test.go
+++ b/core/dkg-tsig-protocol_test.go
@@ -29,6 +29,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/core/test"
"github.com/dexon-foundation/dexon-consensus/core/types"
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
type DKGTSIGProtocolTestSuite struct {
@@ -36,13 +37,13 @@ type DKGTSIGProtocolTestSuite struct {
nIDs types.NodeIDs
dkgIDs map[types.NodeID]dkg.ID
- prvKeys map[types.NodeID]crypto.PrivateKey
+ signers map[types.NodeID]*utils.Signer
}
type testDKGReceiver struct {
s *DKGTSIGProtocolTestSuite
- prvKey crypto.PrivateKey
+ signer *utils.Signer
complaints map[types.NodeID]*typesDKG.Complaint
mpk *typesDKG.MasterPublicKey
prvShare map[types.NodeID]*typesDKG.PrivateShare
@@ -51,11 +52,11 @@ type testDKGReceiver struct {
final []*typesDKG.Finalize
}
-func newTestDKGReceiver(
- s *DKGTSIGProtocolTestSuite, prvKey crypto.PrivateKey) *testDKGReceiver {
+func newTestDKGReceiver(s *DKGTSIGProtocolTestSuite,
+ signer *utils.Signer) *testDKGReceiver {
return &testDKGReceiver{
s: s,
- prvKey: prvKey,
+ signer: signer,
complaints: make(map[types.NodeID]*typesDKG.Complaint),
prvShare: make(map[types.NodeID]*typesDKG.PrivateShare),
antiComplaints: make(map[types.NodeID]*typesDKG.PrivateShare),
@@ -63,32 +64,32 @@ func newTestDKGReceiver(
}
func (r *testDKGReceiver) ProposeDKGComplaint(complaint *typesDKG.Complaint) {
- var err error
- complaint.Signature, err = r.prvKey.Sign(hashDKGComplaint(complaint))
+ complaint = test.CloneDKGComplaint(complaint)
+ err := r.signer.SignDKGComplaint(complaint)
r.s.Require().NoError(err)
r.complaints[complaint.PrivateShare.ProposerID] = complaint
}
func (r *testDKGReceiver) ProposeDKGMasterPublicKey(
mpk *typesDKG.MasterPublicKey) {
- var err error
- mpk.Signature, err = r.prvKey.Sign(hashDKGMasterPublicKey(mpk))
+ mpk = test.CloneDKGMasterPublicKey(mpk)
+ err := r.signer.SignDKGMasterPublicKey(mpk)
r.s.Require().NoError(err)
r.mpk = mpk
}
func (r *testDKGReceiver) ProposeDKGPrivateShare(
prv *typesDKG.PrivateShare) {
- var err error
- prv.Signature, err = r.prvKey.Sign(hashDKGPrivateShare(prv))
+ prv = test.CloneDKGPrivateShare(prv)
+ err := r.signer.SignDKGPrivateShare(prv)
r.s.Require().NoError(err)
r.prvShare[prv.ReceiverID] = prv
}
func (r *testDKGReceiver) ProposeDKGAntiNackComplaint(
prv *typesDKG.PrivateShare) {
- var err error
- prv.Signature, err = r.prvKey.Sign(hashDKGPrivateShare(prv))
+ prv = test.CloneDKGPrivateShare(prv)
+ err := r.signer.SignDKGPrivateShare(prv)
r.s.Require().NoError(err)
r.antiComplaints[prv.ReceiverID] = prv
}
@@ -103,7 +104,7 @@ func (r *testDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) {
func (s *DKGTSIGProtocolTestSuite) setupDKGParticipants(n int) {
s.nIDs = make(types.NodeIDs, 0, n)
- s.prvKeys = make(map[types.NodeID]crypto.PrivateKey, n)
+ s.signers = make(map[types.NodeID]*utils.Signer, n)
s.dkgIDs = make(map[types.NodeID]dkg.ID)
ids := make(dkg.IDs, 0, n)
for i := 0; i < n; i++ {
@@ -111,7 +112,7 @@ func (s *DKGTSIGProtocolTestSuite) setupDKGParticipants(n int) {
s.Require().NoError(err)
nID := types.NewNodeID(prvKey.PublicKey())
s.nIDs = append(s.nIDs, nID)
- s.prvKeys[nID] = prvKey
+ s.signers[nID] = utils.NewSigner(prvKey)
id := dkg.NewID(nID.Hash[:])
ids = append(ids, id)
s.dkgIDs[nID] = id
@@ -125,7 +126,7 @@ func (s *DKGTSIGProtocolTestSuite) newProtocols(k, n int, round uint64) (
receivers := make(map[types.NodeID]*testDKGReceiver, n)
protocols := make(map[types.NodeID]*dkgProtocol, n)
for _, nID := range s.nIDs {
- receivers[nID] = newTestDKGReceiver(s, s.prvKeys[nID])
+ receivers[nID] = newTestDKGReceiver(s, s.signers[nID])
protocols[nID] = newDKGProtocol(
nID,
receivers[nID],
@@ -233,8 +234,7 @@ func (s *DKGTSIGProtocolTestSuite) TestDKGTSIGProtocol() {
Hash: msgHash,
PartialSignature: shareSecret.sign(msgHash),
}
- var err error
- psig.Signature, err = s.prvKeys[nID].Sign(hashDKGPartialSignature(psig))
+ err := s.signers[nID].SignDKGPartialSignature(psig)
s.Require().NoError(err)
s.Require().NoError(tsig.processPartialSignature(psig))
if len(tsig.sigs) >= k {
@@ -288,7 +288,7 @@ func (s *DKGTSIGProtocolTestSuite) TestNackComplaint() {
complaint, exist := recv.complaints[byzantineID]
s.True(complaint.IsNack())
s.Require().True(exist)
- s.True(VerifyDKGComplaintSignature(complaint))
+ s.True(utils.VerifyDKGComplaintSignature(complaint))
}
}
@@ -669,8 +669,7 @@ func (s *DKGTSIGProtocolTestSuite) TestPartialSignature() {
case byzantineID3:
psig.Hash = common.NewRandomHash()
}
- var err error
- psig.Signature, err = s.prvKeys[nID].Sign(hashDKGPartialSignature(psig))
+ err := s.signers[nID].SignDKGPartialSignature(psig)
s.Require().NoError(err)
err = tsig.processPartialSignature(psig)
switch nID {
@@ -693,7 +692,7 @@ func (s *DKGTSIGProtocolTestSuite) TestPartialSignature() {
func (s *DKGTSIGProtocolTestSuite) TestProposeReady() {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
- recv := newTestDKGReceiver(s, prvKey)
+ recv := newTestDKGReceiver(s, utils.NewSigner(prvKey))
nID := types.NewNodeID(prvKey.PublicKey())
protocol := newDKGProtocol(nID, recv, 1, 2)
protocol.proposeMPKReady()
@@ -708,7 +707,7 @@ func (s *DKGTSIGProtocolTestSuite) TestProposeReady() {
func (s *DKGTSIGProtocolTestSuite) TestProposeFinalize() {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
- recv := newTestDKGReceiver(s, prvKey)
+ recv := newTestDKGReceiver(s, utils.NewSigner(prvKey))
nID := types.NewNodeID(prvKey.PublicKey())
protocol := newDKGProtocol(nID, recv, 1, 2)
protocol.proposeFinalize()
diff --git a/core/lattice-data_test.go b/core/lattice-data_test.go
index 1cd2c18..8252361 100644
--- a/core/lattice-data_test.go
+++ b/core/lattice-data_test.go
@@ -166,7 +166,7 @@ func (s *LatticeDataTestSuite) genTestCase1() (
// hashBlock is a helper to hash a block and check if any error.
func (s *LatticeDataTestSuite) hashBlock(b *types.Block) {
var err error
- b.Hash, err = hashBlock(b)
+ b.Hash, err = utils.HashBlock(b)
s.Require().Nil(err)
}
@@ -370,7 +370,7 @@ func (s *LatticeDataTestSuite) TestRandomlyGeneratedBlocks() {
gen := test.NewBlocksGenerator(&test.BlocksGeneratorConfig{
NumChains: genesisConfig.NumChains,
MinBlockTimeInterval: genesisConfig.MinBlockInterval,
- }, nil, hashBlock)
+ }, nil)
req.NoError(gen.Generate(
0,
genesisTime,
diff --git a/core/lattice.go b/core/lattice.go
index 8780bba..db19cf9 100644
--- a/core/lattice.go
+++ b/core/lattice.go
@@ -25,6 +25,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/db"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
// Errors for sanity check error.
@@ -34,15 +35,15 @@ var (
// Lattice represents a unit to produce a global ordering from multiple chains.
type Lattice struct {
- lock sync.RWMutex
- authModule *Authenticator
- app Application
- debug Debug
- pool blockPool
- data *latticeData
- toModule *totalOrdering
- ctModule *consensusTimestamp
- logger common.Logger
+ lock sync.RWMutex
+ signer *utils.Signer
+ app Application
+ debug Debug
+ pool blockPool
+ data *latticeData
+ toModule *totalOrdering
+ ctModule *consensusTimestamp
+ logger common.Logger
}
// NewLattice constructs an Lattice instance.
@@ -50,7 +51,7 @@ func NewLattice(
dMoment time.Time,
round uint64,
cfg *types.Config,
- authModule *Authenticator,
+ signer *utils.Signer,
app Application,
debug Debug,
db db.Database,
@@ -58,14 +59,14 @@ func NewLattice(
// Create genesis latticeDataConfig.
return &Lattice{
- authModule: authModule,
- app: app,
- debug: debug,
- pool: newBlockPool(cfg.NumChains),
- data: newLatticeData(db, dMoment, round, cfg),
- toModule: newTotalOrdering(dMoment, round, cfg),
- ctModule: newConsensusTimestamp(dMoment, round, cfg.NumChains),
- logger: logger,
+ signer: signer,
+ app: app,
+ debug: debug,
+ pool: newBlockPool(cfg.NumChains),
+ data: newLatticeData(db, dMoment, round, cfg),
+ toModule: newTotalOrdering(dMoment, round, cfg),
+ ctModule: newConsensusTimestamp(dMoment, round, cfg.NumChains),
+ logger: logger,
}
}
@@ -89,7 +90,7 @@ func (l *Lattice) PrepareBlock(
if b.Witness, err = l.app.PrepareWitness(b.Witness.Height); err != nil {
return
}
- if err = l.authModule.SignBlock(b); err != nil {
+ if err = l.signer.SignBlock(b); err != nil {
return
}
return
@@ -102,7 +103,7 @@ func (l *Lattice) PrepareEmptyBlock(b *types.Block) (err error) {
if err = l.data.prepareEmptyBlock(b); err != nil {
return
}
- if b.Hash, err = hashBlock(b); err != nil {
+ if b.Hash, err = utils.HashBlock(b); err != nil {
return
}
return
@@ -116,7 +117,7 @@ func (l *Lattice) SanityCheck(b *types.Block) (err error) {
if b.IsEmpty() {
// Only need to verify block's hash.
var hash common.Hash
- if hash, err = hashBlock(b); err != nil {
+ if hash, err = utils.HashBlock(b); err != nil {
return
}
if b.Hash != hash {
@@ -124,7 +125,7 @@ func (l *Lattice) SanityCheck(b *types.Block) (err error) {
}
} else {
// Verify block's signature.
- if err = l.authModule.VerifyBlock(b); err != nil {
+ if err = utils.VerifyBlockSignature(b); err != nil {
return
}
}
diff --git a/core/lattice_test.go b/core/lattice_test.go
index 0c9b018..99723d6 100644
--- a/core/lattice_test.go
+++ b/core/lattice_test.go
@@ -27,6 +27,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/core/db"
"github.com/dexon-foundation/dexon-consensus/core/test"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
"github.com/stretchr/testify/suite"
)
@@ -126,7 +127,7 @@ func (s *LatticeTestSuite) newTestLatticeMgr(
dMoment,
0,
cfg,
- NewAuthenticator(prvKey),
+ utils.NewSigner(prvKey),
app,
app,
dbInst,
@@ -224,7 +225,7 @@ func (s *LatticeTestSuite) TestSanityCheck() {
MinBlockInterval: 0,
}
lattice = s.newTestLatticeMgr(&cfg, time.Now().UTC()).lattice
- auth = lattice.authModule // Steal auth module from lattice, :(
+ signer = lattice.signer // Steal signer module from lattice, :(
req = s.Require()
err error
)
@@ -233,11 +234,12 @@ func (s *LatticeTestSuite) TestSanityCheck() {
Position: types.Position{ChainID: 0},
Timestamp: time.Now().UTC(),
}
- req.NoError(auth.SignBlock(b))
+ req.NoError(signer.SignBlock(b))
req.NoError(lattice.SanityCheck(b))
// A block with incorrect signature should not pass sanity check.
- b.Signature, err = auth.prvKey.Sign(common.NewRandomHash())
+ otherPrvKey, err := ecdsa.NewPrivateKey()
req.NoError(err)
+ b.Signature, err = otherPrvKey.Sign(common.NewRandomHash())
req.Equal(lattice.SanityCheck(b), ErrIncorrectSignature)
// A block with un-sorted acks should not pass sanity check.
b.Acks = common.NewSortedHashes(common.Hashes{
@@ -248,7 +250,7 @@ func (s *LatticeTestSuite) TestSanityCheck() {
common.NewRandomHash(),
})
b.Acks[0], b.Acks[1] = b.Acks[1], b.Acks[0]
- req.NoError(auth.SignBlock(b))
+ req.NoError(signer.SignBlock(b))
req.Equal(lattice.SanityCheck(b), ErrAcksNotSorted)
// A block with incorrect hash should not pass sanity check.
b.Hash = common.NewRandomHash()
diff --git a/core/leader-selector.go b/core/leader-selector.go
index a68f8ab..94d28fa 100644
--- a/core/leader-selector.go
+++ b/core/leader-selector.go
@@ -25,6 +25,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/crypto"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
// Errors for leader module.
@@ -121,7 +122,7 @@ func (l *leaderSelector) leaderBlockHash() common.Hash {
}
func (l *leaderSelector) processBlock(block *types.Block) error {
- ok, err := verifyCRSSignature(block, l.hashCRS)
+ ok, err := utils.VerifyCRSSignature(block, l.hashCRS)
if err != nil {
return err
}
diff --git a/core/leader-selector_test.go b/core/leader-selector_test.go
index 2edad60..71499d6 100644
--- a/core/leader-selector_test.go
+++ b/core/leader-selector_test.go
@@ -25,6 +25,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
type LeaderSelectorTestSuite struct {
@@ -105,7 +106,7 @@ func (s *LeaderSelectorTestSuite) TestLeaderBlockHash() {
Hash: common.NewRandomHash(),
}
s.Require().NoError(
- NewAuthenticator(prv).SignCRS(block, leader.hashCRS))
+ utils.NewSigner(prv).SignCRS(block, leader.hashCRS))
s.Require().NoError(leader.processBlock(block))
blocks[block.Hash] = block
}
@@ -133,7 +134,7 @@ func (s *LeaderSelectorTestSuite) TestValidLeaderFn() {
Hash: common.NewRandomHash(),
}
s.Require().NoError(
- NewAuthenticator(prv).SignCRS(block, leader.hashCRS))
+ utils.NewSigner(prv).SignCRS(block, leader.hashCRS))
s.Require().NoError(leader.processBlock(block))
blocks[block.Hash] = block
}
@@ -164,7 +165,7 @@ func (s *LeaderSelectorTestSuite) TestPotentialLeader() {
Hash: common.NewRandomHash(),
}
s.Require().NoError(
- NewAuthenticator(prv).SignCRS(block, leader.hashCRS))
+ utils.NewSigner(prv).SignCRS(block, leader.hashCRS))
ok, _ := leader.potentialLeader(block)
s.Require().NoError(leader.processBlock(block))
if i > 0 {
diff --git a/core/syncer/consensus.go b/core/syncer/consensus.go
index da9d352..43a9e21 100644
--- a/core/syncer/consensus.go
+++ b/core/syncer/consensus.go
@@ -127,7 +127,7 @@ func (con *Consensus) initConsensusObj(initBlock *types.Block) {
con.roundBeginTimes[con.latticeLastRound],
con.latticeLastRound,
cfg,
- core.NewAuthenticator(con.prv),
+ utils.NewSigner(con.prv),
con.app,
debugApp,
con.db,
diff --git a/core/test/block-revealer_test.go b/core/test/block-revealer_test.go
index ba4cf71..0e56eea 100644
--- a/core/test/block-revealer_test.go
+++ b/core/test/block-revealer_test.go
@@ -48,7 +48,7 @@ func (s *BlockRevealerTestSuite) SetupSuite() {
NumChains: 19,
MinBlockTimeInterval: 250 * time.Millisecond,
}
- gen := NewBlocksGenerator(config, nil, stableRandomHash)
+ gen := NewBlocksGenerator(config, nil)
s.Require().NoError(gen.Generate(
0,
genesisTime,
diff --git a/core/test/blocks-generator.go b/core/test/blocks-generator.go
index aab7f96..5f1dbea 100644
--- a/core/test/blocks-generator.go
+++ b/core/test/blocks-generator.go
@@ -24,10 +24,10 @@ import (
"time"
"github.com/dexon-foundation/dexon-consensus/common"
- "github.com/dexon-foundation/dexon-consensus/core/crypto"
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
"github.com/dexon-foundation/dexon-consensus/core/db"
"github.com/dexon-foundation/dexon-consensus/core/types"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
)
// ErrParentNotAcked would be raised when some block doesn't
@@ -39,13 +39,11 @@ var ErrParentNotAcked = errors.New("parent is not acked")
type nodeStatus struct {
blocks []*types.Block
genesisTime time.Time
- prvKey crypto.PrivateKey
+ signer *utils.Signer
tip *types.Block
nextAckingIndex map[types.NodeID]uint64
}
-type hashBlockFn func(*types.Block) (common.Hash, error)
-
// getAckedBlockHash would randomly pick one block between
// last acked one to current head.
func (ns *nodeStatus) getAckedBlockHash(
@@ -85,7 +83,6 @@ type nodeSetStatus struct {
nIDs []types.NodeID
randGen *rand.Rand
timePicker func(time.Time) time.Time
- hashBlock hashBlockFn
}
func newNodeSetStatus(
@@ -93,8 +90,7 @@ func newNodeSetStatus(
tips map[uint32]*types.Block,
round uint64,
genesisTime, endTime time.Time,
- timePicker func(time.Time) time.Time,
- hashBlock hashBlockFn) *nodeSetStatus {
+ timePicker func(time.Time) time.Time) *nodeSetStatus {
var (
status = make(map[types.NodeID]*nodeStatus)
proposerChain = make(map[types.NodeID]uint32)
@@ -110,7 +106,7 @@ func newNodeSetStatus(
status[nID] = &nodeStatus{
blocks: []*types.Block{},
genesisTime: genesisTime,
- prvKey: prvKey,
+ signer: utils.NewSigner(prvKey),
tip: tips[i],
nextAckingIndex: make(map[types.NodeID]uint64),
}
@@ -124,7 +120,6 @@ func newNodeSetStatus(
nIDs: nIDs,
randGen: rand.New(rand.NewSource(time.Now().UnixNano())),
timePicker: timePicker,
- hashBlock: hashBlock,
}
}
@@ -200,15 +195,8 @@ func (ns *nodeSetStatus) proposeBlock(
},
Timestamp: status.getNextBlockTime(ns.timePicker),
}
- newBlock.ProposerID = proposerID
newBlock.Acks = common.NewSortedHashes(acks)
- var err error
- newBlock.Hash, err = ns.hashBlock(newBlock)
- if err != nil {
- return nil, err
- }
- newBlock.Signature, err = status.prvKey.Sign(newBlock.Hash)
- if err != nil {
+ if err := status.signer.SignBlock(newBlock); err != nil {
return nil, err
}
status.blocks = append(status.blocks, newBlock)
@@ -276,7 +264,6 @@ type BlocksGenerator struct {
nodePicker func([]types.NodeID) types.NodeID
timePicker func(time.Time) time.Time
ackingCountGenerator func() int
- hashBlock hashBlockFn
}
// NewBlocksGenerator constructs BlockGenerator.
@@ -290,8 +277,7 @@ type BlocksGenerator struct {
// the nodeCount you provided with a normal distribution.
func NewBlocksGenerator(
config *BlocksGeneratorConfig,
- ackingCountGenerator func() int,
- hashBlock hashBlockFn) *BlocksGenerator {
+ ackingCountGenerator func() int) *BlocksGenerator {
if config.MinBlockTimeInterval == time.Duration(0) {
panic(errors.New("min block interval cannot be 0"))
}
@@ -307,7 +293,6 @@ func NewBlocksGenerator(
nodePicker: generateNodePicker(),
timePicker: timePicker,
ackingCountGenerator: ackingCountGenerator,
- hashBlock: hashBlock,
}
}
@@ -325,7 +310,7 @@ func (gen *BlocksGenerator) Generate(
}
}
status := newNodeSetStatus(gen.config.NumChains, tips, roundID,
- roundBegin, roundEnd, gen.timePicker, gen.hashBlock)
+ roundBegin, roundEnd, gen.timePicker)
// We would record the smallest height of block that could be acked
// from each node's point-of-view.
toAck := make(map[types.NodeID]map[types.NodeID]uint64)
diff --git a/core/test/blocks-generator_test.go b/core/test/blocks-generator_test.go
index d71cd62..bcbd749 100644
--- a/core/test/blocks-generator_test.go
+++ b/core/test/blocks-generator_test.go
@@ -39,7 +39,7 @@ func (s *BlocksGeneratorTestSuite) TestGenerate() {
NumChains: 19,
MinBlockTimeInterval: 200 * time.Millisecond,
}
- gen = NewBlocksGenerator(config, nil, stableRandomHash)
+ gen = NewBlocksGenerator(config, nil)
req = s.Require()
beginTime = time.Now().UTC()
endTime = beginTime.Add(time.Minute)
@@ -129,8 +129,7 @@ func (s *BlocksGeneratorTestSuite) TestGenerateWithMaxAckCount() {
// Generate with 0 acks.
dbInst, err := db.NewMemBackedDB()
req.NoError(err)
- gen := NewBlocksGenerator(
- config, MaxAckingCountGenerator(0), stableRandomHash)
+ gen := NewBlocksGenerator(config, MaxAckingCountGenerator(0))
req.NoError(gen.Generate(
0,
genesisTime,
@@ -153,8 +152,7 @@ func (s *BlocksGeneratorTestSuite) TestGenerateWithMaxAckCount() {
// Generate with acks as many as possible.
dbInst, err = db.NewMemBackedDB()
req.NoError(err)
- gen = NewBlocksGenerator(
- config, MaxAckingCountGenerator(config.NumChains), stableRandomHash)
+ gen = NewBlocksGenerator(config, MaxAckingCountGenerator(config.NumChains))
req.NoError(gen.Generate(
0,
genesisTime,
@@ -190,7 +188,7 @@ func (s *BlocksGeneratorTestSuite) TestFindTips() {
genesisTime = time.Now().UTC()
endTime = genesisTime.Add(100 * time.Second)
)
- gen := NewBlocksGenerator(config, nil, stableRandomHash)
+ gen := NewBlocksGenerator(config, nil)
dbInst, err := db.NewMemBackedDB()
req.NoError(err)
req.NoError(gen.Generate(
@@ -220,7 +218,7 @@ func (s *BlocksGeneratorTestSuite) TestConcateBlocksFromRounds() {
gen := NewBlocksGenerator(&BlocksGeneratorConfig{
NumChains: 4,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, MaxAckingCountGenerator(4), stableRandomHash)
+ }, MaxAckingCountGenerator(4))
req.NoError(gen.Generate(
0,
genesisTime,
@@ -233,7 +231,7 @@ func (s *BlocksGeneratorTestSuite) TestConcateBlocksFromRounds() {
gen = NewBlocksGenerator(&BlocksGeneratorConfig{
NumChains: 10,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, MaxAckingCountGenerator(10), stableRandomHash)
+ }, MaxAckingCountGenerator(10))
req.NoError(gen.Generate(
1,
genesisTime.Add(10*time.Second),
@@ -246,7 +244,7 @@ func (s *BlocksGeneratorTestSuite) TestConcateBlocksFromRounds() {
gen = NewBlocksGenerator(&BlocksGeneratorConfig{
NumChains: 7,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, MaxAckingCountGenerator(7), stableRandomHash)
+ }, MaxAckingCountGenerator(7))
req.NoError(gen.Generate(
2,
genesisTime.Add(20*time.Second),
diff --git a/core/test/state-change-request.go b/core/test/state-change-request.go
index 83119b5..687eef7 100644
--- a/core/test/state-change-request.go
+++ b/core/test/state-change-request.go
@@ -117,14 +117,14 @@ func (req *StateChangeRequest) Clone() (copied *StateChangeRequest) {
CRS: crsReq.CRS,
}
case StateAddDKGMPKReady:
- copied.Payload = cloneDKGMPKReady(req.Payload.(*typesDKG.MPKReady))
+ copied.Payload = CloneDKGMPKReady(req.Payload.(*typesDKG.MPKReady))
case StateAddDKGFinal:
- copied.Payload = cloneDKGFinalize(req.Payload.(*typesDKG.Finalize))
+ copied.Payload = CloneDKGFinalize(req.Payload.(*typesDKG.Finalize))
case StateAddDKGMasterPublicKey:
- copied.Payload = cloneDKGMasterPublicKey(
+ copied.Payload = CloneDKGMasterPublicKey(
req.Payload.(*typesDKG.MasterPublicKey))
case StateAddDKGComplaint:
- copied.Payload = cloneDKGComplaint(req.Payload.(*typesDKG.Complaint))
+ copied.Payload = CloneDKGComplaint(req.Payload.(*typesDKG.Complaint))
default:
copied.Payload = req.Payload
}
diff --git a/core/test/state.go b/core/test/state.go
index 3c24fb6..b834b11 100644
--- a/core/test/state.go
+++ b/core/test/state.go
@@ -476,7 +476,7 @@ func (s *State) Clone() (copied *State) {
for nID, comps := range complaintsForRound {
tmpComps := []*typesDKG.Complaint{}
for _, comp := range comps {
- tmpComps = append(tmpComps, cloneDKGComplaint(comp))
+ tmpComps = append(tmpComps, CloneDKGComplaint(comp))
}
copied.dkgComplaints[round][nID] = tmpComps
}
@@ -486,19 +486,19 @@ func (s *State) Clone() (copied *State) {
make(map[types.NodeID]*typesDKG.MasterPublicKey)
for nID, mKey := range mKeysForRound {
copied.dkgMasterPublicKeys[round][nID] =
- cloneDKGMasterPublicKey(mKey)
+ CloneDKGMasterPublicKey(mKey)
}
}
for round, readysForRound := range s.dkgReadys {
copied.dkgReadys[round] = make(map[types.NodeID]*typesDKG.MPKReady)
for nID, ready := range readysForRound {
- copied.dkgReadys[round][nID] = cloneDKGMPKReady(ready)
+ copied.dkgReadys[round][nID] = CloneDKGMPKReady(ready)
}
}
for round, finalsForRound := range s.dkgFinals {
copied.dkgFinals[round] = make(map[types.NodeID]*typesDKG.Finalize)
for nID, final := range finalsForRound {
- copied.dkgFinals[round][nID] = cloneDKGFinalize(final)
+ copied.dkgFinals[round][nID] = CloneDKGFinalize(final)
}
}
for _, crs := range s.crs {
@@ -825,7 +825,7 @@ func (s *State) DKGComplaints(round uint64) []*typesDKG.Complaint {
tmpComps := make([]*typesDKG.Complaint, 0, len(comps))
for _, compProp := range comps {
for _, comp := range compProp {
- tmpComps = append(tmpComps, cloneDKGComplaint(comp))
+ tmpComps = append(tmpComps, CloneDKGComplaint(comp))
}
}
return tmpComps
@@ -843,7 +843,7 @@ func (s *State) DKGMasterPublicKeys(round uint64) []*typesDKG.MasterPublicKey {
}
mpks := make([]*typesDKG.MasterPublicKey, 0, len(masterPublicKeys))
for _, mpk := range masterPublicKeys {
- mpks = append(mpks, cloneDKGMasterPublicKey(mpk))
+ mpks = append(mpks, CloneDKGMasterPublicKey(mpk))
}
return mpks
}
diff --git a/core/test/state_test.go b/core/test/state_test.go
index c05d41b..ad3d1c4 100644
--- a/core/test/state_test.go
+++ b/core/test/state_test.go
@@ -28,6 +28,7 @@ import (
"github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
"github.com/dexon-foundation/dexon-consensus/core/types"
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+ "github.com/dexon-foundation/dexon-consensus/core/utils"
"github.com/stretchr/testify/suite"
)
@@ -55,12 +56,9 @@ func (s *StateTestSuite) newDKGMasterPublicKey(
func (s *StateTestSuite) newDKGComplaint(round uint64) *typesDKG.Complaint {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
- pubKey := prvKey.PublicKey()
- nodeID := types.NewNodeID(pubKey)
- // TODO(mission): sign it, and it doesn't make sense to complaint self.
- return &typesDKG.Complaint{
- ProposerID: nodeID,
- Round: round,
+ nodeID := types.NewNodeID(prvKey.PublicKey())
+ comp := &typesDKG.Complaint{
+ Round: round,
PrivateShare: typesDKG.PrivateShare{
ProposerID: nodeID,
ReceiverID: nodeID,
@@ -68,29 +66,23 @@ func (s *StateTestSuite) newDKGComplaint(round uint64) *typesDKG.Complaint {
PrivateShare: *dkg.NewPrivateKey(),
},
}
+ s.Require().NoError(utils.NewSigner(prvKey).SignDKGComplaint(comp))
+ return comp
}
func (s *StateTestSuite) newDKGMPKReady(round uint64) *typesDKG.MPKReady {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
- pubKey := prvKey.PublicKey()
- nodeID := types.NewNodeID(pubKey)
- // TODO(mission): sign it.
- return &typesDKG.MPKReady{
- ProposerID: nodeID,
- Round: round,
- }
+ ready := &typesDKG.MPKReady{Round: round}
+ s.Require().NoError(utils.NewSigner(prvKey).SignDKGMPKReady(ready))
+ return ready
}
func (s *StateTestSuite) newDKGFinal(round uint64) *typesDKG.Finalize {
prvKey, err := ecdsa.NewPrivateKey()
s.Require().NoError(err)
- pubKey := prvKey.PublicKey()
- nodeID := types.NewNodeID(pubKey)
- // TODO(mission): sign it.
- return &typesDKG.Finalize{
- ProposerID: nodeID,
- Round: round,
- }
+ final := &typesDKG.Finalize{Round: round}
+ s.Require().NoError(utils.NewSigner(prvKey).SignDKGFinalize(final))
+ return final
}
func (s *StateTestSuite) compareNodes(node1, node2 []crypto.PublicKey) bool {
diff --git a/core/test/utils.go b/core/test/utils.go
index c6c08fc..84c90a9 100644
--- a/core/test/utils.go
+++ b/core/test/utils.go
@@ -33,13 +33,6 @@ import (
"github.com/dexon-foundation/dexon/rlp"
)
-func stableRandomHash(block *types.Block) (common.Hash, error) {
- if (block.Hash != common.Hash{}) {
- return block.Hash, nil
- }
- return common.NewRandomHash(), nil
-}
-
// GenerateRandomNodeIDs generates randomly a slices of types.NodeID.
func GenerateRandomNodeIDs(nodeCount int) (nIDs types.NodeIDs) {
nIDs = types.NodeIDs{}
@@ -121,7 +114,8 @@ func NewKeys(count int) (
return
}
-func cloneDKGComplaint(
+// CloneDKGComplaint clones a tpyesDKG.Complaint instance.
+func CloneDKGComplaint(
comp *typesDKG.Complaint) (copied *typesDKG.Complaint) {
b, err := rlp.EncodeToBytes(comp)
if err != nil {
@@ -134,7 +128,8 @@ func cloneDKGComplaint(
return
}
-func cloneDKGMasterPublicKey(mpk *typesDKG.MasterPublicKey) (
+// CloneDKGMasterPublicKey clones a typesDKG.MasterPublicKey instance.
+func CloneDKGMasterPublicKey(mpk *typesDKG.MasterPublicKey) (
copied *typesDKG.MasterPublicKey) {
b, err := rlp.EncodeToBytes(mpk)
if err != nil {
@@ -147,7 +142,8 @@ func cloneDKGMasterPublicKey(mpk *typesDKG.MasterPublicKey) (
return
}
-func cloneDKGMPKReady(ready *typesDKG.MPKReady) (
+// CloneDKGMPKReady clones a typesDKG.MPKReady instance.
+func CloneDKGMPKReady(ready *typesDKG.MPKReady) (
copied *typesDKG.MPKReady) {
b, err := rlp.EncodeToBytes(ready)
if err != nil {
@@ -160,7 +156,8 @@ func cloneDKGMPKReady(ready *typesDKG.MPKReady) (
return
}
-func cloneDKGFinalize(final *typesDKG.Finalize) (
+// CloneDKGFinalize clones a typesDKG.Finalize instance.
+func CloneDKGFinalize(final *typesDKG.Finalize) (
copied *typesDKG.Finalize) {
b, err := rlp.EncodeToBytes(final)
if err != nil {
@@ -173,6 +170,20 @@ func cloneDKGFinalize(final *typesDKG.Finalize) (
return
}
+// CloneDKGPrivateShare clones a typesDKG.PrivateShare instance.
+func CloneDKGPrivateShare(prvShare *typesDKG.PrivateShare) (
+ copied *typesDKG.PrivateShare) {
+ b, err := rlp.EncodeToBytes(prvShare)
+ if err != nil {
+ panic(err)
+ }
+ copied = &typesDKG.PrivateShare{}
+ if err = rlp.DecodeBytes(b, copied); err != nil {
+ panic(err)
+ }
+ return
+}
+
func cloneBlockRandomnessResult(rand *types.BlockRandomnessResult) (
copied *types.BlockRandomnessResult) {
b, err := rlp.EncodeToBytes(rand)
diff --git a/core/total-ordering-syncer_test.go b/core/total-ordering-syncer_test.go
index 208c1a3..79a6830 100644
--- a/core/total-ordering-syncer_test.go
+++ b/core/total-ordering-syncer_test.go
@@ -49,7 +49,7 @@ func (s *TotalOrderingSyncerTestSuite) genDeliverySet(numChains uint32) (
gen := test.NewBlocksGenerator(&test.BlocksGeneratorConfig{
NumChains: numChains,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, nil, hashBlock)
+ }, nil)
dbInst, err := db.NewMemBackedDB()
s.Require().NoError(err)
diff --git a/core/total-ordering_test.go b/core/total-ordering_test.go
index 511228e..846770b 100644
--- a/core/total-ordering_test.go
+++ b/core/total-ordering_test.go
@@ -957,7 +957,7 @@ func (s *TotalOrderingTestSuite) baseTestRandomlyGeneratedBlocks(
gen := test.NewBlocksGenerator(&test.BlocksGeneratorConfig{
NumChains: chainNum,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, ackingCountGenerator, hashBlock)
+ }, ackingCountGenerator)
dbInst, err := db.NewMemBackedDB()
req.NoError(err)
req.NoError(gen.Generate(
@@ -1089,7 +1089,7 @@ func (s *TotalOrderingTestSuite) baseTestForRoundChange(
begin := genesisTime
for roundID, config := range configs[:len(configs)-1] {
gen := test.NewBlocksGenerator(
- test.NewBlocksGeneratorConfig(config), nil, hashBlock)
+ test.NewBlocksGeneratorConfig(config), nil)
end := begin.Add(config.RoundInterval)
req.NoError(gen.Generate(uint64(roundID), begin, end, dbInst))
begin = end
@@ -1213,7 +1213,7 @@ func (s *TotalOrderingTestSuite) TestSync() {
gen := test.NewBlocksGenerator(&test.BlocksGeneratorConfig{
NumChains: numChains,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, nil, hashBlock)
+ }, nil)
dbInst, err := db.NewMemBackedDB()
req.NoError(err)
err = gen.Generate(0, genesisTime, genesisTime.Add(20*time.Second), dbInst)
@@ -1337,7 +1337,7 @@ func (s *TotalOrderingTestSuite) TestSyncWithConfigChange() {
gen := test.NewBlocksGenerator(&test.BlocksGeneratorConfig{
NumChains: cfg.NumChains,
MinBlockTimeInterval: 250 * time.Millisecond,
- }, nil, hashBlock)
+ }, nil)
err = gen.Generate(
uint64(i),
genesisTime.Add(time.Duration(i)*cfg.RoundInterval),
diff --git a/core/utils.go b/core/utils.go
index 671d680..838369c 100644
--- a/core/utils.go
+++ b/core/utils.go
@@ -146,27 +146,6 @@ func HashConfigurationBlock(
)
}
-// VerifyBlock verifies the signature of types.Block.
-func VerifyBlock(b *types.Block) (err error) {
- hash, err := hashBlock(b)
- if err != nil {
- return
- }
- if hash != b.Hash {
- err = ErrIncorrectHash
- return
- }
- pubKey, err := crypto.SigToPub(b.Hash, b.Signature)
- if err != nil {
- return
- }
- if !b.ProposerID.Equal(types.NewNodeID(pubKey)) {
- err = ErrIncorrectSignature
- return
- }
- return
-}
-
// VerifyAgreementResult perform sanity check against a types.AgreementResult
// instance.
func VerifyAgreementResult(
@@ -201,7 +180,7 @@ func VerifyAgreementResult(
if _, exist := notarySet[vote.ProposerID]; !exist {
return ErrIncorrectVoteProposer
}
- ok, err := verifyVoteSignature(&vote)
+ ok, err := utils.VerifyVoteSignature(&vote)
if err != nil {
return err
}
diff --git a/core/crypto.go b/core/utils/crypto.go
index d4a7f0e..6042411 100644
--- a/core/crypto.go
+++ b/core/utils/crypto.go
@@ -15,7 +15,7 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-package core
+package utils
import (
"encoding/binary"
@@ -34,7 +34,8 @@ func hashWitness(witness *types.Witness) (common.Hash, error) {
witness.Data), nil
}
-func hashBlock(block *types.Block) (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))
@@ -62,13 +63,31 @@ func hashBlock(block *types.Block) (common.Hash, error) {
return hash, nil
}
-func verifyBlockSignature(pubkey crypto.PublicKey,
- block *types.Block, sig crypto.Signature) (bool, error) {
- hash, err := hashBlock(block)
+// VerifyBlockSignature verifies the signature of types.Block.
+func VerifyBlockSignature(b *types.Block) (err error) {
+ payloadHash := crypto.Keccak256Hash(b.Payload)
+ if payloadHash != b.PayloadHash {
+ err = ErrIncorrectHash
+ return
+ }
+ hash, err := HashBlock(b)
if err != nil {
- return false, err
+ return
}
- return pubkey.VerifySignature(hash, sig), nil
+ if hash != b.Hash {
+ err = ErrIncorrectHash
+ return
+ }
+ pubKey, err := crypto.SigToPub(b.Hash, b.Signature)
+ if err != nil {
+ return
+ }
+ if !b.ProposerID.Equal(types.NewNodeID(pubKey)) {
+ err = ErrIncorrectSignature
+ return
+ }
+ return
+
}
func hashVote(vote *types.Vote) common.Hash {
@@ -87,7 +106,8 @@ func hashVote(vote *types.Vote) common.Hash {
return hash
}
-func verifyVoteSignature(vote *types.Vote) (bool, error) {
+// VerifyVoteSignature verifies the signature of types.Vote.
+func VerifyVoteSignature(vote *types.Vote) (bool, error) {
hash := hashVote(vote)
pubKey, err := crypto.SigToPub(hash, vote.Signature)
if err != nil {
@@ -104,7 +124,8 @@ func hashCRS(block *types.Block, crs common.Hash) common.Hash {
return crypto.Keccak256Hash(crs[:], hashPos[:])
}
-func verifyCRSSignature(block *types.Block, crs common.Hash) (
+// VerifyCRSSignature verifies the CRS signature of types.Block.
+func VerifyCRSSignature(block *types.Block, crs common.Hash) (
bool, error) {
hash := hashCRS(block, crs)
pubKey, err := crypto.SigToPub(hash, block.CRSSignature)
@@ -146,7 +167,9 @@ func hashDKGPrivateShare(prvShare *typesDKG.PrivateShare) common.Hash {
)
}
-func verifyDKGPrivateShareSignature(
+// VerifyDKGPrivateShareSignature verifies the signature of
+// typesDKG.PrivateShare.
+func VerifyDKGPrivateShareSignature(
prvShare *typesDKG.PrivateShare) (bool, error) {
hash := hashDKGPrivateShare(prvShare)
pubKey, err := crypto.SigToPub(hash, prvShare.Signature)
@@ -213,7 +236,7 @@ func VerifyDKGComplaintSignature(
return false, nil
}
if !complaint.IsNack() {
- return verifyDKGPrivateShareSignature(&complaint.PrivateShare)
+ return VerifyDKGPrivateShareSignature(&complaint.PrivateShare)
}
return true, nil
}
@@ -230,7 +253,9 @@ func hashDKGPartialSignature(psig *typesDKG.PartialSignature) common.Hash {
)
}
-func verifyDKGPartialSignatureSignature(
+// VerifyDKGPartialSignatureSignature verifies the signature of
+// typesDKG.PartialSignature.
+func VerifyDKGPartialSignatureSignature(
psig *typesDKG.PartialSignature) (bool, error) {
hash := hashDKGPartialSignature(psig)
pubKey, err := crypto.SigToPub(hash, psig.Signature)
diff --git a/core/crypto_test.go b/core/utils/crypto_test.go
index 17a52b7..f4280c2 100644
--- a/core/crypto_test.go
+++ b/core/utils/crypto_test.go
@@ -15,7 +15,7 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-package core
+package utils
import (
"testing"
@@ -67,7 +67,7 @@ func (s *CryptoTestSuite) prepareBlock(prevBlock *types.Block) *types.Block {
func (s *CryptoTestSuite) newBlock(prevBlock *types.Block) *types.Block {
block := s.prepareBlock(prevBlock)
var err error
- block.Hash, err = hashBlock(block)
+ block.Hash, err = HashBlock(block)
s.Require().NoError(err)
return block
}
@@ -85,14 +85,13 @@ func (s *CryptoTestSuite) generateCompactionChain(
}
func (s *CryptoTestSuite) generateBlockChain(
- length int, prv crypto.PrivateKey) []*types.Block {
+ length int, signer *Signer) []*types.Block {
blocks := make([]*types.Block, length)
var prevBlock *types.Block
for idx := range blocks {
block := s.newBlock(prevBlock)
blocks[idx] = block
- var err error
- block.Signature, err = prv.Sign(block.Hash)
+ err := signer.SignBlock(block)
s.Require().NoError(err)
}
return blocks
@@ -100,9 +99,8 @@ func (s *CryptoTestSuite) generateBlockChain(
func (s *CryptoTestSuite) TestBlockSignature() {
prv, err := ecdsa.NewPrivateKey()
- pub := prv.PublicKey()
s.Require().NoError(err)
- blocks := s.generateBlockChain(10, prv)
+ blocks := s.generateBlockChain(10, NewSigner(prv))
blockMap := make(map[common.Hash]*types.Block)
for _, block := range blocks {
blockMap[block.Hash] = block
@@ -112,17 +110,16 @@ func (s *CryptoTestSuite) TestBlockSignature() {
parentBlock, exist := blockMap[block.ParentHash]
s.Require().True(exist)
s.True(parentBlock.Position.Height == block.Position.Height-1)
- hash, err := hashBlock(parentBlock)
+ hash, err := HashBlock(parentBlock)
s.Require().NoError(err)
s.Equal(hash, block.ParentHash)
}
- s.True(verifyBlockSignature(pub, block, block.Signature))
+ s.NoError(VerifyBlockSignature(block))
}
// Modify Block.Acks and verify signature again.
for _, block := range blocks {
block.Acks = append(block.Acks, common.NewRandomHash())
- s.False(verifyBlockSignature(
- pub, block, block.Signature))
+ s.Error(VerifyBlockSignature(block))
}
}
@@ -135,11 +132,11 @@ func (s *CryptoTestSuite) TestVoteSignature() {
vote.ProposerID = nID
vote.Signature, err = prv.Sign(hashVote(vote))
s.Require().NoError(err)
- ok, err := verifyVoteSignature(vote)
+ ok, err := VerifyVoteSignature(vote)
s.Require().NoError(err)
s.True(ok)
vote.Type = types.VoteCom
- ok, err = verifyVoteSignature(vote)
+ ok, err = VerifyVoteSignature(vote)
s.Require().NoError(err)
s.False(ok)
}
@@ -155,11 +152,11 @@ func (s *CryptoTestSuite) TestCRSSignature() {
}
block.CRSSignature, err = prv.Sign(hashCRS(block, crs))
s.Require().NoError(err)
- ok, err := verifyCRSSignature(block, crs)
+ ok, err := VerifyCRSSignature(block, crs)
s.Require().NoError(err)
s.True(ok)
block.Position.Height++
- ok, err = verifyCRSSignature(block, crs)
+ ok, err = VerifyCRSSignature(block, crs)
s.Require().NoError(err)
s.False(ok)
}
@@ -175,11 +172,11 @@ func (s *CryptoTestSuite) TestDKGSignature() {
}
prvShare.Signature, err = prv.Sign(hashDKGPrivateShare(prvShare))
s.Require().NoError(err)
- ok, err := verifyDKGPrivateShareSignature(prvShare)
+ ok, err := VerifyDKGPrivateShareSignature(prvShare)
s.Require().NoError(err)
s.True(ok)
prvShare.Round++
- ok, err = verifyDKGPrivateShareSignature(prvShare)
+ ok, err = VerifyDKGPrivateShareSignature(prvShare)
s.Require().NoError(err)
s.False(ok)
@@ -243,11 +240,11 @@ func (s *CryptoTestSuite) TestDKGSignature() {
}
sig.Signature, err = prv.Sign(hashDKGPartialSignature(sig))
s.Require().NoError(err)
- ok, err = verifyDKGPartialSignatureSignature(sig)
+ ok, err = VerifyDKGPartialSignatureSignature(sig)
s.Require().NoError(err)
s.True(ok)
sig.Round++
- ok, err = verifyDKGPartialSignatureSignature(sig)
+ ok, err = VerifyDKGPartialSignatureSignature(sig)
s.Require().NoError(err)
s.False(ok)
diff --git a/core/utils/signer.go b/core/utils/signer.go
new file mode 100644
index 0000000..47bea3f
--- /dev/null
+++ b/core/utils/signer.go
@@ -0,0 +1,126 @@
+// Copyright 2018 The dexon-consensus Authors
+// This file is part of the dexon-consensus library.
+//
+// The dexon-consensus library is free software: you can redistribute it
+// and/or modify it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// The dexon-consensus library is distributed in the hope that it will be
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+// General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the dexon-consensus library. If not, see
+// <http://www.gnu.org/licenses/>.
+
+package utils
+
+import (
+ "errors"
+
+ "github.com/dexon-foundation/dexon-consensus/common"
+ "github.com/dexon-foundation/dexon-consensus/core/crypto"
+ "github.com/dexon-foundation/dexon-consensus/core/types"
+ typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
+)
+
+// Errors for signer.
+var (
+ ErrInvalidProposerID = errors.New("invalid proposer id")
+ ErrIncorrectHash = errors.New("hash of block is incorrect")
+ ErrIncorrectSignature = errors.New("signature of block is incorrect")
+)
+
+// Signer signs a segment of data.
+type Signer struct {
+ prvKey crypto.PrivateKey
+ pubKey crypto.PublicKey
+ proposerID types.NodeID
+}
+
+// NewSigner constructs an Signer instance.
+func NewSigner(prvKey crypto.PrivateKey) (s *Signer) {
+ s = &Signer{
+ prvKey: prvKey,
+ pubKey: prvKey.PublicKey(),
+ }
+ s.proposerID = types.NewNodeID(s.pubKey)
+ return
+}
+
+// SignBlock signs a types.Block.
+func (s *Signer) SignBlock(b *types.Block) (err error) {
+ b.ProposerID = s.proposerID
+ b.PayloadHash = crypto.Keccak256Hash(b.Payload)
+ if b.Hash, err = HashBlock(b); err != nil {
+ return
+ }
+ if b.Signature, err = s.prvKey.Sign(b.Hash); err != nil {
+ return
+ }
+ return
+}
+
+// SignVote signs a types.Vote.
+func (s *Signer) SignVote(v *types.Vote) (err error) {
+ v.ProposerID = s.proposerID
+ v.Signature, err = s.prvKey.Sign(hashVote(v))
+ return
+}
+
+// SignCRS signs CRS signature of types.Block.
+func (s *Signer) SignCRS(b *types.Block, crs common.Hash) (err error) {
+ if b.ProposerID != s.proposerID {
+ err = ErrInvalidProposerID
+ return
+ }
+ b.CRSSignature, err = s.prvKey.Sign(hashCRS(b, crs))
+ return
+}
+
+// SignDKGComplaint signs a DKG complaint.
+func (s *Signer) SignDKGComplaint(complaint *typesDKG.Complaint) (err error) {
+ complaint.ProposerID = s.proposerID
+ complaint.Signature, err = s.prvKey.Sign(hashDKGComplaint(complaint))
+ return
+}
+
+// SignDKGMasterPublicKey signs a DKG master public key.
+func (s *Signer) SignDKGMasterPublicKey(
+ mpk *typesDKG.MasterPublicKey) (err error) {
+ mpk.ProposerID = s.proposerID
+ mpk.Signature, err = s.prvKey.Sign(hashDKGMasterPublicKey(mpk))
+ return
+}
+
+// SignDKGPrivateShare signs a DKG private share.
+func (s *Signer) SignDKGPrivateShare(
+ prvShare *typesDKG.PrivateShare) (err error) {
+ prvShare.ProposerID = s.proposerID
+ prvShare.Signature, err = s.prvKey.Sign(hashDKGPrivateShare(prvShare))
+ return
+}
+
+// SignDKGPartialSignature signs a DKG partial signature.
+func (s *Signer) SignDKGPartialSignature(
+ pSig *typesDKG.PartialSignature) (err error) {
+ pSig.ProposerID = s.proposerID
+ pSig.Signature, err = s.prvKey.Sign(hashDKGPartialSignature(pSig))
+ return
+}
+
+// SignDKGMPKReady signs a DKG ready message.
+func (s *Signer) SignDKGMPKReady(ready *typesDKG.MPKReady) (err error) {
+ ready.ProposerID = s.proposerID
+ ready.Signature, err = s.prvKey.Sign(hashDKGMPKReady(ready))
+ return
+}
+
+// SignDKGFinalize signs a DKG finalize message.
+func (s *Signer) SignDKGFinalize(final *typesDKG.Finalize) (err error) {
+ final.ProposerID = s.proposerID
+ final.Signature, err = s.prvKey.Sign(hashDKGFinalize(final))
+ return
+}
diff --git a/core/authenticator_test.go b/core/utils/signer_test.go
index 68e4243..8e34b98 100644
--- a/core/authenticator_test.go
+++ b/core/utils/signer_test.go
@@ -15,7 +15,7 @@
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.
-package core
+package utils
import (
"testing"
@@ -27,18 +27,18 @@ import (
"github.com/stretchr/testify/suite"
)
-type AuthenticatorTestSuite struct {
+type SignerTestSuite struct {
suite.Suite
}
-func (s *AuthenticatorTestSuite) setupAuthenticator() *Authenticator {
+func (s *SignerTestSuite) setupSigner() *Signer {
k, err := ecdsa.NewPrivateKey()
s.NoError(err)
- return NewAuthenticator(k)
+ return NewSigner(k)
}
-func (s *AuthenticatorTestSuite) TestBlock() {
- k := s.setupAuthenticator()
+func (s *SignerTestSuite) TestBlock() {
+ k := s.setupSigner()
b := &types.Block{
ParentHash: common.NewRandomHash(),
Position: types.Position{
@@ -48,11 +48,11 @@ func (s *AuthenticatorTestSuite) TestBlock() {
Timestamp: time.Now().UTC(),
}
s.NoError(k.SignBlock(b))
- s.NoError(k.VerifyBlock(b))
+ s.NoError(VerifyBlockSignature(b))
}
-func (s *AuthenticatorTestSuite) TestVote() {
- k := s.setupAuthenticator()
+func (s *SignerTestSuite) TestVote() {
+ k := s.setupSigner()
v := types.NewVote(types.VoteCom, common.NewRandomHash(), 123)
v.Position = types.Position{
ChainID: 4,
@@ -60,13 +60,13 @@ func (s *AuthenticatorTestSuite) TestVote() {
}
v.ProposerID = types.NodeID{Hash: common.NewRandomHash()}
s.NoError(k.SignVote(v))
- ok, err := k.VerifyVote(v)
+ ok, err := VerifyVoteSignature(v)
s.True(ok)
s.NoError(err)
}
-func (s *AuthenticatorTestSuite) TestCRS() {
- k := s.setupAuthenticator()
+func (s *SignerTestSuite) TestCRS() {
+ k := s.setupSigner()
b := &types.Block{
ParentHash: common.NewRandomHash(),
Position: types.Position{
@@ -80,11 +80,11 @@ func (s *AuthenticatorTestSuite) TestCRS() {
// Hash block before hash CRS.
s.NoError(k.SignBlock(b))
s.NoError(k.SignCRS(b, crs))
- ok, err := k.VerifyCRS(b, crs)
+ ok, err := VerifyCRSSignature(b, crs)
s.True(ok)
s.NoError(err)
}
-func TestAuthenticator(t *testing.T) {
- suite.Run(t, new(AuthenticatorTestSuite))
+func TestSigner(t *testing.T) {
+ suite.Run(t, new(SignerTestSuite))
}
diff --git a/core/utils_test.go b/core/utils_test.go
index 81b093e..dd15607 100644
--- a/core/utils_test.go
+++ b/core/utils_test.go
@@ -21,10 +21,6 @@ import (
"testing"
"github.com/stretchr/testify/suite"
-
- "github.com/dexon-foundation/dexon-consensus/common"
- "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa"
- "github.com/dexon-foundation/dexon-consensus/core/types"
)
type UtilsTestSuite struct {
@@ -43,24 +39,6 @@ func (s *UtilsTestSuite) TestRemoveFromSortedUint32Slice() {
s.Equal([]uint32{}, removeFromSortedUint32Slice([]uint32{}, 1))
}
-func (s *UtilsTestSuite) TestVerifyBlock() {
- prv, err := ecdsa.NewPrivateKey()
- s.Require().NoError(err)
- auth := NewAuthenticator(prv)
- block := &types.Block{}
- auth.SignBlock(block)
- s.NoError(VerifyBlock(block))
-
- hash := block.Hash
- block.Hash = common.NewRandomHash()
- s.Equal(ErrIncorrectHash, VerifyBlock(block))
-
- block.Hash = hash
- block.Signature, err = prv.Sign(common.NewRandomHash())
- s.Require().NoError(err)
- s.Equal(ErrIncorrectSignature, VerifyBlock(block))
-}
-
func TestUtils(t *testing.T) {
suite.Run(t, new(UtilsTestSuite))
}
diff --git a/integration_test/node.go b/integration_test/node.go
index 511b5fd..2d0ca9f 100644
--- a/integration_test/node.go
+++ b/integration_test/node.go
@@ -111,7 +111,7 @@ func newNode(
dMoment,
0,
configs[0],
- core.NewAuthenticator(privateKey),
+ utils.NewSigner(privateKey),
app,
app,
dbInst,