packages feed

haskoin-node 0.3.0 → 0.3.1

raw patch · 3 files changed

+48/−37 lines, 3 files

Files

Network/Haskoin/Node/BlockChain.hs view
@@ -128,21 +128,27 @@ -- rescans. merkleDownload     :: (MonadLoggerIO m, MonadBaseControl IO m)-    => NodeBlock+    => BlockHash     -> Word32     -> NodeT m        (BlockChainAction, Source (NodeT m) (Either (MerkleBlock, MerkleTxs) Tx))-merkleDownload bh batchSize = do+merkleDownload walletHash batchSize = do     -- Store the best block received from the wallet for information only.     -- This will be displayed in `hw status`-    atomicallyNodeT $ writeTVarS sharedBestBlock bh-    merkleCheckSync+    merkleSyncedActions walletHash+    walletBlockM <- runSqlNodeT $ getBlockByHash walletHash+    walletBlock <- case walletBlockM of+        Just walletBlock -> do+            atomicallyNodeT $ writeTVarS sharedBestBlock walletBlock+            return walletBlock+        Nothing ->+            error "Could not find wallet best block in headers"     rescanTMVar <- asks sharedRescan     -- Wait either for a new block to arrive or a rescan to be triggered     $(logDebug) "Waiting for a new block or a rescan..."     resE <- atomicallyNodeT $ orElseNodeT         (fmap Left $ lift $ takeTMVar rescanTMVar)-        (const (Right ()) <$> waitNewBlock (nodeHash bh))+        (const (Right ()) <$> waitNewBlock walletHash)     resM <- case resE of         -- A rescan was triggered         Left valE -> do@@ -154,16 +160,16 @@                 [ "Rescan condition reached:", show newValE ]             case newValE of                 Left ts -> tryMerkleDwnTimestamp ts batchSize-                Right _ -> tryMerkleDwnHeight bh batchSize+                Right _ -> tryMerkleDwnHeight walletBlock batchSize         -- Continue download from a hash-        Right _ -> tryMerkleDwnBlock bh batchSize+        Right _ -> tryMerkleDwnBlock walletBlock batchSize     case resM of         Just res -> return res         _ -> do             $(logWarn) "Invalid merkleDownload result. Retrying ..."             -- Sleep 10 seconds and retry             liftIO $ threadDelay $ 10*1000000-            merkleDownload bh batchSize+            merkleDownload walletHash batchSize   where     waitRescan rescanTMVar valE = do         resE <- atomicallyNodeT $ orElseNodeT@@ -176,21 +182,30 @@         Left ts -> waitFastCatchup ts         Right h -> waitHeight h -merkleCheckSync :: (MonadLoggerIO m, MonadBaseControl IO m)-                => NodeT m ()-merkleCheckSync = do+-- | Perform some actions only when headers have been synced.+merkleSyncedActions+    :: (MonadLoggerIO m, MonadBaseControl IO m)+    => BlockHash -- ^ Wallet best block+    -> NodeT m ()+merkleSyncedActions walletHash =+    asks sharedSyncLock >>= \lock -> liftBaseOp_ (Lock.with lock) $ do     -- Check if we are synced-    (synced, mempool, ourHeight) <- atomicallyNodeT $ do-        synced <- areBlocksSynced-        when synced $ writeTVarS sharedMerklePeer Nothing-        ourHeight <- nodeBlockHeight <$> readTVarS sharedBestHeader+    (synced, mempool, header) <- atomicallyNodeT $ do+        header <- readTVarS sharedBestHeader+        synced <- areBlocksSynced walletHash         mempool <- readTVarS sharedMempool-        return (synced, mempool, ourHeight)+        return (synced, mempool, header)     when synced $ do         $(logInfo) $ pack $ unwords             [ "Merkle blocks are in sync with the"-            , "network at height", show ourHeight+            , "network at height", show walletHash             ]+        -- Prune side chains+        bestBlock <- runSqlNodeT $ pruneChain header+        atomicallyNodeT $ do+            -- Update shared best header after pruning+            writeTVarS sharedBestHeader bestBlock+            writeTVarS sharedMerklePeer Nothing         -- Do a mempool sync on the first merkle sync         unless mempool $ do             atomicallyNodeT $ do@@ -469,8 +484,6 @@         (synced, ourHeight) <- syncedHeight         if synced             then do-                -- Check if merkles are synced-                merkleCheckSync                 $(logInfo) $ formatPid pid peerSessionHost $ unwords                     [ "Block headers are in sync with the"                     , "network at height", show ourHeight@@ -516,12 +529,11 @@                 , "network at height", show ourHeight                 ] -areBlocksSynced :: NodeT STM Bool-areBlocksSynced = do+areBlocksSynced :: BlockHash -> NodeT STM Bool+areBlocksSynced walletHash = do     headersSynced <- areHeadersSynced-    bestBlock     <- readTVarS sharedBestBlock     bestHeader    <- readTVarS sharedBestHeader-    return $ headersSynced && nodeHash bestBlock == nodeHash bestHeader+    return $ headersSynced && walletHash == nodeHash bestHeader  -- Check if the block headers are synced with the network height areHeadersSynced :: NodeT STM Bool
Network/Haskoin/Node/HeaderTree.hs view
@@ -37,6 +37,7 @@ , connectHeader , connectHeaders , blockLocator+, pruneChain ) where  import           Control.Monad                         (foldM, forM, unless,@@ -616,8 +617,7 @@ evalNewChain _ [] = error "You find yourself in the dungeon of missing blocks" evalNewChain best newNodes     | buildsOnBest = do-        pruneChain best-        return $ BestChain $ map (\n -> n{ nodeBlockChain = 0 }) newNodes+        return $ BestChain newNodes     | nodeBlockWork (last newNodes) > nodeBlockWork best = do         (split, old, new) <- splitChains (best, 0) (head newNodes, 0)         return $ ChainReorg split old (new ++ tail newNodes)@@ -629,16 +629,15 @@   where     buildsOnBest = nodePrev (head newNodes) == nodeHash best +-- | Remove all other chains from database and return updated best block node. pruneChain :: MonadIO m            => NodeBlock-           -> SqlPersistT m ()-pruneChain best = do-    when (nodeBlockChain best /= 0) $ do-        forks <- reverse <$> getPivots best-        delete $ from $ \t -> do-            where_ $ not_ (chainPathQuery t forks)-                 &&. t ^. NodeBlockHeight <=. val (nodeBlockHeight best)-        update $ \t -> do-            set t [ NodeBlockChain =. val 0 ]-            where_ $ t ^. NodeBlockHeight <=. val (nodeBlockHeight best)-                 &&. t ^. NodeBlockChain  !=. val 0+           -> SqlPersistT m NodeBlock+pruneChain best = if (nodeBlockChain best == 0) then return best else do+    forks <- reverse <$> getPivots best+    delete $ from $ \t -> where_ $ not_ (chainPathQuery t forks)+    update $ \t -> do+        set t [ NodeBlockChain =. val 0 ]+        where_ $ t ^. NodeBlockHeight <=. val (nodeBlockHeight best)+              &&. t ^. NodeBlockChain  !=. val 0+    return best{ nodeBlockChain = 0 }
haskoin-node.cabal view
@@ -1,5 +1,5 @@ name:                  haskoin-node-version:               0.3.0+version:               0.3.1 synopsis:     Implementation of a Bitoin node. description: