]> git.mxchange.org Git - hub.git/blobdiff - application/hub/main/package/class_NetworkPackage.php
Some noisy debug lines commented out.
[hub.git] / application / hub / main / package / class_NetworkPackage.php
index a325f471a2320f999c8679730979ce5f0af9aabc..20af55662d19849f65dc73066efeeddb4ba76b42 100644 (file)
@@ -17,7 +17,7 @@
  *
  * @author             Roland Haeder <webmaster@shipsimu.org>
  * @version            0.0.0
- * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2014 Hub Developer Team
+ * @copyright  Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Hub Developer Team
  * @license            GNU GPL 3.0 or any newer version
  * @link               http://www.shipsimu.org
  * @todo               Needs to add functionality for handling the object's type
@@ -73,34 +73,38 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        /**
         * Array indexes for raw package array
         */
-       const INDEX_PACKAGE_SENDER    = 0;
-       const INDEX_PACKAGE_RECIPIENT = 1;
-       const INDEX_PACKAGE_CONTENT   = 2;
-       const INDEX_PACKAGE_STATUS    = 3;
-       const INDEX_PACKAGE_SIGNATURE = 4;
+       const INDEX_PACKAGE_SENDER           = 0;
+       const INDEX_PACKAGE_RECIPIENT        = 1;
+       const INDEX_PACKAGE_CONTENT          = 2;
+       const INDEX_PACKAGE_STATUS           = 3;
+       const INDEX_PACKAGE_HASH             = 4;
+       const INDEX_PACKAGE_PRIVATE_KEY_HASH = 5;
 
        /**
-        * Size of the decoded data array ('status' is not included)
+        * Size of the decoded data array
         */
-       const DECODED_DATA_ARRAY_SIZE = 4;
+       const DECODED_DATA_ARRAY_SIZE = 6;
 
        /**
         * Named array elements for decoded package content
         */
-       const PACKAGE_CONTENT_EXTENSION = 'compressor';
-       const PACKAGE_CONTENT_MESSAGE   = 'message';
-       const PACKAGE_CONTENT_TAGS      = 'tags';
-       const PACKAGE_CONTENT_CHECKSUM  = 'checksum';
+       const PACKAGE_CONTENT_EXTENSION        = 'compressor';
+       const PACKAGE_CONTENT_MESSAGE          = 'message';
+       const PACKAGE_CONTENT_TAGS             = 'tags';
+       const PACKAGE_CONTENT_CHECKSUM         = 'checksum';
+       const PACKAGE_CONTENT_SENDER           = 'sender';
+       const PACKAGE_CONTENT_HASH             = 'hash';
+       const PACKAGE_CONTENT_PRIVATE_KEY_HASH = 'pkhash';
 
        /**
         * Named array elements for package data
         */
-       const PACKAGE_DATA_SENDER    = 'sender';
-       const PACKAGE_DATA_RECIPIENT = 'recipient';
-       const PACKAGE_DATA_PROTOCOL  = 'protocol';
-       const PACKAGE_DATA_CONTENT   = 'content';
-       const PACKAGE_DATA_STATUS    = 'status';
-       const PACKAGE_DATA_SIGNATURE = 'signature';
+       const PACKAGE_DATA_SENDER           = 'sender';
+       const PACKAGE_DATA_RECIPIENT        = 'recipient';
+       const PACKAGE_DATA_CONTENT          = 'content';
+       const PACKAGE_DATA_STATUS           = 'status';
+       const PACKAGE_DATA_HASH             = 'hash';
+       const PACKAGE_DATA_PRIVATE_KEY_HASH = 'pkhash';
 
        /**
         * All package status
@@ -113,8 +117,11 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        /**
         * Constants for message data array
         */
