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

Commit

Permalink
Merge pull request #119 from NanoTools/develop
Browse files Browse the repository at this point in the history
Block confirmation times in API
  • Loading branch information
dbachm123 authored Mar 2, 2019
2 parents 8a1f639 + 4db6b78 commit 868e432
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
48 changes: 48 additions & 0 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,51 @@
$peers = (array) $rpcPeers->{'peers'};
$data->numPeers = count($peers);

// -- Get confirmation info from nano_node. Average time, blocks used, time span and percentiles
// -- over last X min (set by CONFIRMATION_TIME_LIMIT) or max 2048 blocks which is a node limitation
//$timeStampBefore = microtime(true); // measure execution time
$rpcConfHistory = getConfirmationHistory($ch);
$confirmations = $rpcConfHistory->{'confirmations'}; // a list of last X confirmations {hash,duration,time,tally}
//$confAverage = $rpcConfHistory->{'confirmation_stats'}->{'average'}; // average time [ms] of all confirmations
//$confCount = $rpcConfHistory->{'confirmation_stats'}->{'count'}; // number of confirmations retrieved from the node

// remove data older than $timeLimit
usort($confirmations, 'cmpByTime'); // sort array by time value [ms unix time]
$confCompact = []; // new filtered array
$durationTotal = 0; // for average calc
$confAverage = 0; // average confirmation duration
$timeSpan = 0; // full time span of the data [ms]
foreach ($confirmations as $confirmation) {
// only keep data which is later than X ms from latest (highest) value
if ($confirmation->{'time'} >= $confirmations[0]->{'time'} - CONFIRMATION_TIME_LIMIT) {
array_push($confCompact, $confirmation); // add new data
$durationTotal += $confirmation->{'duration'};
} else {
break; // stop iterating once we pass that limit to save time
}
}
$confCount = count($confCompact);

// calculate duration average and time span, avoid dividing by zero
if ($confCount > 0) {
$confAverage = round($durationTotal / $confCount);
$timeSpan = $confCompact[0]->{'time'} - $confCompact[$confCount - 1]->{'time'}; // first minus last
}

// get percentiles directly from the filtered array
usort($confCompact, 'cmpByDuration'); // sort array by duration value
$percentile50 = getConfirmationsDurationPercentile(50, $confCompact); // 50 percentile also called median
$percentile75 = getConfirmationsDurationPercentile(75, $confCompact);
$percentile90 = getConfirmationsDurationPercentile(90, $confCompact);
$percentile95 = getConfirmationsDurationPercentile(95, $confCompact);
$percentile99 = getConfirmationsDurationPercentile(99, $confCompact);

// combine an array with all confirmation info
$confSummary = ['count' => $confCount, 'timeSpan' => $timeSpan, 'average' => $confAverage, 'percentile50' => $percentile50,
'percentile75' => $percentile75, 'percentile90' => $percentile90, 'percentile95' => $percentile95, 'percentile99' => $percentile99, ];
$data->confirmationInfo = $confSummary;
//$data->apiProcTimeConf = round((microtime(true) - $timeStampBefore) * 1000);

// -- Get node account balance from nano_node
$rpcNodeAccountBalance = getAccountBalance($ch, $nanoNodeAccount);
$data->accBalanceMnano = rawToCurrency($rpcNodeAccountBalance->{'balance'}, $currency);
Expand Down Expand Up @@ -122,6 +167,9 @@
// close curl handle
curl_close($ch);

// calculate total script execution time
$data->apiProcTime = round((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000);

return $data;
});

Expand Down
5 changes: 4 additions & 1 deletion modules/constants.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

// the project version
define('PROJECT_VERSION', '1.4.14');
define('PROJECT_VERSION', '1.5.0');

// project URL
define('PROJECT_URL', 'https://github.com/NanoTools/nanoNodeMonitor');
Expand Down Expand Up @@ -29,3 +29,6 @@

// curl timeout in seconds to connect to ninja (max delay is NINJA_TIMEOUT + NINJA_CONECTTIMEOUT)
define ('NINJA_CONECTTIMEOUT', 2);

// maximum allowed age of data to be part of the block confirmation time percentiles calculation (milliseconds)
define ('CONFIRMATION_TIME_LIMIT', 600000);
26 changes: 26 additions & 0 deletions modules/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,3 +510,29 @@ function currencySymbol($currency)
}

}

// sort array by 'duration' sub value
function cmpByDuration($a, $b) {
return $a->{'duration'} - $b->{'duration'};
}

// sort array by 'time' sub value (largest first)
function cmpByTime($a, $b) {
return $b->{'time'} - $a->{'time'};
}

// get a percentile from a sorted json structure which contains sub element values with the name 'duration'
// ex: get_percentile(75, $arr) to get the 75th percentile
function getConfirmationsDurationPercentile($percentile, $array) {
if (empty($array)) {
return 0;
}
$index = ($percentile/100) * count($array);
if (floor($index) == $index) {
$result = ($array[$index-1]->{'duration'} + $array[$index]->{'duration'})/2;
}
else {
$result = $array[floor($index)]->{'duration'};
}
return $result;
}
10 changes: 10 additions & 0 deletions modules/functions_rpc.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,13 @@ function getStats($ch, $type = "counters")
// post curl
return postCurl($ch, $data);
}

// get confirmation history from nano_node
function getConfirmationHistory($ch)
{
// get confirmation history of latest 2048 elections
$data = array("action" => "confirmation_history");

// post curl
return postCurl($ch, $data);
}

0 comments on commit 868e432

Please sign in to comment.