diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-08-30 17:21:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-30 17:21:58 +0800 |
commit | 96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8 (patch) | |
tree | 418e2c43acf4f9c13289eaccf66f94ef46c9356b | |
parent | a4e0da981a3dfc8817d39be65cb5b24938b0761a (diff) | |
download | dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.gz dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.tar.zst dexon-consensus-96554a3bc14030e5d0dfc9dc1ee6bcdd9a133fa8.zip |
core: Add PreparePayloads to Application and Remove blockConverter interface. (#84)
-rw-r--r-- | core/consensus.go | 21 | ||||
-rw-r--r-- | core/crypto.go | 10 | ||||
-rw-r--r-- | core/crypto_test.go | 24 | ||||
-rw-r--r-- | core/interfaces.go (renamed from core/application.go) | 19 | ||||
-rw-r--r-- | core/nonblocking-application.go | 6 | ||||
-rw-r--r-- | core/nonblocking-application_test.go | 4 | ||||
-rw-r--r-- | core/test/app.go | 5 | ||||
-rw-r--r-- | core/test/blocks-generator.go | 2 | ||||
-rw-r--r-- | core/test/utils.go | 3 | ||||
-rw-r--r-- | core/types/block.go | 29 | ||||
-rw-r--r-- | simulation/app.go | 5 | ||||
-rw-r--r-- | simulation/network.go | 7 | ||||
-rw-r--r-- | simulation/tcp-network.go | 6 | ||||
-rw-r--r-- | simulation/validator.go | 5 |
14 files changed, 73 insertions, 73 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 } diff --git a/simulation/app.go b/simulation/app.go index 635b071..78e1d9a 100644 --- a/simulation/app.go +++ b/simulation/app.go @@ -88,6 +88,11 @@ func (a *simApp) getAckedBlocks(ackHash common.Hash) (output common.Hashes) { return } +// PreparePayloads implements core.Application. +func (a *simApp) PreparePayloads(shardID, chainID, height uint64) [][]byte { + return [][]byte{} +} + // StronglyAcked is called when a block is strongly acked by DEXON // Reliabe Broadcast algorithm. func (a *simApp) StronglyAcked(blockHash common.Hash) { diff --git a/simulation/network.go b/simulation/network.go index 687dd90..791790c 100644 --- a/simulation/network.go +++ b/simulation/network.go @@ -22,6 +22,7 @@ import ( "time" "github.com/dexon-foundation/dexon-consensus-core/common" + "github.com/dexon-foundation/dexon-consensus-core/core" "github.com/dexon-foundation/dexon-consensus-core/core/types" ) @@ -76,12 +77,10 @@ type Endpoint interface { // Network is the interface for network related functions. type Network interface { PeerServerNetwork + core.Network Start() NumPeers() int - Join(endpoint Endpoint) chan interface{} - BroadcastBlock(block *types.Block) - BroadcastNotaryAck(notaryAck *types.NotaryAck) - BroadcastVote(vote *types.Vote) + Join(endpoint Endpoint) Endpoints() types.ValidatorIDs } diff --git a/simulation/tcp-network.go b/simulation/tcp-network.go index f30284b..31c8d95 100644 --- a/simulation/tcp-network.go +++ b/simulation/tcp-network.go @@ -176,7 +176,7 @@ func (n *TCPNetwork) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Join allow a client to join the network. It reutnrs a interface{} channel for // the client to recieve information. -func (n *TCPNetwork) Join(endpoint Endpoint) chan interface{} { +func (n *TCPNetwork) Join(endpoint Endpoint) { n.endpointMutex.Lock() defer n.endpointMutex.Unlock() @@ -235,6 +235,10 @@ func (n *TCPNetwork) Join(endpoint Endpoint) chan interface{} { for key, val := range peerList { n.endpoints[key] = val } +} + +// ReceiveChan return the receive channel. +func (n *TCPNetwork) ReceiveChan() <-chan interface{} { return n.recieveChan } diff --git a/simulation/validator.go b/simulation/validator.go index 302f3af..8a672c5 100644 --- a/simulation/validator.go +++ b/simulation/validator.go @@ -38,7 +38,7 @@ type Validator struct { db blockdb.BlockDatabase config config.Validator - msgChannel chan interface{} + msgChannel <-chan interface{} isFinished chan struct{} ID types.ValidatorID @@ -84,7 +84,8 @@ func (v *Validator) GetID() types.ValidatorID { // Run starts the validator. func (v *Validator) Run() { - v.msgChannel = v.network.Join(v) + v.network.Join(v) + v.msgChannel = v.network.ReceiveChan() hashes := make(common.Hashes, 0, v.network.NumPeers()) for _, vID := range v.network.Endpoints() { |