-       const MESSAGE_ARRAY_DATA = 'message_data';
-       const MESSAGE_ARRAY_TYPE = 'message_type';
+       const MESSAGE_ARRAY_DATA   = 'message_data';
+       const MESSAGE_ARRAY_TYPE   = 'message_type';
+       const MESSAGE_ARRAY_SENDER = 'message_sender';
+       const MESSAGE_ARRAY_HASH   = 'message_hash';
+       const MESSAGE_ARRAY_TAGS   = 'message_tags';
 
        /**
         * Generic answer status field
@@ -289,7 +296,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $packageInstance->initStacks();
 
                // Get a visitor instance for speeding up things and set it
-               $visitorInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_monitor_visitor_class', array($packageInstance));
+               $visitorInstance = ObjectFactory::createObjectByConfiguredName('node_raw_data_monitor_visitor_class');
                $packageInstance->setVisitorInstance($visitorInstance);
 
                // Get crypto instance and set it, too
@@ -300,6 +307,15 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $assemblerInstance = PackageAssemblerFactory::createAssemblerInstance($packageInstance);
                $packageInstance->setAssemblerInstance($assemblerInstance);
 
+               // Get node instance
+               $nodeInstance = NodeObjectFactory::createNodeInstance();
+
+               // Get pool instance from node
+               $poolInstance = $nodeInstance->getListenerPoolInstance();
+
+               // And set it here
+               $packageInstance->setListenerPoolInstance($poolInstance);
+
                // Return the prepared instance
                return $packageInstance;
        }
@@ -325,6 +341,37 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                ), $forceReInit);
        }
 
+       /**
+        * Determines private key hash from given session id
+        *
+        * @param       $decodedData    Array with decoded data
+        * @return      $hash                   Private key's hash
+        */
+       private function determineSenderPrivateKeyHash (array $decodedData) {
+               // Get DHT instance
+               $dhtInstance = DhtObjectFactory::createDhtInstance('node');
+
+               // Ask DHT for session id
+               $senderData = $dhtInstance->findNodeLocalBySessionId($decodedData[self::PACKAGE_CONTENT_SENDER]);
+
+               // Is an entry found?
+               if (count($senderData) > 0) {
+                       // Make sure the element 'private_key_hash' is there
+                       /* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: senderData=' . print_r($senderData, TRUE));
+                       assert(isset($senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH]));
+
+                       // Return it
+                       return $senderData[NodeDistributedHashTableDatabaseWrapper::DB_COLUMN_PRIVATE_KEY_HASH];
+               } // END - if
+
+               // Make sure the requested element is there
+               //* DEBUG-DIE */ die('decodedData=' . print_r($decodedData, TRUE));
+               assert(isset($decodedData[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH]));
+
+               // There is no DHT entry so, accept the hash from decoded data
+               return $decodedData[self::PACKAGE_CONTENT_PRIVATE_KEY_HASH];
+       }
+
        /**
         * "Getter" for hash from given content
         *
@@ -388,8 +435,8 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // Pop the entry (it should be it)
                $nextData = $this->getStackInstance()->popNamed($stackerName);
 
-               // Compare both signatures
-               assert($nextData[self::PACKAGE_DATA_SIGNATURE] == $packageData[self::PACKAGE_DATA_SIGNATURE]);
+               // Compare both hashes
+               assert($nextData[self::PACKAGE_DATA_HASH] == $packageData[self::PACKAGE_DATA_HASH]);
 
                // Temporary set the new status
                $packageData[self::PACKAGE_DATA_STATUS] = $newStatus;
@@ -451,6 +498,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // Now get an iterator
                $iteratorInstance = $discoveryInstance->getIterator();
 
+               // Make sure the iterator instance is valid
+               assert($iteratorInstance instanceof Iterator);
+
                // Rewind back to the beginning
                $iteratorInstance->rewind();
 
@@ -460,7 +510,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        $currentRecipient = $iteratorInstance->current();
 
                        // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Setting recipient to ' . $currentRecipient . ',previous=' . $packageData[self::PACKAGE_DATA_RECIPIENT]);
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Setting recipient to ' . $currentRecipient . ',previous=' . $packageData[self::PACKAGE_DATA_RECIPIENT]);
 
                        // Set the recipient
                        $packageData[self::PACKAGE_DATA_RECIPIENT] = $currentRecipient;
@@ -469,7 +519,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        $this->getStackInstance()->pushNamed(self::STACKER_NAME_DECLARED, $packageData);
 
                        // Debug message
-                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Package declared for recipient ' . $currentRecipient);
+                       /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Package declared for recipient ' . $currentRecipient);
 
                        // Skip to next entry
                        $iteratorInstance->next();
@@ -526,13 +576,19 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // And make sure it is valid
                assert($helperInstance instanceof ConnectionHelper);
 
+               // Get connection info class
+               $infoInstance = ConnectionInfoFactory::createConnectionInfoInstance($helperInstance->getProtocolName(), 'helper');
+
+               // Will the info instance with connection helper data
+               $infoInstance->fillWithConnectionHelperInformation($helperInstance);
+
                // Is it not there?
-               if ((is_resource($socketResource)) && (!$registryInstance->isSocketRegistered($helperInstance, $socketResource))) {
+               if ((is_resource($socketResource)) && (!$registryInstance->isSocketRegistered($infoInstance, $socketResource))) {
                        // Debug message
                        //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Registering socket ' . $socketResource . ' ...');
 
                        // Then register it
-                       $registryInstance->registerSocket($helperInstance, $socketResource, $packageData);
+                       $registryInstance->registerSocket($infoInstance, $socketResource, $packageData);
                } elseif (!$helperInstance->getStateInstance()->isPeerStateConnected()) {
                        // Is not connected, then we cannot send
                        self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Unexpected peer state ' . $helperInstance->getStateInstance()->__toString() . ' detected.');
@@ -568,7 +624,18 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $sentBytes = 0;
 
                // Get the right connection instance
-               $helperInstance = SocketRegistryFactory::createSocketRegistryInstance()->getHandlerInstanceFromPackageData($packageData);
+               $infoInstance = SocketRegistryFactory::createSocketRegistryInstance()->getInfoInstanceFromPackageData($packageData);
+
+               // Test helper instance
+               assert($infoInstance instanceof ShareableInfo);
+
+               // Get helper instance
+               $helperInstance = $infoInstance->getHelperInstance();
+
+               // Some sanity-checks on the object
+               //* DEBUG-DIE: */ die('[' . __METHOD__ . ':' . __LINE__ . ']: p1=' . $infoInstance->getProtocolName() . ',p2=' . $helperInstance->getProtocolName() . ',infoInstance=' . print_r($infoInstance, TRUE));
+               assert($helperInstance instanceof ConnectionHelper);
+               assert($infoInstance->getProtocolName() == $helperInstance->getProtocolName());
 
                // Is this connection still alive?
                if ($helperInstance->isShuttedDown()) {
@@ -582,41 +649,73 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        }
 
        /**
-        * Generates a signature for given raw package content and sender id
+        * Generates a secure hash for given raw package content and sender id
         *
         * @param       $content        Raw package data
-        * @param       $senderId       Sender id to generate a signature for
-        * @return      $signature      Signature as BASE64-encoded string
+        * @param       $senderId       Sender id to generate a hash for
+        * @return      $hash           Hash as hex-encoded string
         */
-       private function generatePackageSignature ($content, $senderId) {
-               // Hash content and sender id together, use md5() as last algo
-               $hash = md5($this->getCryptoInstance()->hashString($senderId . $content, $this->getPrivateKey(), FALSE));
+       private function generatePackageHash ($content, $senderId) {
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: content()=' . strlen($content) . ',senderId=' . $senderId . ' - CALLED!');
 
-               // Encrypt the content again with the hash as a key
-               $encryptedContent = $this->getCryptoInstance()->encryptString($content, $hash);
+               // Is the feature enabled?
+               if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+                       // Feature is not enabled
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Feature "hubcoin_reward" not available, not generating package hash. Returning NULL ...');
+                       return NULL;
+               } // END - if
+
+               // Fake array
+               $data = array(
+                       self::PACKAGE_CONTENT_SENDER           => $senderId,
+                       self::PACKAGE_CONTENT_MESSAGE          => $content,
+                       self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => ''
+               );
+       
+               // Hash content and sender id together, use scrypt
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: senderId=' . $senderId . ',content()=' . strlen($content));
+               $hash = FrameworkFeature::callFeature('hubcoin_reward', 'generateHash', array($senderId . ':' . $content . ':' . $this->determineSenderPrivateKeyHash($data)));
 
-               // Encode it with BASE64
-               $signature = base64_encode($encryptedContent);
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: hash=' . $hash . ' - EXIT!');
 
                // Return it
-               return $signature;
+               return $hash;
        }
 
        /**
-        * Checks whether the signature of given package data is 'valid', here that
+        * Checks whether the hash of given package data is 'valid', here that
         * means it is the same or not.
         *
         * @param       $decodedArray           An array with 'decoded' (explode() was mostly called) data
-        * @return      $isSignatureValid       Whether the signature is valid
-        * @todo        Unfinished area, signatures are currently NOT fully supported
+        * @return      $isHashValid    Whether the hash is valid
+        * @todo        Unfinished area, hashes are currently NOT fully supported
         */
-       private function isPackageSignatureValid (array $decodedArray) {
-               // Generate the signature of comparing it
-               $signature = $this->generatePackageSignature($decodedArray[self::INDEX_PACKAGE_CONTENT], $decodedArray[self::INDEX_PACKAGE_SENDER]);
+       private function isPackageHashValid (array $decodedArray) {
+               // Debug message
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: decodedArray=' . print_r($decodedArray, TRUE) . ' - CALLED!');
+
+               // Make sure the required array elements are there
+               assert(isset($decodedArray[self::PACKAGE_CONTENT_SENDER]));
+               assert(isset($decodedArray[self::PACKAGE_CONTENT_MESSAGE]));
+               assert(isset($decodedArray[self::PACKAGE_CONTENT_HASH]));
+
+               // Is the feature enabled?
+               if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+                       // Feature is not enabled, so hashes are always valid
+                       //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: Feature "hubcoin_reward" not available, not checking hash. Returning TRUE ...');
+                       return TRUE;
+               } // END - if
 
-               // Is it the same?
-               //$isSignatureValid = 
-               exit(__METHOD__.': signature='.$signature.chr(10).',decodedArray='.print_r($decodedArray, TRUE));
+               // Check validity
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: senderId=' . $decodedArray[self::PACKAGE_CONTENT_SENDER] . ',message()=' . strlen($decodedArray[self::PACKAGE_CONTENT_MESSAGE]) . '),hash=' . $decodedArray[self::PACKAGE_CONTENT_HASH]);
+               //* DEBUG-DIE: */ die(__METHOD__ . ': decodedArray=' . print_r($decodedArray, TRUE));
+               $isHashValid = FrameworkFeature::callFeature('hubcoin_reward', 'checkHash', array($decodedArray[self::PACKAGE_CONTENT_SENDER] . ':' . $decodedArray[self::PACKAGE_CONTENT_MESSAGE] . ':' . $this->determineSenderPrivateKeyHash($decodedArray), $decodedArray[self::PACKAGE_CONTENT_HASH]));
+
+               // Return it
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: isHashValid=' . intval($isHashValid) . ' - EXIT!');
+               return $isHashValid;
        }
 
        /**
@@ -628,15 +727,15 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @return      void
         */
        public function enqueueRawDataFromTemplate (HubHelper $helperInstance) {
-               // Get protocol instance for recipient
-               $protocolInstance = ProtocolHandlerFactory::createProtocolFromRecipientHelper($helperInstance);
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': CALLED!');
 
                // Get the raw content ...
                $content = $helperInstance->getTemplateInstance()->getRawTemplateData();
                //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('content(' . strlen($content) . ')=' . $content);
 
                // ... and compress it
