aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2018-10-29 16:45:43 +0800
committerGitHub <noreply@github.com>2018-10-29 16:45:43 +0800
commit51904f3e9b821f3313d3ab1f268efb28f739eb5f (patch)
tree235f636525027fccf42aee2520afcc9e2463f49e
parentdcc2319797d3ab78ff0611b82c56d43803675e3c (diff)
downloaddexon-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.go6
-rw-r--r--core/crypto.go3
-rw-r--r--core/types/block.go5
-rw-r--r--core/types/block_test.go4
-rw-r--r--core/utils.go21
-rw-r--r--core/utils_test.go39
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))
}