Skip to content
This repository was archived by the owner on May 15, 2024. It is now read-only.

Commit 868e432

Browse files
author
dbachm123
authored
Merge pull request #119 from NanoTools/develop
Block confirmation times in API
2 parents 8a1f639 + 4db6b78 commit 868e432

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

api.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,51 @@
6767
$peers = (array) $rpcPeers->{'peers'};
6868
$data->numPeers = count($peers);
6969

70+
// -- Get confirmation info from nano_node. Average time, blocks used, time span and percentiles
71+
// -- over last X min (set by CONFIRMATION_TIME_LIMIT) or max 2048 blocks which is a node limitation
72+
//$timeStampBefore = microtime(true); // measure execution time
73+
$rpcConfHistory = getConfirmationHistory($ch);
74+
$confirmations = $rpcConfHistory->{'confirmations'}; // a list of last X confirmations {hash,duration,time,tally}
75+
//$confAverage = $rpcConfHistory->{'confirmation_stats'}->{'average'}; // average time [ms] of all confirmations
76+
//$confCount = $rpcConfHistory->{'confirmation_stats'}->{'count'}; // number of confirmations retrieved from the node
77+
78+
// remove data older than $timeLimit
79+
usort($confirmations, 'cmpByTime'); // sort array by time value [ms unix time]
80+
$confCompact = []; // new filtered array
81+
$durationTotal = 0; // for average calc
82+
$confAverage = 0; // average confirmation duration
83+
$timeSpan = 0; // full time span of the data [ms]
84+
foreach ($confirmations as $confirmation) {
85+
// only keep data which is later than X ms from latest (highest) value
86+
if ($confirmation->{'time'} >= $confirmations[0]->{'time'} - CONFIRMATION_TIME_LIMIT) {
87+
array_push($confCompact, $confirmation); // add new data
88+
$durationTotal += $confirmation->{'duration'};
89+
} else {
90+
break; // stop iterating once we pass that limit to save time
91+
}
92+
}
93+
$confCount = count($confCompact);
94+
95+
// calculate duration average and time span, avoid dividing by zero
96+
if ($confCount > 0) {
97+
$confAverage = round($durationTotal / $confCount);
98+
$timeSpan = $confCompact[0]->{'time'} - $confCompact[$confCount - 1]->{'time'}; // first minus last
99+
}
100+
101+
// get percentiles directly from the filtered array
102+
usort($confCompact, 'cmpByDuration'); // sort array by duration value
103+
$percentile50 = getConfirmationsDurationPercentile(50, $confCompact); // 50 percentile also called median
104+
$percentile75 = getConfirmationsDurationPercentile(75, $confCompact);
105+
$percentile90 = getConfirmationsDurationPercentile(90, $confCompact);
106+
$percentile95 = getConfirmationsDurationPercentile(95, $confCompact);
107+
$percentile99 = getConfirmationsDurationPercentile(99, $confCompact);
108+
109+
// combine an array with all confirmation info
110+
$confSummary = ['count' => $confCount, 'timeSpan' => $timeSpan, 'average' => $confAverage, 'percentile50' => $percentile50,
111+
'percentile75' => $percentile75, 'percentile90' => $percentile90, 'percentile95' => $percentile95, 'percentile99' => $percentile99, ];
112+
$data->confirmationInfo = $confSummary;
113+
//$data->apiProcTimeConf = round((microtime(true) - $timeStampBefore) * 1000);
114+
70115
// -- Get node account balance from nano_node
71116
$rpcNodeAccountBalance = getAccountBalance($ch, $nanoNodeAccount);
72117
$data->accBalanceMnano = rawToCurrency($rpcNodeAccountBalance->{'balance'}, $currency);
@@ -122,6 +167,9 @@
122167
// close curl handle
123168
curl_close($ch);
124169

170+
// calculate total script execution time
171+
$data->apiProcTime = round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000);
172+
125173
return $data;
126174
});
127175

modules/constants.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
// the project version
4-
define('PROJECT_VERSION', '1.4.14');
4+
define('PROJECT_VERSION', '1.5.0');
55

66
// project URL
77
define('PROJECT_URL', 'https://github.com/NanoTools/nanoNodeMonitor');
@@ -29,3 +29,6 @@
2929

3030
// curl timeout in seconds to connect to ninja (max delay is NINJA_TIMEOUT + NINJA_CONECTTIMEOUT)
3131
define ('NINJA_CONECTTIMEOUT', 2);
32+
33+
// maximum allowed age of data to be part of the block confirmation time percentiles calculation (milliseconds)
34+
define ('CONFIRMATION_TIME_LIMIT', 600000);

modules/functions.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,29 @@ function currencySymbol($currency)
510510
}
511511

512512
}
513+
514+
// sort array by 'duration' sub value
515+
function cmpByDuration($a, $b) {
516+
return $a->{'duration'} - $b->{'duration'};
517+
}
518+
519+
// sort array by 'time' sub value (largest first)
520+
function cmpByTime($a, $b) {
521+
return $b->{'time'} - $a->{'time'};
522+
}
523+
524+
// get a percentile from a sorted json structure which contains sub element values with the name 'duration'
525+
// ex: get_percentile(75, $arr) to get the 75th percentile
526+
function getConfirmationsDurationPercentile($percentile, $array) {
527+
if (empty($array)) {
528+
return 0;
529+
}
530+
$index = ($percentile/100) * count($array);
531+
if (floor($index) == $index) {
532+
$result = ($array[$index-1]->{'duration'} + $array[$index]->{'duration'})/2;
533+
}
534+
else {
535+
$result = $array[floor($index)]->{'duration'};
536+
}
537+
return $result;
538+
}

modules/functions_rpc.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,13 @@ function getStats($ch, $type = "counters")
102102
// post curl
103103
return postCurl($ch, $data);
104104
}
105+
106+
// get confirmation history from nano_node
107+
function getConfirmationHistory($ch)
108+
{
109+
// get confirmation history of latest 2048 elections
110+
$data = array("action" => "confirmation_history");
111+
112+
// post curl
113+
return postCurl($ch, $data);
114+
}

0 commit comments

Comments
 (0)