-               $content = $this->getCompressorInstance()->compressStream($content);
+               $compressed = $this->getCompressorInstance()->compressStream($content);
 
                // Add magic in front of it and hash behind it, including BASE64 encoding
                $packageContent = sprintf(self::PACKAGE_MASK,
@@ -644,8 +743,8 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        $this->getCompressorInstance()->getCompressorExtension(),
                        // - separator
                        self::PACKAGE_MASK_SEPARATOR,
-                       // 2.) Raw package content, encoded with BASE64
-                       base64_encode($content),
+                       // 2.) Compressed raw package content, encoded with BASE64
+                       base64_encode($compressed),
                        // - separator
                        self::PACKAGE_MASK_SEPARATOR,
                        // 3.) Tags
@@ -653,18 +752,24 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        // - separator
                        self::PACKAGE_MASK_SEPARATOR,
                        // 4.) Checksum
-                       $this->getHashFromContent($content)
+                       $this->getHashFromContent($compressed)
                );
 
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': Enqueueing package for recipientType=' . $helperInstance->getRecipientType() . ' ...');
+
                // Now prepare the temporary array and push it on the 'undeclared' stack
                $this->getStackInstance()->pushNamed(self::STACKER_NAME_UNDECLARED, array(
-                       self::PACKAGE_DATA_SENDER    => $this->getSessionId(),
-                       self::PACKAGE_DATA_RECIPIENT => $helperInstance->getRecipientType(),
-                       self::PACKAGE_DATA_PROTOCOL  => $protocolInstance->getProtocolName(),
-                       self::PACKAGE_DATA_CONTENT   => $packageContent,
-                       self::PACKAGE_DATA_STATUS    => self::PACKAGE_STATUS_NEW,
-                       self::PACKAGE_DATA_SIGNATURE => $this->generatePackageSignature($packageContent, $this->getSessionId())
+                       self::PACKAGE_DATA_SENDER           => $this->getSessionId(),
+                       self::PACKAGE_DATA_RECIPIENT        => $helperInstance->getRecipientType(),
+                       self::PACKAGE_DATA_CONTENT          => $packageContent,
+                       self::PACKAGE_DATA_STATUS           => self::PACKAGE_STATUS_NEW,
+                       self::PACKAGE_DATA_HASH             => $this->generatePackageHash($content, $this->getSessionId()),
+                       self::PACKAGE_DATA_PRIVATE_KEY_HASH => $this->getPrivateKeyHash(),
                ));
