From d44c236f2ba0a70183d8db912312597498b5c4ca Mon Sep 17 00:00:00 2001 From: Sebastian Grewe Date: Mon, 27 May 2013 14:44:40 +0200 Subject: [PATCH] Adding support for orphan blocks * Adjusted blockupdate cronjob * Fetch block information via `gettransaction` * Adjusted block class * Only getAllUnconfirmed where confirmations > -1 * Adjusted transaction class * added setOrphan method to mark orphaned transactions * If block is orphaned * Mark all related transactions as Orphan_*type* * Set confirmations of block to -1 so it is ignored and marked as orphan * Change transaction template, added listing for orphan transactions * Add orphan status to block listings template --- cronjobs/blockupdate.php | 11 +++++ public/include/classes/block.class.php | 2 +- public/include/classes/transaction.class.php | 35 ++++++++++++++ .../mmcFE/account/transactions/default.tpl | 46 ++++++++++++++++++- .../mmcFE/statistics/blocks/blocks_found.tpl | 7 ++- 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/cronjobs/blockupdate.php b/cronjobs/blockupdate.php index 877471a8..1f74e68c 100755 --- a/cronjobs/blockupdate.php +++ b/cronjobs/blockupdate.php @@ -33,7 +33,18 @@ $aAllBlocks = $block->getAllUnconfirmed($config['confirmations']); verbose("ID\tBlockhash\tConfirmations\t\n"); foreach ($aAllBlocks as $iIndex => $aBlock) { $aBlockInfo = $bitcoin->query('getblock', $aBlock['blockhash']); + // Fetch this blocks transaction details to find orphan blocks + $aTxDetails = $bitcoin->query('gettransaction', $aBlockInfo['merkleroot']); verbose($aBlock['id'] . "\t" . $aBlock['blockhash'] . "\t" . $aBlock['confirmations'] . " -> " . $aBlockInfo['confirmations'] . "\t"); + if ($aTxDetails['details'][0]['category'] == 'orphan') { + // We have an orphaned block, we need to invalidate all transactions for this one + if ($transaction->setOrphan($aBlock['id']) && $block->setConfirmations($aBlock['id'], -1)) { + verbose("ORPHAN\n"); + } else { + verbose("ORPHAN_ERR"); + } + continue; + } if ($aBlock['confirmations'] == $aBlockInfo['confirmations']) { verbose("SKIPPED\n"); } else if ($block->setConfirmations($aBlock['id'], $aBlockInfo['confirmations'])) { diff --git a/public/include/classes/block.class.php b/public/include/classes/block.class.php index e4c3f7e2..cd5e0456 100644 --- a/public/include/classes/block.class.php +++ b/public/include/classes/block.class.php @@ -50,7 +50,7 @@ class Block { } public function getAllUnconfirmed($confirmations='120') { - $stmt = $this->mysqli->prepare("SELECT id, blockhash, confirmations FROM $this->table WHERE confirmations < ?"); + $stmt = $this->mysqli->prepare("SELECT id, blockhash, confirmations FROM $this->table WHERE confirmations < ? AND confirmations > -1"); if ($this->checkStmt($stmt)) { $stmt->bind_param("i", $confirmations); $stmt->execute(); diff --git a/public/include/classes/transaction.class.php b/public/include/classes/transaction.class.php index ee4bbc21..207081bd 100644 --- a/public/include/classes/transaction.class.php +++ b/public/include/classes/transaction.class.php @@ -38,6 +38,41 @@ class Transaction { return false; } + public function setOrphan($block_id) { + $this->debug->append("STA " . __METHOD__, 4); + $stmt = $this->mysqli->prepare(" + UPDATE $this->table + SET type = 'Orphan_Credit' + WHERE type = 'Credit' + AND block_id = ? + "); + if (!($this->checkStmt($stmt) && $stmt->bind_param('i', $block_id) && $stmt->execute())) { + $this->debug->append("Failed to set orphan credit transactions for $block_id"); + return false; + } + $stmt = $this->mysqli->prepare(" + UPDATE $this->table + SET type = 'Orphan_Fee' + WHERE type = 'Fee' + AND block_id = ? + "); + if (!($this->checkStmt($stmt) && $stmt->bind_param('i', $block_id) && $stmt->execute())) { + $this->debug->append("Failed to set orphan fee transactions for $block_id"); + return false; + } + $stmt = $this->mysqli->prepare(" + UPDATE $this->table + SET type = 'Orphan_Donation' + WHERE type = 'Donation' + AND block_id = ? + "); + if (!($this->checkStmt($stmt) && $stmt->bind_param('i', $block_id) && $stmt->execute())) { + $this->debug->append("Failed to set orphan donation transactions for $block_id"); + return false; + } + return true; + } + public function getTransactions($account_id, $start=0) { $this->debug->append("STA " . __METHOD__, 4); $stmt = $this->mysqli->prepare(" diff --git a/public/templates/mmcFE/account/transactions/default.tpl b/public/templates/mmcFE/account/transactions/default.tpl index 35ec2cc4..ed523e54 100644 --- a/public/templates/mmcFE/account/transactions/default.tpl +++ b/public/templates/mmcFE/account/transactions/default.tpl @@ -1,4 +1,4 @@ -{include file="global/block_header.tpl" BLOCK_HEADER="Transaction Log" BUTTONS=array(Confirmed,Unconfirmed)} +{include file="global/block_header.tpl" BLOCK_HEADER="Transaction Log" BUTTONS=array(Confirmed,Unconfirmed,Orphan)}
@@ -84,4 +84,48 @@

Listed are your estimated rewards and donations/fees for all blocks awaiting {$GLOBAL.confirmations} confirmations.

+
+
+
+ + + + + + + + + + + +{section transaction $TRANSACTIONS} + {if ( + $TRANSACTIONS[transaction].type == 'Orphan_Credit' + or $TRANSACTIONS[transaction].type == 'Orphan_Donation' + or $TRANSACTIONS[transaction].type == 'Orphan_Fee' + )} + + + + + + + + + {if $TRANSACTIONS[transaction].type == Orphan_Credit} + {assign var="orphan_credits" value="`$orphan_credits+$TRANSACTIONS[transaction].amount`"} + {else} + {assign var="orphan_debits" value="`$orphan_debits+$TRANSACTIONS[transaction].amount`"} + {/if} + {/if} +{/section} + + + + + +
TX #DateTX TypePayment AddressBlock #Amount
{$TRANSACTIONS[transaction].id}{$TRANSACTIONS[transaction].timestamp}{$TRANSACTIONS[transaction].type}{$TRANSACTIONS[transaction].coin_address}{if $TRANSACTIONS[transaction].height == 0}n/a{else}{$TRANSACTIONS[transaction].height}{/if}{$TRANSACTIONS[transaction].amount}
Orphaned Totals:{$orphan_credits - $orphan_debits}
+

Listed are your orphaned transactions for blocks not part of the main blockchain.

+
+
{include file="global/block_footer.tpl"} diff --git a/public/templates/mmcFE/statistics/blocks/blocks_found.tpl b/public/templates/mmcFE/statistics/blocks/blocks_found.tpl index 6751ad64..db1d79ab 100644 --- a/public/templates/mmcFE/statistics/blocks/blocks_found.tpl +++ b/public/templates/mmcFE/statistics/blocks/blocks_found.tpl @@ -16,7 +16,12 @@ {section block $BLOCKSFOUND} {$BLOCKSFOUND[block].height} - {if $BLOCKSFOUND[block].confirmations >= $GLOBAL.confirmations}Confirmed{else}{$GLOBAL.confirmations - $BLOCKSFOUND[block].confirmations} left{/if} + + {if $BLOCKSFOUND[block].confirmations >= $GLOBAL.confirmations} + Confirmed + {else if $BLOCKSFOUND[block].confirmations == -1} + Orphan + {else}{$GLOBAL.confirmations - $BLOCKSFOUND[block].confirmations} left{/if} {$BLOCKSFOUND[block].finder|default:"unknown"} {$BLOCKSFOUND[block].time|date_format:"%d/%m/%Y %H:%M:%S"} {$BLOCKSFOUND[block].difficulty|number_format:"8"}