aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2018-08-20 14:03:18 +0800
committerGitHub <noreply@github.com>2018-08-20 14:03:18 +0800
commit1e71e263e063adbe7e44d48818f9c74924a2945d (patch)
treeb874d8d4d6cc1d0aa6f106f276f83706361f0878 /core
parentd9ba7986a975615fb10790cfd448c48c89c1a7b3 (diff)
downloaddexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar.gz
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar.bz2
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar.lz
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar.xz
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.tar.zst
dexon-consensus-1e71e263e063adbe7e44d48818f9c74924a2945d.zip
core: NotaryAck interfaces. (#67)
Diffstat (limited to 'core')
-rw-r--r--core/application.go4
-rw-r--r--core/compaction-chain.go40
-rw-r--r--core/consensus.go28
-rw-r--r--core/crypto.go2
-rw-r--r--core/crypto_test.go21
-rw-r--r--core/nonblocking-application.go5
-rw-r--r--core/nonblocking-application_test.go8
-rw-r--r--core/test/app.go5
-rw-r--r--core/types/block.go43
-rw-r--r--core/types/notary.go43
10 files changed, 132 insertions, 67 deletions
diff --git a/core/application.go b/core/application.go
index 5bd325c..e39e238 100644
--- a/core/application.go
+++ b/core/application.go
@@ -21,6 +21,7 @@ import (
"time"
"github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/core/types"
)
// Application describes the application interface that interacts with DEXON
@@ -34,4 +35,7 @@ type Application interface {
// DeliverBlock is called when a block is add to the compaction chain.
DeliverBlock(blockHash common.Hash, timestamp time.Time)
+
+ // NotaryAck is called when a notary ack is created.
+ NotaryAck(notaryAck types.NotaryAck)
}
diff --git a/core/compaction-chain.go b/core/compaction-chain.go
index f2b4d1b..664b692 100644
--- a/core/compaction-chain.go
+++ b/core/compaction-chain.go
@@ -20,24 +20,37 @@
package core
import (
+ "fmt"
"sync"
- //"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"
)
+// Errors for compaction chain.
+var (
+ ErrIncorrectNotaryAck = fmt.Errorf(
+ "compaction chain notary of block is incorrect")
+)
+
type compactionChain struct {
- prevBlock *types.Block
- lock sync.RWMutex
+ prevBlock *types.Block
+ lock sync.RWMutex
+ latestNotaryAcks map[types.ValidatorID]types.NotaryAck
}
func newCompactionChain() *compactionChain {
return &compactionChain{}
}
-func (cc *compactionChain) prepareBlock(
- block *types.Block, prvKey crypto.PrivateKey) (err error) {
+func (cc *compactionChain) sanityCheck(notaryAck types.NotaryAck) bool {
+ return true
+}
+
+func (cc *compactionChain) processBlock(block *types.Block) (err error) {
+ cc.lock.Lock()
+ defer cc.lock.Unlock()
+ cc.prevBlock = block
/*
prevBlock := cc.lastBlock()
if prevBlock != nil {
@@ -51,8 +64,18 @@ func (cc *compactionChain) prepareBlock(
*/
return
}
+func (cc *compactionChain) prepareNotaryAck(prvKey crypto.PrivateKey) (
+ notaryAck types.NotaryAck, err error) {
+ notaryAck.NotaryBlockHash = cc.lastBlock().Hash
+ return
+}
-func (cc *compactionChain) processBlock(block *types.Block) (err error) {
+func (cc *compactionChain) processNotaryAck(notaryAck types.NotaryAck) (
+ err error) {
+ if !cc.sanityCheck(notaryAck) {
+ err = ErrIncorrectNotaryAck
+ return
+ }
/*
prevBlock := cc.lastBlock()
if prevBlock == nil {
@@ -69,9 +92,14 @@ func (cc *compactionChain) processBlock(block *types.Block) (err error) {
defer cc.lock.Unlock()
cc.prevBlock = block
*/
+ cc.latestNotaryAcks[notaryAck.ProposerID] = notaryAck
return
}
+func (cc *compactionChain) notaryAcks() map[types.ValidatorID]types.NotaryAck {
+ return cc.latestNotaryAcks
+}
+
func (cc *compactionChain) lastBlock() *types.Block {
cc.lock.RLock()
defer cc.lock.RUnlock()
diff --git a/core/consensus.go b/core/consensus.go
index 3e8f87d..0b4ea62 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -48,8 +48,6 @@ var (
"hash of block is incorrect")
ErrIncorrectSignature = fmt.Errorf(
"signature of block is incorrect")
- ErrIncorrectNotaryAck = fmt.Errorf(
- "compaction chain notary of block is incorrect")
ErrGenesisBlockNotEmpty = fmt.Errorf(
"genesis block should be empty")
)
@@ -204,6 +202,12 @@ func (con *Consensus) ProcessBlock(blockConv types.BlockConverter) (err error) {
}
con.app.DeliverBlock(b.Hash, b.Notary.Timestamp)
}
+ var notaryAck types.NotaryAck
+ notaryAck, err = con.ccModule.prepareNotaryAck(con.prvKey)
+ if err != nil {
+ return
+ }
+ con.app.NotaryAck(notaryAck)
}
return
}
@@ -237,10 +241,6 @@ func (con *Consensus) PrepareBlock(blockConv types.BlockConverter,
if err != nil {
return
}
- err = con.ccModule.prepareBlock(b, con.prvKey)
- if err != nil {
- return
- }
blockConv.SetBlock(b)
return
}
@@ -275,3 +275,19 @@ func (con *Consensus) PrepareGenesisBlock(blockConv types.BlockConverter,
blockConv.SetBlock(b)
return
}
+
+// ProcessNotaryAck is the entry point to submit one notary ack.
+func (con *Consensus) ProcessNotaryAck(notaryAck types.NotaryAck) (err error) {
+ err = con.ccModule.processNotaryAck(notaryAck)
+ return
+}
+
+// NotaryAcks returns the latest NotaryAck received from all other validators.
+func (con *Consensus) NotaryAcks() (
+ notaryAcks map[types.ValidatorID]types.NotaryAck) {
+ notaryAcks = make(map[types.ValidatorID]types.NotaryAck)
+ for k, v := range con.ccModule.notaryAcks() {
+ notaryAcks[k] = v
+ }
+ return
+}
diff --git a/core/crypto.go b/core/crypto.go
index 664607b..0de73af 100644
--- a/core/crypto.go
+++ b/core/crypto.go
@@ -34,7 +34,7 @@ func hashNotary(block *types.Block) (common.Hash, error) {
binaryHeight := make([]byte, 8)
binary.LittleEndian.PutUint64(binaryHeight, block.Notary.Height)
hash := crypto.Keccak256Hash(
- block.NotaryParentHash[:],
+ block.Notary.ParentHash[:],
binaryTime,
binaryHeight)
return hash, nil
diff --git a/core/crypto_test.go b/core/crypto_test.go
index 94b500e..3aa1674 100644
--- a/core/crypto_test.go
+++ b/core/crypto_test.go
@@ -69,19 +69,14 @@ func (s *CryptoTestSuite) prepareBlock(prevBlock *types.Block) *types.Block {
s.Require().NotEqual(prevBlock.Hash, common.Hash{})
acks[parentHash] = struct{}{}
return &types.Block{
- ParentHash: prevBlock.Hash,
- Acks: acks,
- Timestamps: timestamps,
- NotaryParentHash: parentHash,
- Height: prevBlock.Height + 1,
- /*
- NotaryAck: types.NotaryAck{
- NotaryBlockHash: prevBlock.Hash,
- },
- */
+ ParentHash: prevBlock.Hash,
+ Acks: acks,
+ Timestamps: timestamps,
+ Height: prevBlock.Height + 1,
Notary: types.Notary{
- Timestamp: time.Now(),
- Height: prevBlock.Notary.Height + 1,
+ ParentHash: parentHash,
+ Timestamp: time.Now(),
+ Height: prevBlock.Notary.Height + 1,
},
}
}
@@ -104,7 +99,7 @@ func (s *CryptoTestSuite) generateCompactionChain(
blocks[idx] = block
var err error
if idx > 0 {
- block.NotaryParentHash, err = hashNotary(blocks[idx-1])
+ block.Notary.ParentHash, err = hashNotary(blocks[idx-1])
s.Require().Nil(err)
/*
block.NotaryAck.NotarySignature, err =
diff --git a/core/nonblocking-application.go b/core/nonblocking-application.go
index 4c06ab9..a04d7d2 100644
--- a/core/nonblocking-application.go
+++ b/core/nonblocking-application.go
@@ -23,6 +23,7 @@ import (
"time"
"github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/core/types"
)
type stronglyAckedEvent struct {
@@ -124,3 +125,7 @@ func (app *nonBlockingApplication) DeliverBlock(
blockHash common.Hash, timestamp time.Time) {
app.addEvent(deliverBlockEvent{blockHash, timestamp})
}
+
+// NotaryAck is called when a notary ack is created.
+func (app *nonBlockingApplication) NotaryAck(notaryAck types.NotaryAck) {
+}
diff --git a/core/nonblocking-application_test.go b/core/nonblocking-application_test.go
index 070eae3..0f7d7f2 100644
--- a/core/nonblocking-application_test.go
+++ b/core/nonblocking-application_test.go
@@ -24,6 +24,7 @@ import (
"github.com/stretchr/testify/suite"
"github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/core/types"
)
type slowApp struct {
@@ -31,6 +32,7 @@ type slowApp struct {
stronglyAcked map[common.Hash]struct{}
totalOrderingDeliver map[common.Hash]struct{}
deliverBlock map[common.Hash]struct{}
+ notaryAck map[common.Hash]struct{}
}
func newSlowApp(sleep time.Duration) *slowApp {
@@ -39,6 +41,7 @@ func newSlowApp(sleep time.Duration) *slowApp {
stronglyAcked: make(map[common.Hash]struct{}),
totalOrderingDeliver: make(map[common.Hash]struct{}),
deliverBlock: make(map[common.Hash]struct{}),
+ notaryAck: make(map[common.Hash]struct{}),
}
}
@@ -59,6 +62,11 @@ func (app *slowApp) DeliverBlock(blockHash common.Hash, timestamp time.Time) {
app.deliverBlock[blockHash] = struct{}{}
}
+func (app *slowApp) NotaryAck(notaryAck types.NotaryAck) {
+ time.Sleep(app.sleep)
+ app.notaryAck[notaryAck.Hash] = struct{}{}
+}
+
type NonBlockingAppTestSuite struct {
suite.Suite
}
diff --git a/core/test/app.go b/core/test/app.go
index 5c438a7..4a704a0 100644
--- a/core/test/app.go
+++ b/core/test/app.go
@@ -23,6 +23,7 @@ import (
"time"
"github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/core/types"
)
var (
@@ -105,6 +106,10 @@ func (app *App) DeliverBlock(blockHash common.Hash, timestamp time.Time) {
app.DeliverSequence = append(app.DeliverSequence, blockHash)
}
+// NotaryAck implements Application interface.
+func (app *App) NotaryAck(notaryAck types.NotaryAck) {
+}
+
// Compare performs these checks against another App instance
// and return erros if not passed:
// - deliver sequence by comparing block hashes.
diff --git a/core/types/block.go b/core/types/block.go
index 0386ed7..557974f 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -28,28 +28,6 @@ import (
"github.com/dexon-foundation/dexon-consensus-core/crypto"
)
-// NotaryAck represents the acking to the compaction chain.
-type NotaryAck struct {
- NotaryBlockHash common.Hash `json:"notary_block_hash"`
- // NotarySignature is the signature of the hash value of
- // Block.NotaryParentHash and Block.Notary.
- NotarySignature crypto.Signature `json:"notary_signature"`
-}
-
-// CompactionChainAck represents the acking to the compaction chain.
-type CompactionChainAck struct {
- AckingBlockHash common.Hash `json:"acking_block_hash"`
- // Signature is the signature of the hash value of
- // Block.ConsensusInfoParentHash and Block.ConsensusInfo.
- ConsensusSignature crypto.Signature `json:"consensus_signature"`
-}
-
-// Notary represents the consensus information on the compaction chain.
-type Notary struct {
- Timestamp time.Time `json:"timestamp"`
- Height uint64 `json:"height"`
-}
-
// Block represents a single event broadcasted on the network.
type Block struct {
ProposerID ValidatorID `json:"proposer_id"`
@@ -58,16 +36,9 @@ type Block struct {
Height uint64 `json:"height"`
Timestamps map[ValidatorID]time.Time `json:"timestamps"`
Acks map[common.Hash]struct{} `json:"acks"`
- //NotaryAck NotaryAck `json:"notary_ack"`
- Signature crypto.Signature `json:"signature"`
+ Signature crypto.Signature `json:"signature"`
Notary Notary `json:"notary"`
- // NotaryParentHash is the hash value of Block.NotaryParentHash
- // and Block.Notary, where Block is the previous block on
- // the compaction chain.
- NotaryParentHash common.Hash `json:"notary_parent_hash"`
-
- ConsensusInfoParentHash common.Hash `json:"consensus_info_parent_hash"`
}
// Block implements BlockConverter interface.
@@ -106,22 +77,12 @@ func (b *Block) Clone() *Block {
Height: b.Height,
Timestamps: make(map[ValidatorID]time.Time),
Acks: make(map[common.Hash]struct{}),
- /*
- NotaryAck: NotaryAck{
- NotaryBlockHash: b.NotaryAck.NotaryBlockHash,
- },
- */
- Signature: b.Signature,
+ Signature: b.Signature,
Notary: Notary{
Timestamp: b.Notary.Timestamp,
Height: b.Notary.Height,
},
- NotaryParentHash: b.NotaryParentHash,
}
- /*
- bcopy.NotaryAck.NotarySignature = append(
- crypto.Signature(nil), b.NotaryAck.NotarySignature...)
- */
for k, v := range b.Timestamps {
bcopy.Timestamps[k] = v
}
diff --git a/core/types/notary.go b/core/types/notary.go
new file mode 100644
index 0000000..01237b4
--- /dev/null
+++ b/core/types/notary.go
@@ -0,0 +1,43 @@
+// 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/>.
+
+// TODO(jimmy-dexon): remove comments of NotaryAck before open source.
+
+package types
+
+import (
+ "time"
+
+ "github.com/dexon-foundation/dexon-consensus-core/common"
+ "github.com/dexon-foundation/dexon-consensus-core/crypto"
+)
+
+// NotaryAck represents the acking to the compaction chain.
+type NotaryAck struct {
+ ProposerID ValidatorID `json:"proposer_id"`
+ NotaryBlockHash common.Hash `json:"notary_block_hash"`
+ Hash common.Hash `json:"hash"`
+ // NotarySignature is the signature of the hash value of BlockNotary.
+ Signature crypto.Signature `json:"signature"`
+}
+
+// Notary represents the consensus information on the compaction chain.
+type Notary struct {
+ ParentHash common.Hash `json:"parent_hash"`
+ Timestamp time.Time `json:"timestamp"`
+ Height uint64 `json:"height"`
+}