aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2018-08-30 17:21:58 +0800
committerGitHub <noreply@github.com>2018-08-30 17:21:58 +0800
commit96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8 (patch)
tree418e2c43acf4f9c13289eaccf66f94ef46c9356b /core
parenta4e0da981a3dfc8817d39be65cb5b24938b0761a (diff)
downloaddexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.gz
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.bz2
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.lz
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.xz
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.zst
dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.zip
core: Add PreparePayloads to Application and Remove blockConverter interface. (#84)
Diffstat (limited to 'core')
-rw-r--r--core/consensus.go21
-rw-r--r--core/crypto.go10
-rw-r--r--core/crypto_test.go24
-rw-r--r--core/interfaces.go (renamed from core/application.go)19
-rw-r--r--core/nonblocking-application.go6
-rw-r--r--core/nonblocking-application_test.go4
-rw-r--r--core/test/app.go5
-rw-r--r--core/test/blocks-generator.go2
-rw-r--r--core/test/utils.go3
-rw-r--r--core/types/block.go29
10 files changed, 57 insertions, 66 deletions
diff --git a/core/consensus.go b/core/consensus.go
index d163686..9c109e4 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -113,10 +113,9 @@ func (con *Consensus) ProcessVote(vote *types.Vote) (err error) {
}
// sanityCheck checks if the block is a valid block
-func (con *Consensus) sanityCheck(blockConv types.BlockConverter) (err error) {
- b := blockConv.Block()
+func (con *Consensus) sanityCheck(b *types.Block) (err error) {
// Check the hash of block.
- hash, err := hashBlock(blockConv)
+ hash, err := hashBlock(b)
if err != nil || hash != b.Hash {
return ErrIncorrectHash
}
@@ -133,12 +132,11 @@ func (con *Consensus) sanityCheck(blockConv types.BlockConverter) (err error) {
}
// ProcessBlock is the entry point to submit one block to a Consensus instance.
-func (con *Consensus) ProcessBlock(blockConv types.BlockConverter) (err error) {
+func (con *Consensus) ProcessBlock(b *types.Block) (err error) {
// TODO(jimmy-dexon): BlockConverter.Block() is called twice in this method.
- if err := con.sanityCheck(blockConv); err != nil {
+ if err := con.sanityCheck(b); err != nil {
return err
}
- b := blockConv.Block()
var (
deliveredBlocks []*types.Block
earlyDelivered bool
@@ -218,9 +216,8 @@ func (con *Consensus) checkPrepareBlock(
}
// PrepareBlock would setup header fields of block based on its ProposerID.
-func (con *Consensus) PrepareBlock(blockConv types.BlockConverter,
+func (con *Consensus) PrepareBlock(b *types.Block,
proposeTime time.Time) (err error) {
- b := blockConv.Block()
if err = con.checkPrepareBlock(b, proposeTime); err != nil {
return
}
@@ -229,6 +226,7 @@ func (con *Consensus) PrepareBlock(blockConv types.BlockConverter,
con.rbModule.prepareBlock(b)
b.Timestamps[b.ProposerID] = proposeTime
+ b.Payloads = con.app.PreparePayloads(b.ShardID, b.ChainID, b.Height)
b.Hash, err = hashBlock(b)
if err != nil {
return
@@ -237,18 +235,16 @@ func (con *Consensus) PrepareBlock(blockConv types.BlockConverter,
if err != nil {
return
}
- blockConv.SetBlock(b)
return
}
// PrepareGenesisBlock would setup header fields for genesis block.
-func (con *Consensus) PrepareGenesisBlock(blockConv types.BlockConverter,
+func (con *Consensus) PrepareGenesisBlock(b *types.Block,
proposeTime time.Time) (err error) {
- b := blockConv.Block()
if err = con.checkPrepareBlock(b, proposeTime); err != nil {
return
}
- if len(b.Payloads()) != 0 {
+ if len(b.Payloads) != 0 {
err = ErrGenesisBlockNotEmpty
return
}
@@ -268,7 +264,6 @@ func (con *Consensus) PrepareGenesisBlock(blockConv types.BlockConverter,
if err != nil {
return
}
- blockConv.SetBlock(b)
return
}
diff --git a/core/crypto.go b/core/crypto.go
index 57aae92..d6af360 100644
--- a/core/crypto.go
+++ b/core/crypto.go
@@ -49,9 +49,7 @@ func verifyNotarySignature(pubkey crypto.PublicKey,
return pubkey.VerifySignature(hash, sig), nil
}
-func hashBlock(blockConv types.BlockConverter) (common.Hash, error) {
- block := blockConv.Block()
-
+func hashBlock(block *types.Block) (common.Hash, error) {
hashPosition := hashPosition(block.ShardID, block.ChainID, block.Height)
// Handling Block.Acks.
acks := make(common.Hashes, 0, len(block.Acks))
@@ -80,7 +78,7 @@ func hashBlock(blockConv types.BlockConverter) (common.Hash, error) {
}
}
hashTimestamps := crypto.Keccak256Hash(binaryTimestamps...)
- payloadHash := crypto.Keccak256Hash(blockConv.Payloads()...)
+ payloadHash := crypto.Keccak256Hash(block.Payloads...)
hash := crypto.Keccak256Hash(
block.ProposerID.Hash[:],
@@ -93,8 +91,8 @@ func hashBlock(blockConv types.BlockConverter) (common.Hash, error) {
}
func verifyBlockSignature(pubkey crypto.PublicKey,
- blockConv types.BlockConverter, sig crypto.Signature) (bool, error) {
- hash, err := hashBlock(blockConv)
+ block *types.Block, sig crypto.Signature) (bool, error) {
+ hash, err := hashBlock(block)
if err != nil {
return false, err
}
diff --git a/core/crypto_test.go b/core/crypto_test.go
index 62f7daa..f4013be 100644
--- a/core/crypto_test.go
+++ b/core/crypto_test.go
@@ -34,22 +34,6 @@ type CryptoTestSuite struct {
var myVID = types.ValidatorID{Hash: common.NewRandomHash()}
-type simpleBlock struct {
- block *types.Block
-}
-
-func (sb *simpleBlock) Block() *types.Block {
- return sb.block
-}
-
-func (sb *simpleBlock) Payloads() [][]byte {
- return [][]byte{}
-}
-
-func (sb *simpleBlock) SetBlock(block *types.Block) {
- *sb.block = *block
-}
-
func (s *CryptoTestSuite) prepareBlock(prevBlock *types.Block) *types.Block {
acks := make(map[common.Hash]struct{})
timestamps := make(map[types.ValidatorID]time.Time)
@@ -84,7 +68,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(&simpleBlock{block: block})
+ block.Hash, err = hashBlock(block)
s.Require().Nil(err)
return block
}
@@ -177,17 +161,17 @@ func (s *CryptoTestSuite) TestBlockSignature() {
parentBlock, exist := blockMap[block.ParentHash]
s.Require().True(exist)
s.True(parentBlock.Height == block.Height-1)
- hash, err := hashBlock(&simpleBlock{block: parentBlock})
+ hash, err := hashBlock(parentBlock)
s.Require().Nil(err)
s.Equal(hash, block.ParentHash)
}
- s.True(verifyBlockSignature(pub, &simpleBlock{block: block}, block.Signature))
+ s.True(verifyBlockSignature(pub, block, block.Signature))
}
// Modify Block.Acks and verify signature again.
for _, block := range blocks {
block.Acks[common.NewRandomHash()] = struct{}{}
s.False(verifyBlockSignature(
- pub, &simpleBlock{block: block}, block.Signature))
+ pub, block, block.Signature))
}
}
diff --git a/core/application.go b/core/interfaces.go
index 3834d68..364f2da 100644
--- a/core/application.go
+++ b/core/interfaces.go
@@ -27,10 +27,14 @@ import (
// Application describes the application interface that interacts with DEXON
// consensus core.
type Application interface {
+ // PreparePayload is called when consensus core is preparing a block.
+ PreparePayloads(shardID, chainID, height uint64) [][]byte
+
// StronglyAcked is called when a block is strongly acked.
StronglyAcked(blockHash common.Hash)
- // TotalOrderingDeliver is called when the total ordering algorithm deliver // a set of block.
+ // TotalOrderingDeliver is called when the total ordering algorithm deliver
+ // a set of block.
TotalOrderingDeliver(blockHashes common.Hashes, early bool)
// DeliverBlock is called when a block is add to the compaction chain.
@@ -39,3 +43,16 @@ type Application interface {
// NotaryAckDeliver is called when a notary ack is created.
NotaryAckDeliver(notaryAck *types.NotaryAck)
}
+
+// Network describs the network interface that interacts with DEXON consensus
+// core.
+type Network interface {
+ // BroadcastVote broadcasts vote to all nodes in DEXON network.
+ BroadcastVote(vote *types.Vote)
+ // BroadcastBlock broadcasts block to all nodes in DEXON network.
+ BroadcastBlock(block *types.Block)
+ // BroadcastNotaryAck broadcasts notaryAck to all nodes in DEXON network.
+ BroadcastNotaryAck(notaryAck *types.NotaryAck)
+ // ReceiveChan returns a channel to receive messages from DEXON network.
+ ReceiveChan() <-chan interface{}
+}
diff --git a/core/nonblocking-application.go b/core/nonblocking-application.go
index ccdf42e..72f63b9 100644
--- a/core/nonblocking-application.go
+++ b/core/nonblocking-application.go
@@ -114,6 +114,12 @@ func (app *nonBlockingApplication) wait() {
app.running.Wait()
}
+// PreparePayloads cannot be non-blocking.
+func (app *nonBlockingApplication) PreparePayloads(
+ shardID, chainID, height uint64) [][]byte {
+ return app.app.PreparePayloads(shardID, chainID, height)
+}
+
// StronglyAcked is called when a block is strongly acked.
func (app *nonBlockingApplication) StronglyAcked(blockHash common.Hash) {
app.addEvent(stronglyAckedEvent{blockHash})
diff --git a/core/nonblocking-application_test.go b/core/nonblocking-application_test.go
index 336eea0..14fb670 100644
--- a/core/nonblocking-application_test.go
+++ b/core/nonblocking-application_test.go
@@ -45,6 +45,10 @@ func newSlowApp(sleep time.Duration) *slowApp {
}
}
+func (app *slowApp) PreparePayloads(_, _, _ uint64) [][]byte {
+ return [][]byte{}
+}
+
func (app *slowApp) StronglyAcked(blockHash common.Hash) {
time.Sleep(app.sleep)
app.stronglyAcked[blockHash] = struct{}{}
diff --git a/core/test/app.go b/core/test/app.go
index e26c20c..e36a184 100644
--- a/core/test/app.go
+++ b/core/test/app.go
@@ -102,6 +102,11 @@ func NewApp() *App {
}
}
+// PreparePayloads implements Application interface.
+func (app *App) PreparePayloads(shardID, chainID, height uint64) [][]byte {
+ return [][]byte{}
+}
+
// StronglyAcked implements Application interface.
func (app *App) StronglyAcked(blockHash common.Hash) {
app.ackedLock.Lock()
diff --git a/core/test/blocks-generator.go b/core/test/blocks-generator.go
index 3485b77..92271f7 100644
--- a/core/test/blocks-generator.go
+++ b/core/test/blocks-generator.go
@@ -39,7 +39,7 @@ type validatorStatus struct {
lastAckingHeight map[types.ValidatorID]uint64
}
-type hashBlockFn func(types.BlockConverter) (common.Hash, error)
+type hashBlockFn func(*types.Block) (common.Hash, error)
// getAckedBlockHash would randomly pick one block between
// last acked one to current head.
diff --git a/core/test/utils.go b/core/test/utils.go
index 789c28e..5f92ad9 100644
--- a/core/test/utils.go
+++ b/core/test/utils.go
@@ -25,8 +25,7 @@ import (
"github.com/dexon-foundation/dexon-consensus-core/core/types"
)
-func stableRandomHash(blockConv types.BlockConverter) (common.Hash, error) {
- block := blockConv.Block()
+func stableRandomHash(block *types.Block) (common.Hash, error) {
if (block.Hash != common.Hash{}) {
return block.Hash, nil
}
diff --git a/core/types/block.go b/core/types/block.go
index 1a55121..f13d868 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -70,6 +70,7 @@ type Block struct {
Height uint64 `json:"height"`
Timestamps map[ValidatorID]time.Time `json:"timestamps"`
Acks map[common.Hash]struct{} `json:"acks"`
+ Payloads [][]byte `json:"payloads"`
Signature crypto.Signature `json:"signature"`
CRSSignature crypto.Signature `json:"crs_signature"`
@@ -77,29 +78,6 @@ type Block struct {
Notary Notary `json:"notary"`
}
-// Block implements BlockConverter interface.
-func (b *Block) Block() *Block {
- return b
-}
-
-// Payloads impelmemnts BlockConverter interface.
-func (b *Block) Payloads() [][]byte {
- return [][]byte{}
-}
-
-// SetBlock implments BlockConverter interface.
-func (b *Block) SetBlock(block *Block) {
- *b = *block
-}
-
-// BlockConverter interface define the interface for extracting block
-// information from an existing object.
-type BlockConverter interface {
- Block() *Block
- Payloads() [][]byte
- SetBlock(block *Block)
-}
-
func (b *Block) String() string {
return fmt.Sprintf("Block(%v)", b.Hash.String()[:6])
}
@@ -130,6 +108,11 @@ func (b *Block) Clone() (bcopy *Block) {
for k, v := range b.Acks {
bcopy.Acks[k] = v
}
+ bcopy.Payloads = make([][]byte, len(b.Payloads))
+ for k, v := range b.Payloads {
+ bcopy.Payloads[k] = make([]byte, len(v))
+ copy(bcopy.Payloads[k], v)
+ }
return
}