+
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': EXIT!');
        }
 
        /**
@@ -730,6 +835,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @throws      NoTargetException       If no target can't be determined
         */
        public function declareEnqueuedPackage () {
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': CALLED!');
+
                // Make sure this method isn't working if there is no package enqueued
                if (!$this->isPackageEnqueued()) {
                        // This is not fatal but should be avoided
@@ -745,6 +853,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
 
                // Declare the raw package data for delivery
                $this->declareRawPackageData($packageData);
+
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': EXIT!');
        }
 
        /**
@@ -755,6 +866,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @return      void
         */
        public function processDeclaredPackage () {
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': CALLED!');
+
                // Sanity check if we have packages declared
                if (!$this->isPackageDeclared()) {
                        // This is not fatal but should be avoided
@@ -782,6 +896,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        // Mark the package with status failed
                        $this->changePackageStatus($packageData, self::STACKER_NAME_DECLARED, self::PACKAGE_STATUS_FAILED);
                }
+
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': EXIT!');
        }
 
        /**
@@ -790,6 +907,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @return      void
         */
        public function sendWaitingPackage () {
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': CALLED!');
+
                // Sanity check if we have packages waiting for delivery
                if (!$this->isPackageWaitingForDelivery()) {
                        // This is not fatal but should be avoided
@@ -813,6 +933,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                        // Mark package as failed
                        $this->changePackageStatus($packageData, self::STACKER_NAME_OUTGOING, self::PACKAGE_STATUS_FAILED);
                }
