Development Log for arikado gridcoin pool

in #utopian-io6 years ago

Repository

https://github.com/sau412/arikado_gridcoin_pool

Introduction

New version: added redirect failover, more information about SQL errors in logs, magnitude information.

Details

Redirect failover

Pool site uses redirects when performing actions. Redirect requires HTTP header 'Location'. But headers cannot be sent when page text is sent or warnings appear. So it fixed with redirect function, which also checks is headers sent. If they are send, special message added to log:

// Redirect and die
function html_redirect_and_die($url) {
        $file="";
        $line=0;
        if(headers_sent($file,$line)) {
                auth_log("Redirect warning: headers already sent, file '$file', line '$line'");
                echo "<br>Auto redirect failed, please <a href='$url'>click here</a>";
        } else {
                header("Location: $url");
        }
        die();
}

Github commit function: https://github.com/sau412/arikado_gridcoin_pool/commit/b100ef22d615c715dd407f2f2bc7adc6d0b79853
Github commit usage: https://github.com/sau412/arikado_gridcoin_pool/commit/e9dff39fe0de3379419e9b61153ef119bfdbb2e5

It is not seen by users, so no screenshots.

Magnitude

Magnitude shows user relative contribution. It is used for calculating rewards and for ratings. So it appear multiple times here and there. So I created functions to boincmgr.php receive information from single place:

// Get magnitude per project
function boincmgr_get_mag_per_project() {
        $magnitude_total=115000;
        $whiltelisted_count=db_query_to_variable("SELECT count(*) FROM `boincmgr_projects` WHERE `status` IN ('enabled','auto enabled','stats only')");
        if($whiltelisted_count!=0) $mag_per_project=$magnitude_total/$whiltelisted_count;
        else $mag_per_project=0;
        return $mag_per_project;
}

// Get magnitude unit
function boincmgr_get_magnitude_unit() {
        return boincmgr_get_variable("magnitude_unit");
}

