diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-10-29 16:45:43 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-29 16:45:43 +0800 |
commit | 51904f3e9b821f3313d3ab1f268efb28f739eb5f (patch) | |
tree | 235f636525027fccf42aee2520afcc9e2463f49e | |
parent | dcc2319797d3ab78ff0611b82c56d43803675e3c (diff) | |
download | dexon-consensus-51904f3e9b821f3313d3ab1f268efb28f739eb5f.tar.gz dexon-consensus-51904f3e9b821f3313d3ab1f268efb28f739eb5f.tar.zst dexon-consensus-51904f3e9b821f3313d3ab1f268efb28f739eb5f.zip |
core: Add BlockSkeleton and Verify functions (#271)
-rw-r--r-- | core/authenticator.go | 6 | ||||
-rw-r--r-- | core/crypto.go | 3 | ||||
-rw-r--r-- | core/types/block.go | 5 | ||||
-rw-r--r-- | core/types/block_test.go | 4 | ||||
-rw-r--r-- | core/utils.go | 21 | ||||
-rw-r--r-- | core/utils_test.go | 39 |
6 files changed, 75 insertions, 3 deletions
diff --git a/core/authenticator.go b/core/authenticator.go index f773d52..60a4cf8 100644 --- a/core/authenticator.go +++ b/core/authenticator.go @@ -44,6 +44,7 @@ func NewAuthenticator(prvKey crypto.PrivateKey) (auth *Authenticator) { // 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 } @@ -112,6 +113,11 @@ func (au *Authenticator) SignDKGFinalize( // 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 diff --git a/core/crypto.go b/core/crypto.go index 8eb57fc..52f1c91 100644 --- a/core/crypto.go +++ b/core/crypto.go @@ -50,7 +50,6 @@ func hashBlock(block *types.Block) (common.Hash, error) { if err != nil { return common.Hash{}, err } - payloadHash := crypto.Keccak256Hash(block.Payload) hash := crypto.Keccak256Hash( block.ProposerID.Hash[:], @@ -58,7 +57,7 @@ func hashBlock(block *types.Block) (common.Hash, error) { hashPosition[:], hashAcks[:], binaryTimestamp[:], - payloadHash[:], + block.PayloadHash[:], binaryWitness[:]) return hash, nil } diff --git a/core/types/block.go b/core/types/block.go index 6722692..0088057 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -143,6 +143,7 @@ type Block struct { Timestamp time.Time `json:"timestamp"` Acks common.SortedHashes `json:"acks"` Payload []byte `json:"payload"` + PayloadHash common.Hash `json:"payload_hash"` Witness Witness `json:"witness"` Finalization FinalizationResult `json:"finalization"` Signature crypto.Signature `json:"signature"` @@ -158,6 +159,7 @@ type rlpBlock struct { Timestamp *rlpTimestamp Acks common.SortedHashes Payload []byte + PayloadHash common.Hash Witness *Witness Finalization *FinalizationResult Signature crypto.Signature @@ -175,6 +177,7 @@ func (b *Block) EncodeRLP(w io.Writer) error { Timestamp: &rlpTimestamp{b.Timestamp}, Acks: b.Acks, Payload: b.Payload, + PayloadHash: b.PayloadHash, Witness: &b.Witness, Finalization: &b.Finalization, Signature: b.Signature, @@ -195,6 +198,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error { Timestamp: dec.Timestamp.Time, Acks: dec.Acks, Payload: dec.Payload, + PayloadHash: dec.PayloadHash, Witness: *dec.Witness, Finalization: *dec.Finalization, Signature: dec.Signature, @@ -231,6 +235,7 @@ func (b *Block) Clone() (bcopy *Block) { copy(bcopy.Acks, b.Acks) bcopy.Payload = make([]byte, len(b.Payload)) copy(bcopy.Payload, b.Payload) + bcopy.PayloadHash = b.PayloadHash bcopy.Finalization.Randomness = make([]byte, len(b.Finalization.Randomness)) copy(bcopy.Finalization.Randomness, b.Finalization.Randomness) return diff --git a/core/types/block_test.go b/core/types/block_test.go index 4b899e1..a8274e0 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -61,6 +61,7 @@ func (s *BlockTestSuite) noZeroInStruct(v reflect.Value) { } func (s *BlockTestSuite) createRandomBlock() *Block { + payload := s.randomBytes() b := &Block{ ProposerID: NodeID{common.NewRandomHash()}, ParentHash: common.NewRandomHash(), @@ -85,7 +86,8 @@ func (s *BlockTestSuite) createRandomBlock() *Block { Height: rand.Uint64(), Randomness: s.randomBytes(), }, - Payload: s.randomBytes(), + Payload: payload, + PayloadHash: crypto.Keccak256Hash(payload), Signature: crypto.Signature{ Type: "some type", Signature: s.randomBytes()}, diff --git a/core/utils.go b/core/utils.go index ac95678..38e8746 100644 --- a/core/utils.go +++ b/core/utils.go @@ -131,6 +131,27 @@ 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 +} + // DiffUint64 calculates difference between two uint64. func DiffUint64(a, b uint64) uint64 { if a > b { diff --git a/core/utils_test.go b/core/utils_test.go index bb1cb65..ceec860 100644 --- a/core/utils_test.go +++ b/core/utils_test.go @@ -1,9 +1,30 @@ +// Copyright 2018 The dexon-consensus-core Authors +// This file is part of the dexon-consensus-core library. +// +// The dexon-consensus-core 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-core 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-core library. If not, see +// <http://www.gnu.org/licenses/>. + package core import ( "testing" "github.com/stretchr/testify/suite" + + "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core/crypto/ecdsa" + "github.com/dexon-foundation/dexon-consensus-core/core/types" ) type UtilsTestSuite struct { @@ -22,6 +43,24 @@ 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)) } |