aboutsummaryrefslogtreecommitdiffstats
path: root/simulation/app.go
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2018-08-07 14:33:13 +0800
committerGitHub <noreply@github.com>2018-08-07 14:33:13 +0800
commit3a929b656b6bd5846849fd98dc29ff761db97ed3 (patch)
tree25438de64f434866293aa408915c735352949e6f /simulation/app.go
parent5a818558fc0e8f038ba92b5b6dfa3b55a04b9589 (diff)
downloaddexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar.gz
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar.bz2
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar.lz
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar.xz
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.tar.zst
dexon-consensus-3a929b656b6bd5846849fd98dc29ff761db97ed3.zip
simulation: Show internal and external timestamp latency. (#30)
Diffstat (limited to 'simulation/app.go')
-rw-r--r--simulation/app.go97
1 files changed, 94 insertions, 3 deletions
diff --git a/simulation/app.go b/simulation/app.go
index aea7acf..5533abb 100644
--- a/simulation/app.go
+++ b/simulation/app.go
@@ -18,6 +18,7 @@
package simulation
import (
+ "encoding/json"
"fmt"
"time"
@@ -32,17 +33,50 @@ type SimApp struct {
Early bool
Network PeerServerNetwork
DeliverID int
+ // blockSeen stores the time when block is delivered by Total Ordering.
+ blockSeen map[common.Hash]time.Time
+ // uncofirmBlocks stores the blocks whose timestamps are not ready.
+ unconfirmedBlocks map[types.ValidatorID]common.Hashes
+ blockHash map[common.Hash]*types.Block
}
// NewSimApp returns point to a new instance of SimApp.
func NewSimApp(id types.ValidatorID, Network PeerServerNetwork) *SimApp {
return &SimApp{
- ValidatorID: id,
- Network: Network,
- DeliverID: 0,
+ ValidatorID: id,
+ Network: Network,
+ DeliverID: 0,
+ blockSeen: make(map[common.Hash]time.Time),
+ unconfirmedBlocks: make(map[types.ValidatorID]common.Hashes),
+ blockHash: make(map[common.Hash]*types.Block),
}
}
+// getAckedBlocks will return all unconfirmed blocks' hash with lower Height
+// than the block with ackHash.
+func (a *SimApp) getAckedBlocks(ackHash common.Hash) (output common.Hashes) {
+ // TODO(jimmy-dexon): Why there are some acks never seen?
+ ackBlock, exist := a.blockHash[ackHash]
+ if !exist {
+ return
+ }
+ hashes, exist := a.unconfirmedBlocks[ackBlock.ProposerID]
+ if !exist {
+ return
+ }
+ for i, blockHash := range hashes {
+ if a.blockHash[blockHash].Height > ackBlock.Height {
+ output, a.unconfirmedBlocks[ackBlock.ProposerID] = hashes[:i], hashes[i:]
+ break
+ }
+ }
+ // All of the Height of unconfirmed blocks are lower than the acked block.
+ if len(output) == 0 {
+ output, a.unconfirmedBlocks[ackBlock.ProposerID] = hashes, common.Hashes{}
+ }
+ return
+}
+
// TotalOrderingDeliver is called when blocks are delivered by the total
// ordering algorithm.
func (a *SimApp) TotalOrderingDeliver(blocks []*types.Block, early bool) {
@@ -54,12 +88,37 @@ func (a *SimApp) TotalOrderingDeliver(blocks []*types.Block, early bool) {
blockHash := common.Hashes{}
confirmLatency := []time.Duration{}
+ payload := []TimestampMessage{}
for _, block := range blocks {
blockHash = append(blockHash, block.Hash)
if block.ProposerID == a.ValidatorID {
confirmLatency = append(confirmLatency,
now.Sub(block.Timestamps[a.ValidatorID]))
}
+ // TODO(jimmy-dexon) : Remove block in this hash if it's no longer needed.
+ a.blockHash[block.Hash] = block
+ for hash := range block.Acks {
+ for _, blockHash := range a.getAckedBlocks(hash) {
+ payload = append(payload, TimestampMessage{
+ BlockHash: blockHash,
+ Event: timestampAck,
+ Timestamp: now,
+ })
+ delete(a.blockSeen, block.Hash)
+ }
+ }
+ }
+ if len(payload) > 0 {
+ jsonPayload, err := json.Marshal(payload)
+ if err != nil {
+ fmt.Println(err)
+ } else {
+ msg := Message{
+ Type: blockTimestamp,
+ Payload: jsonPayload,
+ }
+ a.Network.NotifyServer(msg)
+ }
}
blockList := BlockList{
@@ -69,8 +128,40 @@ func (a *SimApp) TotalOrderingDeliver(blocks []*types.Block, early bool) {
}
a.Network.DeliverBlocks(blockList)
a.DeliverID++
+ for _, block := range blocks {
+ a.blockSeen[block.Hash] = now
+ a.unconfirmedBlocks[block.ProposerID] = append(
+ a.unconfirmedBlocks[block.ProposerID], block.Hash)
+ }
}
// DeliverBlock is called when a block in compaction chain is delivered.
func (a *SimApp) DeliverBlock(blockHash common.Hash, timestamp time.Time) {
+ seenTime, exist := a.blockSeen[blockHash]
+ if !exist {
+ return
+ }
+ now := time.Now()
+ payload := []TimestampMessage{
+ {
+ BlockHash: blockHash,
+ Event: blockSeen,
+ Timestamp: seenTime,
+ },
+ {
+ BlockHash: blockHash,
+ Event: timestampConfirm,
+ Timestamp: now,
+ },
+ }
+ jsonPayload, err := json.Marshal(payload)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ msg := Message{
+ Type: blockTimestamp,
+ Payload: jsonPayload,
+ }
+ a.Network.NotifyServer(msg)
}