diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2018-08-07 14:33:13 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-07 14:33:13 +0800 |
commit | 3a929b656b6bd5846849fd98dc29ff761db97ed3 (patch) | |
tree | 25438de64f434866293aa408915c735352949e6f /simulation/app.go | |
parent | 5a818558fc0e8f038ba92b5b6dfa3b55a04b9589 (diff) | |
download | dexon-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.go | 97 |
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) } |