お茶漬けぶろぐ

php-mposのPROP計算を追いかける

初のAdvent Calendar参加です。1日遅れですが、暗号通貨Advent Calendar 5日目に登録しました。

お茶漬けと申します。普段は都内で学生やってます。研究進まない。

昨日4日目は@zinntikumugai氏の仮想通貨を変換した時の金額を求めるTwitterBOT作ったお話でした。JPYやBTCを挟まずに、目的の通貨へのレートを一発で教えてもらえるTwitterBOTだそうです。中間に基準通貨のようなものを挟まずともレートを教えてくれるというのは、便利で良さそうです。新たに対応通貨を増やす等、精力的に活動しているようで、今後が楽しみですね。

さて、プールマイニングを行った場合に、報酬はShareの比率に従って分配されるとかなんとか言いますが、その比率とは何を元に算出されるのか、きちんと考えたことが無かったので、具体的に理解する事が目標です。報酬の分配方式としては、代表的なものにPPLNSがあると思いますが、ここではPROPのみに絞ります(単純に私の技量と気力が足りなかったので)。また、実装を見させてもらうのは、MPOS/php-mposです。

基本的にはgithubのソースを眺めて追いかけていきますが、随時データベースの中身も利用します(採掘経験のある、mposデータベースが手元にあるので)。

ちなみに私は、きちんとPHPを触ったことがない上に、人のコードを読む経験が非常に少ないので、かなり手探りになります。ご了承ください。また、間違い等あったらご指摘頂けると大変嬉しく思います。

TL;DR

比率の計算は各ユーザの提出したShare達のDifficultyの総和を元に行う。おしまい。

以下はphp初心者が手探りで読んでいった痕跡です。

眺める起点

[bash]
~略~

List of cruns to execute

CRONS=”findblock.php proportional_payout.php pplns_payout.php pps_payout.php blockupdate.php payouts.php tickerupdate.php notifications.php statistics.php tables_cleanup.php”
~略~
for cron in $CRONS; do
[[ $VERBOSE == 1 ]] && echo “Running $cron, check logfile for details”
$PHP_BIN $cron $PHP_OPTS
done
[/bash]

proportional_payout.phpを読んでみる

[php]
// Add new credit transaction
if (!$transaction->addTransaction($aData[‘id’], $aData[‘payout’], ‘Credit’, $aBlock[‘id’]))
$log->logFatal(‘Failed to insert new Credit transaction to database for ‘ . $aData[‘username’] . ‘: ‘ . $transaction->getCronError());
[/php]

[php]
$aData[‘percentage’] = ( 100 / $iRoundShares ) * $aData[‘valid’];
$aData[‘payout’] = ( $aData[‘percentage’] / 100 ) * $dReward;
[/php]

$dRewardの記述を探す

[php]
$config[‘reward_type’] == ‘block’ ? $dReward = $aBlock[‘amount’] : $dReward = $config[‘reward’];
[/php]

普通のifで書き直したのはこちら

[php]
if(config[‘reward_type’] == ‘block’){
$dReward = $aBlock[‘amount’]
}else{
$dReward = $config[‘reward’];
}
[/php]

block->getAllUnaccounted()を読む

addBlock()が呼ばれているところを探してみる

結局$dRewardは何が入るか

一旦休憩、まとめ……

[php]
$aData[‘percentage’] = ( 100 / $iRoundShares ) * $aData[‘valid’]
$aData[‘payout’] = ( $aData[‘percentage’] / 100 ) * $dReward
[/php]

$aData['valid']には何が入っている?

[sql]
SELECT
a.id,
SUBSTRING_INDEX( s.username , ‘.’, 1 ) as username,
a.no_fees AS no_fees,
IFNULL(SUM(IF(our_result=’Y’, IF(s.difficulty=0, POW(2, (“ . $this->config[‘difficulty’] . “ - 16)), s.difficulty), 0)), 0) AS valid,
IFNULL(SUM(IF(our_result=’N’, IF(s.difficulty=0, POW(2, (“ . $this->config[‘difficulty’] . “ - 16)), s.difficulty), 0)), 0) AS invalid
FROM $this->table AS s
LEFT JOIN “ . $this->user->getTableName() . “ AS a
ON a.username = SUBSTRING_INDEX( s.username , ‘.’, 1 )
WHERE s.id > ? AND s.id <= ? AND a.is_locked != 2
GROUP BY username DESC
[/sql]

[sql]
FROM shares AS s
LEFT JOIN accounts AS a
ON a.username = SUBSTRING_INDEX( s.username, ‘.’, 1 )
[/sql]

[sql]
IFNULL(
 SUM(
  IF(
   our_result=’Y’,
   IF(
    s.difficulty=0,
    POW(2, (“ . $this->config[‘difficulty’] . “ - 16)),
    s.difficulty
   ),
   0
  )
 ),
 0
)
AS valid
[/sql]

$iRoundSharesには何が入っている?

不明だった変数をまとめると

これらを踏まえて最初の式を見ると

[php]
$aData[‘percentage’] = ( 100 / $iRoundShares ) * $aData[‘valid’]
$aData[‘payout’] = ( $aData[‘percentage’] / 100 ) * $dReward
[/php]

[php]
$aData[‘payout’] = ( $aData[‘valid’] / $iRoundShares ) * $dReward
[/php]

< GPD WINとArchLinuxInstallBattle

AndroidStudioいじってたらjava.lang.IllegalStateException aapt2 is missingとか言われた >