Skip to content

Commit c286ba2

Browse files
lukechampineChrisSchinnerl
authored andcommitted
api: Add drift to /metrics/difficulty
1 parent 19cb192 commit c286ba2

File tree

5 files changed

+26
-4
lines changed

5 files changed

+26
-4
lines changed

api/api_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,11 +392,13 @@ func TestAPI(t *testing.T) {
392392
}
393393
difficulties := make([]consensus.Work, 2)
394394
blockTimes := make([]time.Duration, 2)
395+
drifts := make([]time.Duration, 2)
395396
for i, height := range []uint64{1, 2} {
396397
index, _ := cm.BestIndex(height)
397398
cs, _ := cm.State(index.ID)
398399
difficulties[i] = cs.Difficulty
399400
blockTimes[i] = cs.PrevTimestamps[0].Sub(cs.PrevTimestamps[1])
401+
drifts[i] = cs.PrevTimestamps[0].Sub(network.HardforkOak.GenesisTimestamp.Add(time.Duration(height) * network.BlockInterval))
400402
}
401403
testutil.Equal(t, "blocks per step", 1, resp.BlocksPerStep)
402404
testutil.Equal(t, "difficulties", difficulties, resp.Difficulties)
@@ -409,17 +411,20 @@ func TestAPI(t *testing.T) {
409411
}
410412
difficulties := make([]consensus.Work, 2)
411413
blockTimes := make([]time.Duration, 2)
414+
drifts := make([]time.Duration, 2)
412415
for i, height := range []uint64{0, 2} {
413416
index, _ := cm.BestIndex(height)
414417
cs, _ := cm.State(index.ID)
415418
difficulties[i] = cs.Difficulty
416419
if i > 0 {
417420
blockTimes[i] = cs.PrevTimestamps[0].Sub(cs.PrevTimestamps[2]) / 2
418421
}
422+
drifts[i] = cs.PrevTimestamps[0].Sub(network.HardforkOak.GenesisTimestamp.Add(time.Duration(height) * network.BlockInterval))
419423
}
420424
testutil.Equal(t, "blocks per step", 2, resp.BlocksPerStep)
421425
testutil.Equal(t, "difficulties", difficulties, resp.Difficulties)
422426
testutil.Equal(t, "block times", blockTimes, resp.BlockTimes)
427+
testutil.Equal(t, "drifts", drifts, resp.Drifts)
423428
}},
424429
{"Block", func(t *testing.T) {
425430
tip := cm.Tip()

explorer/explorer.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ type Store interface {
9090
LastSuccessScan() (time.Time, error)
9191
HostMetrics() (HostMetrics, error)
9292
BlockTimeMetrics(blockTime time.Duration) (BlockTimeMetrics, error)
93-
DifficultyMetrics(start, end, step uint64) (DifficultyMetrics, error)
93+
DifficultyMetrics(start, end, step uint64, n *consensus.Network) (DifficultyMetrics, error)
9494
Transactions(ids []types.TransactionID) ([]Transaction, error)
9595
TransactionChainIndices(txid types.TransactionID, offset, limit uint64) ([]types.ChainIndex, error)
9696
V2Transactions(ids []types.TransactionID) ([]V2Transaction, error)
@@ -343,7 +343,7 @@ func (e *Explorer) BlockTimeMetrics() (BlockTimeMetrics, error) {
343343

344344
// DifficultyMetrics returns various difficulty-related metrics.
345345
func (e *Explorer) DifficultyMetrics(start, end, step uint64) (DifficultyMetrics, error) {
346-
return e.s.DifficultyMetrics(start, end, step)
346+
return e.s.DifficultyMetrics(start, end, step, e.cm.TipState().Network)
347347
}
348348

349349
// Transactions returns the transactions with the specified IDs.

explorer/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ type DifficultyMetrics struct {
618618
BlocksPerStep uint64 `json:"blocksPerStep"`
619619
Difficulties []consensus.Work `json:"difficulties"`
620620
BlockTimes []time.Duration `json:"blockTimes"`
621+
Drifts []time.Duration `json:"drifts"`
621622
}
622623

623624
// TopSiacoin pairs an address with its Siacoin balance

persist/sqlite/metrics.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ func (s *Store) BlockTimeMetrics(blockTime time.Duration) (result explorer.Block
274274
}
275275

276276
// DifficultyMetrics implements Store.
277-
func (s *Store) DifficultyMetrics(start, end, step uint64) (result explorer.DifficultyMetrics, err error) {
277+
func (s *Store) DifficultyMetrics(start, end, step uint64, n *consensus.Network) (result explorer.DifficultyMetrics, err error) {
278278
err = s.transaction(func(tx *txn) error {
279279
if start > end {
280280
return fmt.Errorf("start height %d cannot be greater than end height %d", start, end)
@@ -326,11 +326,18 @@ func (s *Store) DifficultyMetrics(start, end, step uint64) (result explorer.Diff
326326
result.BlockTimes[i] = timestamps[i].Sub(timestamps[i-1]) / time.Duration(step)
327327
}
328328
}
329+
result.Drifts = make([]time.Duration, len(timestamps))
330+
for i := range result.Drifts {
331+
height := start + uint64(i)*step
332+
expected := n.HardforkOak.GenesisTimestamp.Add(time.Duration(height) * n.BlockInterval)
333+
result.Drifts[i] = timestamps[i].Sub(expected)
334+
}
329335

330336
// trim if necessary
331337
if start > 0 {
332338
result.Difficulties = result.Difficulties[1:]
333339
result.BlockTimes = result.BlockTimes[1:]
340+
result.Drifts = result.Drifts[1:]
334341
}
335342
return nil
336343
})

persist/sqlite/metrics_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ func TestDifficultyMetrics(t *testing.T) {
472472
}
473473
for _, tt := range tests {
474474
t.Run(tt.name, func(t *testing.T) {
475-
result, err := n.db.DifficultyMetrics(tt.start, tt.end, tt.step)
475+
result, err := n.db.DifficultyMetrics(tt.start, tt.end, tt.step, n.tipState().Network)
476476
if tt.err != "" {
477477
if err == nil || !strings.Contains(err.Error(), tt.err) {
478478
t.Fatalf("Expected %v, got %v", tt.err, err)
@@ -500,6 +500,9 @@ func TestDifficultyMetrics(t *testing.T) {
500500
if len(result.BlockTimes) == 0 {
501501
t.Error("Expected some block time data but got none")
502502
}
503+
if len(result.Drifts) == 0 {
504+
t.Error("Expected some drift data but got none")
505+
}
503506

504507
// Check that block times are reasonable (between 1 second and 1 hour)
505508
for i, blockTime := range result.BlockTimes {
@@ -511,6 +514,12 @@ func TestDifficultyMetrics(t *testing.T) {
511514
t.Errorf("BlockTime[%d] = %v, seems unreasonable", i, blockTime)
512515
}
513516
}
517+
// Check that the drifts are reasonable (between -1 hour and +1 hour)
518+
for i, drift := range result.Drifts {
519+
if drift < -time.Hour || drift > time.Hour {
520+
t.Errorf("Drift[%d] = %v, seems unreasonable", i, drift)
521+
}
522+
}
514523
})
515524
}
516525
}

0 commit comments

Comments
 (0)