// Get project host relative contribution
function boincmgr_get_relative_contribution_project_host($project_uid,$host_uid) {
        $project_uid_escaped=db_escape($project_uid);
        $host_uid_escaped=db_escape($host_uid);
        $relative_contribution=db_query_to_variable("SELECT SUM(bphl.`expavg_credit`/bp.`team_expavg_credit`) FROM `boincmgr_project_hosts_last` AS bphl
LEFT OUTER JOIN `boincmgr_projects` AS bp ON bp.uid=bphl.project_uid
WHERE bphl.`project_uid`='$project_uid_escaped' AND bphl.`host_uid`='$host_uid_escaped' AND bp.`status` IN ('enabled','auto enabled','stats only')");
        if($relative_contribution=="") $relative_contribution=0;
        return $relative_contribution;
}

// Get project user relative contribution
function boincmgr_get_relative_contribution_project_user($project_uid,$user_uid) {
        $project_uid_escaped=db_escape($project_uid);
        $user_uid_escaped=db_escape($user_uid);
        $relative_contribution=db_query_to_variable("SELECT SUM(bphl.`expavg_credit`/bp.`team_expavg_credit`) FROM `boincmgr_project_hosts_last` AS bphl
LEFT OUTER JOIN `boincmgr_projects` AS bp ON bp.uid=bphl.project_uid
LEFT OUTER JOIN `boincmgr_hosts` AS bh ON bh.uid=bphl.host_uid
WHERE bphl.`project_uid`='$project_uid_escaped' AND bh.`username_uid`='$user_uid_escaped' AND bp.`status` IN ('enabled','auto enabled','stats only')");
        if($relative_contribution=="") $relative_contribution=0;
        return $relative_contribution;
}

// Get project relative contribution
function boincmgr_get_relative_contribution_project($project_uid) {
        $project_uid_escaped=db_escape($project_uid);
        $relative_contribution=db_query_to_variable("SELECT SUM(bp.`expavg_credit`/bp.`team_expavg_credit`) FROM `boincmgr_projects` AS bp
WHERE bp.`uid`='$project_uid_escaped' AND bp.`status` IN ('enabled','auto enabled','stats only')");
        if($relative_contribution=="") $relative_contribution=0;
        return $relative_contribution;
}

// Get host relative contribution
function boincmgr_get_relative_contribution_host($host_uid) {
        $host_uid_escaped=db_escape($host_uid);
        $relative_contribution=db_query_to_variable("SELECT SUM(bphl.`expavg_credit`/bp.`team_expavg_credit`) FROM `boincmgr_project_hosts_last` AS bphl
LEFT OUTER JOIN `boincmgr_projects` AS bp ON bp.uid=bphl.project_uid
WHERE bphl.`host_uid`='$host_uid_escaped' AND bp.`status` IN ('enabled','auto enabled','stats only')");
        if($relative_contribution=="") $relative_contribution=0;
        return $relative_contribution;
}

// Get user relative contribution
function boincmgr_get_relative_contribution_user($user_uid) {
        $user_uid_escaped=db_escape($user_uid);
        $relative_contribution=db_query_to_variable("SELECT SUM(bphl.`expavg_credit`/bp.`team_expavg_credit`) FROM `boincmgr_project_hosts_last` AS bphl
LEFT OUTER JOIN `boincmgr_projects` AS bp ON bp.uid=bphl.project_uid
LEFT OUTER JOIN `boincmgr_hosts` AS bh ON bh.uid=bphl.host_uid
WHERE bh.`username_uid`='$user_uid_escaped' AND bp.`status` IN ('enabled','auto enabled','stats only')");
        if($relative_contribution=="") $relative_contribution=0;
        return $relative_contribution;
}

Functions look similar, but have different groupings. Also function boincmgr_get_relative_contribution_project using different tables. So distinct functions is better than one big function with multiple arguments.

Github commit functions: https://github.com/sau412/arikado_gridcoin_pool/commit/20ca4216ba0bbb5eb94d62359902bfd38d66f67b

Now I can use:

$mag_per_project=boincmgr_get_mag_per_project();
$magnitude_unit=boincmgr_get_magnitude_unit();
<...>
$host_relative_contribution=boincmgr_get_relative_contribution_project_host($project_uid,$host_uid);
$mag_formatted=sprintf("%0.2f",$mag_per_project*$host_relative_contribution);

instead of multiple implementations of

// GRC per last day
$total_grc_per_day=db_query_to_variable("SELECT SUM(`mint`-`interest`) FROM `boincmgr_blocks` WHERE cpid<>'INVESTOR' AND date_sub(NOW(), INTERVAL 1 DAY)<`timestamp`");
<...>
// Whitelisted projects count
$whiltelisted_count=db_query_to_variable("SELECT count(*) FROM `boincmgr_projects` WHERE `status` IN ('enabled','auto enabled','stats only')");
if($whiltelisted_count>0) $grc_per_day_est=($total_grc_per_day/$whiltelisted_count)*($relative_credit);
else $grc_per_day_est=0;
$grc_per_day_est=round($grc_per_day_est,4);

Github commit usage: https://github.com/sau412/arikado_gridcoin_pool/commit/b100ef22d615c715dd407f2f2bc7adc6d0b79853

Interface screenshots (one of the ratings):

URL: https://grc.arikado.ru/#rating_by_user_mag

Also I can add magnitude information to other places, like host settings (visible after green fields 'synced, checked'):

Stack trace to log

Using that part of db_query function I can see stack trace in the log when SQL error received:

$debug_backtrace_array=debug_backtrace();
$backtrace_string="Stack trace:\n";
foreach($debug_backtrace_array as $stack_info) {
        $file=$stack_info['file'];
        $line=$stack_info['line'];
        $func=$stack_info['function'];
        $args=implode("','",$stack_info['args']);
        $backtrace_string.="File '$file' line '$line' function '$func' arguments '$args'\n";
}
auth_log($backtrace_string);

Github commit: https://github.com/sau412/arikado_gridcoin_pool/commit/3b8da9f09eeeddd714451b191872ec473840abfc

This is how it looks in administrative interface:

Don't worry about cookie key, it exists only in development server.

Summary

All these changes included in version v1.1 of the pool

Resources

Working implementation of the pool: https://gridcoinpool.ru/
Rating view: https://grc.arikado.ru/#rating_by_user_mag
Release of v1.1: https://github.com/sau412/arikado_gridcoin_pool/tree/v1.1

Sort:  

This post contains the information it is meant to convey, and has the relevant graphical illustrations. However, I have some tips and suggestions on improving future posts.

I would have liked to have seen more detail, and especially explanation. The post includes almost no information on what the project actually is, and I would strongly recommend starting with that.

The post could be better written, and could have used a proofreading. I would recommend putting the text - minus the code, of course - in Hemingway to get help with style and grammar. For folks who want to get the information, it is important that the post be easy to read and understand.

I would also recommend adding links to past posts explaining in greater detail what the project is about. I know those are available further down in your blog, but why not make it easier for users to find? Again, making things easier for users is highly important, especially in a post as technical as this one.

I look forward to seeing future posts from you.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Should I edit this post or just include required information in next post?

An edit could be useful for readers, and I would applaud it. However, for Utopian purposes, the post has been scored. I would definitely incorporate the recommendations in future posts.

Thank you for your review, @didic!

So far this week you've reviewed 24 contributions. Keep up the good work!

Hey @sau412
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!