+
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': EXIT!');
        }
 
        /**
@@ -821,6 +944,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @return      void
         */
        public function sendEncodedData () {
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': CALLED!');
+
                // Make sure there is pending encoded data
                assert($this->isEncodedDataPending());
 
@@ -880,6 +1006,9 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
 
                // Push array back in stack
                $this->getStackInstance()->pushNamed(self::STACKER_NAME_OUTGOING_STREAM, $encodedDataArray);
+
+               // Debug message
+               //* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ': EXIT!');
        }
 
        ///////////////////////////////////////////////////////////////////////////
@@ -902,12 +1031,11 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
        /**
         * Checks whether new raw package data has arrived at a socket
         *
-        * @param       $poolInstance   An instance of a PoolableListener class
         * @return      $hasArrived             Whether new raw package data has arrived for processing
         */
-       public function isNewRawDataPending (PoolableListener $poolInstance) {
+       public function isNewRawDataPending () {
                // Visit the pool. This monitors the pool for incoming raw data.
-               $poolInstance->accept($this->getVisitorInstance());
+               $this->getListenerPoolInstance()->accept($this->getVisitorInstance());
 
                // Check for new data arrival
                $hasArrived = $this->isRawDataPending();
@@ -1085,7 +1213,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         */
        public function accept (Visitor $visitorInstance) {
                // Debug message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - START');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - CALLED!');
 
                // Visit the package
                $visitorInstance->visitNetworkPackage($this);
@@ -1094,7 +1222,7 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                $this->getAssemblerInstance()->accept($visitorInstance);
 
                // Debug message
-               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - FINISHED');
+               //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: ' . $visitorInstance->__toString() . ' has visited - EXIT!');
        }
 
        /**
@@ -1145,24 +1273,16 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                // Assert on count (should be always 3)
                assert(count($decodedArray) == self::DECODED_DATA_ARRAY_SIZE);
 
-               // Generate the signature of comparing it
-               /*
-                * @todo Unsupported feature of "signed" messages commented out
-               if (!$this->isPackageSignatureValid($decodedArray)) {
-                       // Is not valid, so throw an exception here
-                       exit(__METHOD__ . ':INVALID SIG! UNDER CONSTRUCTION!' . chr(10));
-               } // END - if
-               */
-
                /*
-                * Create 'decodedData' array with all assoziative array elements,
-                * except signature.
+                * Create 'decodedData' array with all assoziative array elements.
                 */
                $decodedData = array(
-                       self::PACKAGE_DATA_SENDER    => $decodedArray[self::INDEX_PACKAGE_SENDER],
-                       self::PACKAGE_DATA_RECIPIENT => $decodedArray[self::INDEX_PACKAGE_RECIPIENT],
-                       self::PACKAGE_DATA_CONTENT   => $decodedArray[self::INDEX_PACKAGE_CONTENT],
-                       self::PACKAGE_DATA_STATUS    => self::PACKAGE_STATUS_DECODED
+                       self::PACKAGE_DATA_SENDER           => $decodedArray[self::INDEX_PACKAGE_SENDER],
+                       self::PACKAGE_DATA_RECIPIENT        => $decodedArray[self::INDEX_PACKAGE_RECIPIENT],
+                       self::PACKAGE_DATA_CONTENT          => $decodedArray[self::INDEX_PACKAGE_CONTENT],
+                       self::PACKAGE_DATA_STATUS           => self::PACKAGE_STATUS_DECODED,
+                       self::PACKAGE_DATA_HASH             => $decodedArray[self::INDEX_PACKAGE_HASH],
+                       self::PACKAGE_DATA_PRIVATE_KEY_HASH => $decodedArray[self::INDEX_PACKAGE_PRIVATE_KEY_HASH]
                );
 
                // And return it
@@ -1194,13 +1314,19 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                 */
                $decodedContent = array(
                        // Compressor's extension used to compress the data
-                       self::PACKAGE_CONTENT_EXTENSION => $decodedContent[self::INDEX_COMPRESSOR_EXTENSION],
+                       self::PACKAGE_CONTENT_EXTENSION        => $decodedContent[self::INDEX_COMPRESSOR_EXTENSION],
                        // Package data (aka "message") in BASE64-decoded form but still compressed
-                       self::PACKAGE_CONTENT_MESSAGE   => base64_decode($decodedContent[self::INDEX_PACKAGE_DATA]),
+                       self::PACKAGE_CONTENT_MESSAGE          => base64_decode($decodedContent[self::INDEX_PACKAGE_DATA]),
                        // Tags as an indexed array for "tagging" the message
-                       self::PACKAGE_CONTENT_TAGS      => explode(self::PACKAGE_TAGS_SEPARATOR, $decodedContent[self::INDEX_TAGS]),
+                       self::PACKAGE_CONTENT_TAGS             => explode(self::PACKAGE_TAGS_SEPARATOR, $decodedContent[self::INDEX_TAGS]),
                        // Checksum of the _decoded_ data
-                       self::PACKAGE_CONTENT_CHECKSUM  => $decodedContent[self::INDEX_CHECKSUM]
+                       self::PACKAGE_CONTENT_CHECKSUM         => $decodedContent[self::INDEX_CHECKSUM],
+                       // Sender's id
+                       self::PACKAGE_CONTENT_SENDER           => $decodedData[self::PACKAGE_DATA_SENDER],
+                       // Hash from decoded raw data
+                       self::PACKAGE_CONTENT_HASH             => $decodedData[self::PACKAGE_DATA_HASH],
+                       // Hash of private key
+                       self::PACKAGE_CONTENT_PRIVATE_KEY_HASH => $decodedData[self::PACKAGE_DATA_PRIVATE_KEY_HASH]
                );
 
                // Is the checksum valid?
@@ -1239,9 +1365,18 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
         * @todo        Implement verification of all sent tags here?
         */
        public function handleNewlyArrivedMessage () {
+               // Make sure there is at least one message
+               assert($this->isNewMessageArrived());
+
                // Get it from the stacker, it is the full array with the decoded message
                $decodedContent = $this->getStackInstance()->popNamed(self::STACKER_NAME_NEW_MESSAGE);
 
+               // Generate the hash of comparing it
+               if (!$this->isPackageHashValid($decodedContent)) {
+                       // Is not valid, so throw an exception here
+                       exit(__METHOD__ . ':INVALID HASH! UNDER CONSTRUCTION!' . chr(10));
+               } // END - if
+
                // Now get a filter chain back from factory with given tags array
                $chainInstance = PackageFilterChainFactory::createChainByTagsArray($decodedContent[self::PACKAGE_CONTENT_TAGS]);
 
@@ -1249,7 +1384,13 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
                 * Process the message through all filters, note that all other
                 * elements from $decodedContent are no longer needed.
                 */
-               $chainInstance->processMessage($decodedContent[self::PACKAGE_CONTENT_MESSAGE], $this);
+               $chainInstance->processMessage($decodedContent, $this);
+
+               /*
+                * Post-processing of message data (this won't remote the message from
+                * the stack).
+                */
+               $chainInstance->postProcessMessage($this);
        }
 
        /**
@@ -1285,6 +1426,52 @@ class NetworkPackage extends BaseHubSystem implements Deliverable, Receivable, R
 
                // Handle message data
                $handlerInstance->handleMessageData($messageArray[self::MESSAGE_ARRAY_DATA], $this);
+
+               // Post-handling of message data
+               $handlerInstance->postHandleMessageData($messageArray, $this);
+       }
+
+       /**
+        * Feeds the hash and sender (as recipient for the 'sender' reward) to the
+        * miner's queue, unless the message is not a "reward claim" message as this
+        * leads to an endless loop. You may wish to run the miner to get some
+        * reward ("Hubcoins") for "mining" this hash.
+        *
+        * @param       $messageData    Array with message data
+        * @return      void
+        * @todo        ~10% done?
+        */
+       public function feedHashToMiner (array $messageData) {
+               // Is the feature enabled?
+               if (!FrameworkFeature::isFeatureAvailable('hubcoin_reward')) {
+                       /*
+                        * Feature is not enabled, don't feed the hash to the miner as it
+                        *may be invalid.
+                        */
+                       return;
+               } // END - if
+
+               // Make sure the required elements are there
+               assert(isset($messageData[self::MESSAGE_ARRAY_SENDER]));
+               assert(isset($messageData[self::MESSAGE_ARRAY_HASH]));
+               assert(isset($messageData[self::MESSAGE_ARRAY_TAGS]));
+
+               // Debug message
+               /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('NETWORK-PACKAGE[' . __METHOD__ . ':' . __LINE__ . ']: messageData=' . print_r($messageData, TRUE));
+
+               // Resolve session id ('sender' is a session id) into node id
+               $nodeId = HubTools::resolveNodeIdBySessionId($messageData[self::MESSAGE_ARRAY_SENDER]);
+
+               // Is 'claim_reward' the message type?
+               if (in_array('claim_reward', $messageData[self::MESSAGE_ARRAY_TAGS])) {
+                       /*
+                        * Then don't feed this message to the miner as this causes an
+                        * endless loop of mining.
+                        */
+                       return;
+               } // END - if
+
+               $this->partialStub('@TODO nodeId=' . $nodeId . ',messageData=' . print_r($messageData, TRUE));
        }
 }