diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-08-13 15:13:41 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-13 15:13:41 +0800 |
commit | a8ebf501e54406c7449f71dba0c9af696bbc4e21 (patch) | |
tree | 37ae1a53769d6f7be82ed576b1fd65a476c11d17 | |
parent | 63c76e56169b6f14ef049490392a1b3b414f73c6 (diff) | |
download | dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar.gz dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar.bz2 dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar.lz dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar.xz dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.tar.zst dexon-consensus-a8ebf501e54406c7449f71dba0c9af696bbc4e21.zip |
core: Sign block in Consensus.PrepareBlock. (#50)
-rw-r--r-- | core/consensus.go | 35 | ||||
-rw-r--r-- | core/consensus_test.go | 5 | ||||
-rw-r--r-- | core/crypto.go | 9 | ||||
-rw-r--r-- | core/crypto_test.go | 2 | ||||
-rw-r--r-- | core/types/validator.go | 5 | ||||
-rw-r--r-- | crypto/eth/eth.go | 2 | ||||
-rw-r--r-- | simulation/simulation.go | 6 | ||||
-rw-r--r-- | simulation/validator.go | 9 |
8 files changed, 54 insertions, 19 deletions
diff --git a/core/consensus.go b/core/consensus.go index b1b1973..c8b10a0 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -25,8 +25,13 @@ import ( "github.com/dexon-foundation/dexon-consensus-core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core/types" + "github.com/dexon-foundation/dexon-consensus-core/crypto" ) +// SigToPubFn is a function to recover public key from signature. +type SigToPubFn func(hash common.Hash, signature crypto.Signature) ( + crypto.PublicKey, error) + // ErrMissingBlockInfo would be reported if some information is missing when // calling PrepareBlock. It implements error interface. type ErrMissingBlockInfo struct { @@ -39,7 +44,8 @@ func (e *ErrMissingBlockInfo) Error() string { // Errors for sanity check error. var ( - ErrIncorrectHash = fmt.Errorf("hash of block is incorrect") + ErrIncorrectHash = fmt.Errorf("hash of block is incorrect") + ErrIncorrectSignature = fmt.Errorf("signature of block is incorrect") ) // Consensus implements DEXON Consensus algorithm. @@ -50,6 +56,8 @@ type Consensus struct { toModule *totalOrdering ctModule *consensusTimestamp db blockdb.BlockDatabase + prvKey crypto.PrivateKey + sigToPub SigToPubFn lock sync.RWMutex } @@ -57,7 +65,9 @@ type Consensus struct { func NewConsensus( app Application, gov Governance, - db blockdb.BlockDatabase) *Consensus { + db blockdb.BlockDatabase, + prv crypto.PrivateKey, + sigToPub SigToPubFn) *Consensus { validatorSet := gov.GetValidatorSet() // Setup acking by information returned from Governace. @@ -79,6 +89,8 @@ func NewConsensus( app: app, gov: gov, db: db, + prvKey: prv, + sigToPub: sigToPub, } } @@ -91,6 +103,18 @@ func (con *Consensus) sanityCheck(blockConv types.BlockConverter) (err error) { return ErrIncorrectHash } + /* Disable these check before the implmentation of the signature for + * genesis block is finished. + // Check the signer. + pubKey, err := con.sigToPub(b.Hash, b.Signature) + if err != nil { + return err + } + if !b.ProposerID.Equal(crypto.Keccak256Hash(pubKey.Bytes())) { + return ErrIncorrectSignature + } + */ + return nil } @@ -166,6 +190,13 @@ func (con *Consensus) PrepareBlock(blockConv types.BlockConverter, con.rbModule.prepareBlock(b) b.Timestamps[b.ProposerID] = proposeTime b.Hash, err = hashBlock(b) + if err != nil { + return + } + b.Signature, err = con.prvKey.Sign(b.Hash) + if err != nil { + return + } blockConv.SetBlock(b) return } diff --git a/core/consensus_test.go b/core/consensus_test.go index c26e7e8..522c566 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -26,6 +26,7 @@ import ( "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" + "github.com/dexon-foundation/dexon-consensus-core/crypto/eth" "github.com/stretchr/testify/suite" ) @@ -60,7 +61,9 @@ func (s *ConsensusTestSuite) prepareConsensus(gov *test.Governance) ( app := test.NewApp() db, err := blockdb.NewMemBackedBlockDB() s.Require().Nil(err) - con := NewConsensus(app, gov, db) + prv, err := eth.NewPrivateKey() + s.Require().Nil(err) + con := NewConsensus(app, gov, db, prv, eth.SigToPub) return app, con } diff --git a/core/crypto.go b/core/crypto.go index abfc8fb..564ad38 100644 --- a/core/crypto.go +++ b/core/crypto.go @@ -101,15 +101,6 @@ func hashBlock(blockConv types.BlockConverter) (common.Hash, error) { return hash, nil } -func signBlock(blockConv types.BlockConverter, - prv crypto.PrivateKey) (crypto.Signature, error) { - hash, err := hashBlock(blockConv) - if err != nil { - return crypto.Signature{}, err - } - return prv.Sign(hash) -} - func verifyBlockSignature(pubkey crypto.PublicKey, blockConv types.BlockConverter, sig crypto.Signature) (bool, error) { hash, err := hashBlock(blockConv) diff --git a/core/crypto_test.go b/core/crypto_test.go index 06f4905..595d0e9 100644 --- a/core/crypto_test.go +++ b/core/crypto_test.go @@ -154,7 +154,7 @@ func (s *CryptoTestSuite) generateBlockChain( block := s.newBlock(prevBlock) blocks[idx] = block var err error - block.Signature, err = signBlock(&simpleBlock{block: block}, prv) + block.Signature, err = prv.Sign(block.Hash) s.Require().Nil(err) } return blocks diff --git a/core/types/validator.go b/core/types/validator.go index 27a9acd..5151a6d 100644 --- a/core/types/validator.go +++ b/core/types/validator.go @@ -35,6 +35,11 @@ func NewValidatorID(pubKey crypto.PublicKey) ValidatorID { return ValidatorID{Hash: crypto.Keccak256Hash(pubKey.Bytes())} } +// Equal checks if the hash representation is the same ValidatorID. +func (v ValidatorID) Equal(hash common.Hash) bool { + return v.Hash == hash +} + // ValidatorIDs implements sort.Interface for ValidatorID. type ValidatorIDs []ValidatorID diff --git a/crypto/eth/eth.go b/crypto/eth/eth.go index 975d8a8..c3c5a7c 100644 --- a/crypto/eth/eth.go +++ b/crypto/eth/eth.go @@ -111,7 +111,7 @@ func (pub PublicKey) Bytes() []byte { // SigToPub returns the PublicKey that created the given signature. func SigToPub( - hash common.Hash, signature crypto.Signature) (PublicKey, error) { + hash common.Hash, signature crypto.Signature) (crypto.PublicKey, error) { key, err := ethcrypto.SigToPub(hash[:], signature[:]) if err != nil { return PublicKey{}, err diff --git a/simulation/simulation.go b/simulation/simulation.go index 6730b96..fcd5dbd 100644 --- a/simulation/simulation.go +++ b/simulation/simulation.go @@ -53,7 +53,7 @@ func Run(configPath string) { if err != nil { panic(err) } - vs = append(vs, NewValidator(prv, cfg.Validator, network)) + vs = append(vs, NewValidator(prv, eth.SigToPub, cfg.Validator, network)) } } else if networkType == config.NetworkTypeTCPLocal { for i := 0; i < cfg.Validator.Num; i++ { @@ -63,7 +63,7 @@ func Run(configPath string) { } network := NewTCPNetwork(true, cfg.Networking.PeerServer) go network.Start() - vs = append(vs, NewValidator(prv, cfg.Validator, network)) + vs = append(vs, NewValidator(prv, eth.SigToPub, cfg.Validator, network)) } } @@ -78,7 +78,7 @@ func Run(configPath string) { } network := NewTCPNetwork(false, cfg.Networking.PeerServer) go network.Start() - v := NewValidator(prv, cfg.Validator, network) + v := NewValidator(prv, eth.SigToPub, cfg.Validator, network) go v.Run() vs = append(vs, v) } diff --git a/simulation/validator.go b/simulation/validator.go index c5bbe15..17d6eee 100644 --- a/simulation/validator.go +++ b/simulation/validator.go @@ -41,7 +41,8 @@ type Validator struct { isFinished chan struct{} ID types.ValidatorID - privateKey crypto.PrivateKey + prvKey crypto.PrivateKey + sigToPub core.SigToPubFn consensus *core.Consensus compactionChain *core.BlockChain } @@ -49,6 +50,7 @@ type Validator struct { // NewValidator returns a new empty validator. func NewValidator( prvKey crypto.PrivateKey, + sigToPub core.SigToPubFn, config config.Validator, network Network) *Validator { @@ -63,6 +65,8 @@ func NewValidator( gov.addValidator(id) return &Validator{ ID: id, + prvKey: prvKey, + sigToPub: sigToPub, config: config, network: network, app: newSimApp(id, network), @@ -160,7 +164,8 @@ func (v *Validator) MsgServer( // We don't collect all validators yet. break } - v.consensus = core.NewConsensus(v.app, v.gov, v.db) + v.consensus = core.NewConsensus( + v.app, v.gov, v.db, v.prvKey, v.sigToPub) for _, b := range pendingBlocks { if err := v.consensus.ProcessBlock(b); err != nil { fmt.Println(err) |