diff options
Diffstat (limited to 'integration_test/stats.go')
-rw-r--r-- | integration_test/stats.go | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/integration_test/stats.go b/integration_test/stats.go deleted file mode 100644 index 5d66e29..0000000 --- a/integration_test/stats.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2018 The dexon-consensus Authors -// This file is part of the dexon-consensus library. -// -// The dexon-consensus 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 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 library. If not, see -// <http://www.gnu.org/licenses/>. - -package integration - -import ( - "fmt" - "time" - - "github.com/dexon-foundation/dexon-consensus/core/test" - "github.com/dexon-foundation/dexon-consensus/core/types" -) - -// Errors when calculating statistics for events. -var ( - ErrUnknownEvent = fmt.Errorf("unknown event") - ErrUnknownConsensusEventType = fmt.Errorf("unknown consensus event type") -) - -// StatsSet represents accumulatee result of a group of related events -// (ex. All events from one node). -type StatsSet struct { - ProposedBlockCount int - ReceivedBlockCount int - ConfirmedBlockCount int - TotalOrderedBlockCount int - DeliveredBlockCount int - ProposingLatency time.Duration - ReceivingLatency time.Duration - PrepareExecLatency time.Duration - ProcessExecLatency time.Duration -} - -// newBlockProposeEvent accumulates a block proposing event. -func (s *StatsSet) newBlockProposeEvent( - e *test.Event, payload *consensusEventPayload, history []*test.Event) { - - // Find previous block proposing event. - if e.ParentHistoryIndex != -1 { - parentEvent := history[e.ParentHistoryIndex] - s.ProposingLatency += - e.Time.Sub(parentEvent.Time) - parentEvent.ExecInterval - } - s.PrepareExecLatency += e.ExecInterval - s.ProposedBlockCount++ -} - -// newBlockReceiveEvent accumulates a block received event. -func (s *StatsSet) newBlockReceiveEvent( - e *test.Event, - payload *consensusEventPayload, - history []*test.Event, - app *test.App) { - - // Find previous block proposing event. - parentEvent := history[e.ParentHistoryIndex] - s.ReceivingLatency += - e.Time.Sub(parentEvent.Time) - parentEvent.ExecInterval - s.ProcessExecLatency += e.ExecInterval - s.ReceivedBlockCount++ - - // Find statistics from test.App - block := payload.PiggyBack.(*types.Block) - app.WithLock(func(app *test.App) { - // Is this block confirmed? - if _, exists := app.Confirmed[block.Hash]; !exists { - return - } - s.ConfirmedBlockCount++ - // Is this block total ordered? - if _, exists := app.TotalOrderedByHash[block.Hash]; !exists { - return - } - s.TotalOrderedBlockCount++ - - // Is this block delivered? - if _, exists := app.Delivered[block.Hash]; !exists { - return - } - s.DeliveredBlockCount++ - }) -} - -// done would divide the latencies we cached with related event count. This way -// to calculate average latency is more accurate. -func (s *StatsSet) done(nodeCount int) { - s.ProposingLatency /= time.Duration(s.ProposedBlockCount - nodeCount) - s.ReceivingLatency /= time.Duration(s.ReceivedBlockCount) - s.PrepareExecLatency /= time.Duration(s.ProposedBlockCount) - s.ProcessExecLatency /= time.Duration(s.ReceivedBlockCount) -} - -// Stats is statistics of a slice of test.Event generated by nodes. -type Stats struct { - ByNode map[types.NodeID]*StatsSet - All *StatsSet - BPS float64 - ExecutionTime time.Duration -} - -// NewStats constructs an Stats instance by providing a slice of -// test.Event. -func NewStats( - history []*test.Event, apps map[types.NodeID]*test.App) ( - stats *Stats, err error) { - - stats = &Stats{ - ByNode: make(map[types.NodeID]*StatsSet), - All: &StatsSet{}, - } - if err = stats.calculate(history, apps); err != nil { - stats = nil - } - stats.summary(history) - return -} - -func (stats *Stats) calculate( - history []*test.Event, apps map[types.NodeID]*test.App) error { - - defer func() { - stats.All.done(len(stats.ByNode)) - for _, set := range stats.ByNode { - set.done(1) - } - }() - - for _, e := range history { - payload, ok := e.Payload.(*consensusEventPayload) - if !ok { - return ErrUnknownEvent - } - switch payload.Type { - case evtProposeBlock: - stats.All.newBlockProposeEvent( - e, payload, history) - stats.getStatsSetByNode(e.NodeID).newBlockProposeEvent( - e, payload, history) - case evtReceiveBlock: - stats.All.newBlockReceiveEvent( - e, payload, history, apps[e.NodeID]) - stats.getStatsSetByNode(e.NodeID).newBlockReceiveEvent( - e, payload, history, apps[e.NodeID]) - default: - return ErrUnknownConsensusEventType - } - } - return nil -} - -func (stats *Stats) getStatsSetByNode( - vID types.NodeID) (s *StatsSet) { - - s = stats.ByNode[vID] - if s == nil { - s = &StatsSet{} - stats.ByNode[vID] = s - } - return -} - -func (stats *Stats) summary(history []*test.Event) { - // Find average delivered block count among all blocks. - totalConfirmedBlocks := 0 - for _, s := range stats.ByNode { - totalConfirmedBlocks += s.DeliveredBlockCount - } - averageConfirmedBlocks := totalConfirmedBlocks / len(stats.ByNode) - - // Find execution time. - // Note: it's a simplified way to calculate the execution time: - // the latest event might not be at the end of history when - // the number of worker routine is larger than 1. - stats.ExecutionTime = history[len(history)-1].Time.Sub(history[0].Time) - // Calculate BPS. - latencyAsSecond := stats.ExecutionTime.Nanoseconds() / (1000 * 1000 * 1000) - stats.BPS = float64(averageConfirmedBlocks) / float64(latencyAsSecond) -} |