From 18c6a28ff021c9dc643091b5dc420b51183253cf Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Fri, 31 Aug 2018 13:34:00 +0800 Subject: Add methods to Application interface. (#86) --- core/consensus.go | 1 + core/interfaces.go | 6 ++++++ core/nonblocking-application.go | 16 ++++++++++++++++ core/nonblocking-application_test.go | 13 +++++++++++++ core/test/app.go | 9 +++++++++ 5 files changed, 45 insertions(+) (limited to 'core') diff --git a/core/consensus.go b/core/consensus.go index d6b5efd..4d1a386 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -245,6 +245,7 @@ func (con *Consensus) ProcessBlock(b *types.Block) (err error) { if err = con.rbModule.processBlock(b); err != nil { return err } + con.app.BlockConfirmed(b.Clone()) for _, b := range con.rbModule.extractBlocks() { // Notify application layer that some block is strongly acked. con.app.StronglyAcked(b.Hash) diff --git a/core/interfaces.go b/core/interfaces.go index 364f2da..4376742 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -30,6 +30,12 @@ type Application interface { // PreparePayload is called when consensus core is preparing a block. PreparePayloads(shardID, chainID, height uint64) [][]byte + // VerifyPayloads verifies if the payloads are valid. + VerifyPayloads(payloads [][]byte) bool + + // BlockConfirmed is called when a block is confirmed and added to lattice. + BlockConfirmed(block *types.Block) + // StronglyAcked is called when a block is strongly acked. StronglyAcked(blockHash common.Hash) diff --git a/core/nonblocking-application.go b/core/nonblocking-application.go index 72f63b9..fb25745 100644 --- a/core/nonblocking-application.go +++ b/core/nonblocking-application.go @@ -26,6 +26,10 @@ import ( "github.com/dexon-foundation/dexon-consensus-core/core/types" ) +type blockConfirmedEvent struct { + block *types.Block +} + type stronglyAckedEvent struct { blockHash common.Hash } @@ -90,6 +94,8 @@ func (app *nonBlockingApplication) run() { switch e := event.(type) { case stronglyAckedEvent: app.app.StronglyAcked(e.blockHash) + case blockConfirmedEvent: + app.app.BlockConfirmed(e.block) case totalOrderingDeliverEvent: app.app.TotalOrderingDeliver(e.blockHashes, e.early) case deliverBlockEvent: @@ -120,6 +126,16 @@ func (app *nonBlockingApplication) PreparePayloads( return app.app.PreparePayloads(shardID, chainID, height) } +// VerifyPayloads cannot be non-blocking. +func (app *nonBlockingApplication) VerifyPayloads(payloads [][]byte) bool { + return true +} + +// BlockConfirmed is called when a block is confirmed and added to lattice. +func (app *nonBlockingApplication) BlockConfirmed(block *types.Block) { + app.addEvent(blockConfirmedEvent{block}) +} + // 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 14fb670..65c5700 100644 --- a/core/nonblocking-application_test.go +++ b/core/nonblocking-application_test.go @@ -29,6 +29,7 @@ import ( type slowApp struct { sleep time.Duration + blockConfirmed map[common.Hash]struct{} stronglyAcked map[common.Hash]struct{} totalOrderingDeliver map[common.Hash]struct{} deliverBlock map[common.Hash]struct{} @@ -38,6 +39,7 @@ type slowApp struct { func newSlowApp(sleep time.Duration) *slowApp { return &slowApp{ sleep: sleep, + blockConfirmed: make(map[common.Hash]struct{}), stronglyAcked: make(map[common.Hash]struct{}), totalOrderingDeliver: make(map[common.Hash]struct{}), deliverBlock: make(map[common.Hash]struct{}), @@ -49,6 +51,15 @@ func (app *slowApp) PreparePayloads(_, _, _ uint64) [][]byte { return [][]byte{} } +func (app *slowApp) VerifyPayloads(_ [][]byte) bool { + return true +} + +func (app *slowApp) BlockConfirmed(block *types.Block) { + time.Sleep(app.sleep) + app.blockConfirmed[block.Hash] = struct{}{} +} + func (app *slowApp) StronglyAcked(blockHash common.Hash) { time.Sleep(app.sleep) app.stronglyAcked[blockHash] = struct{}{} @@ -88,6 +99,7 @@ func (s *NonBlockingAppTestSuite) TestNonBlockingApplication() { // Start doing some 'heavy' job. for _, hash := range hashes { + nbapp.BlockConfirmed(&types.Block{Hash: hash}) nbapp.StronglyAcked(hash) nbapp.DeliverBlock(hash, time.Now().UTC()) nbapp.NotaryAckDeliver(&types.NotaryAck{Hash: hash}) @@ -99,6 +111,7 @@ func (s *NonBlockingAppTestSuite) TestNonBlockingApplication() { nbapp.wait() for _, hash := range hashes { + s.Contains(app.blockConfirmed, hash) s.Contains(app.stronglyAcked, hash) s.Contains(app.totalOrderingDeliver, hash) s.Contains(app.deliverBlock, hash) diff --git a/core/test/app.go b/core/test/app.go index e36a184..3ed65f7 100644 --- a/core/test/app.go +++ b/core/test/app.go @@ -107,6 +107,15 @@ func (app *App) PreparePayloads(shardID, chainID, height uint64) [][]byte { return [][]byte{} } +// VerifyPayloads implements Application. +func (app *App) VerifyPayloads(payloads [][]byte) bool { + return true +} + +// BlockConfirmed implements Application interface. +func (app *App) BlockConfirmed(block *types.Block) { +} + // StronglyAcked implements Application interface. func (app *App) StronglyAcked(blockHash common.Hash) { app.ackedLock.Lock() -- cgit v1.2.3