Esempio n. 1
0
        // Returns the number of empty and full blocks, based on PoW field
        public List <int> getBlocksCount()
        {
            int empty_blocks = 0;
            int full_blocks  = 0;

            ulong lastBlockNum        = Node.blockChain.getLastBlockNum();
            ulong oldestRedactedBlock = 0;

            if (lastBlockNum > CoreConfig.getRedactedWindowSize())
            {
                oldestRedactedBlock = lastBlockNum - CoreConfig.getRedactedWindowSize();
            }

            for (ulong i = lastBlockNum; i > oldestRedactedBlock; i--)
            {
                Block block = Node.blockChain.getBlock(i, false, false);
                if (block == null)
                {
                    continue;
                }
                if (block.powField == null)
                {
                    empty_blocks++;
                }
                else
                {
                    full_blocks++;
                }
            }
            List <int> result = new List <int>();

            result.Add(empty_blocks);
            result.Add(full_blocks);
            return(result);
        }
Esempio n. 2
0
        private ulong getLowestBlockNum()
        {
            ulong lowestBlockNum = 1;

            if (Config.fullStorageDataVerification)
            {
                return(lowestBlockNum);
            }

            ulong syncToBlock = wsSyncConfirmedBlockNum;

            if (syncToBlock > CoreConfig.getRedactedWindowSize())
            {
                lowestBlockNum = syncToBlock - CoreConfig.getRedactedWindowSize();
            }
            return(lowestBlockNum);
        }
Esempio n. 3
0
        public bool appendBlock(Block b, bool add_to_storage = true)
        {
            lock (blocks)
            {
                if (b.blockNum > lastBlockNum)
                {
                    lastBlock    = b;
                    lastBlockNum = b.blockNum;
                    if (b.version != lastBlockVersion)
                    {
                        lastBlockVersion = b.version;
                    }
                }

                if (b.lastSuperBlockChecksum != null || b.blockNum == 1)
                {
                    pendingSuperBlocks.Remove(b.blockNum);

                    lastSuperBlockNum      = b.blockNum;
                    lastSuperBlockChecksum = b.blockChecksum;
                }

                // special case when we are starting up and have an empty chain
                if (blocks.Count == 0)
                {
                    blocks.Add(b);
                    lock (blocksDictionary)
                    {
                        blocksDictionary.Add(b.blockNum, b);
                    }
                    Storage.insertBlock(b);
                    return(true);
                }
                // check for invalid block appending
                if (b.blockNum != blocks[blocks.Count - 1].blockNum + 1)
                {
                    Logging.warn(String.Format("Attempting to add non-sequential block #{0} after block #{1}.",
                                               b.blockNum,
                                               blocks[blocks.Count - 1].blockNum));
                    return(false);
                }
                if (!b.lastBlockChecksum.SequenceEqual(blocks[blocks.Count - 1].blockChecksum))
                {
                    Logging.error(String.Format("Attempting to add a block #{0} with invalid lastBlockChecksum!", b.blockNum));
                    return(false);
                }
                if (b.signatureFreezeChecksum != null && blocks.Count > 5 && !blocks[blocks.Count - 5].calculateSignatureChecksum().SequenceEqual(b.signatureFreezeChecksum))
                {
                    Logging.error(String.Format("Attempting to add a block #{0} with invalid sigFreezeChecksum!", b.blockNum));
                    return(false);
                }
                blocks.Add(b);
                lock (blocksDictionary)
                {
                    blocksDictionary.Add(b.blockNum, b);
                }
            }

            if (add_to_storage)
            {
                // Add block to storage
                Storage.insertBlock(b);
            }

            CoreConfig.redactedWindowSize    = CoreConfig.getRedactedWindowSize(b.version);
            CoreConfig.minRedactedWindowSize = CoreConfig.getRedactedWindowSize(b.version);

            redactChain();
            lock (blocks)
            {
                if (blocks.Count > 20)
                {
                    Block tmp_block = getBlock(b.blockNum - 20);
                    if (tmp_block != null)
                    {
                        TransactionPool.compactTransactionsForBlock(tmp_block);
                        tmp_block.compact();
                    }
                }
                compactBlockSigs();
            }

            lastBlockReceivedTime = Clock.getTimestamp();

            return(true);
        }
Esempio n. 4
0
        // Start the node
        static public void start(bool verboseConsoleOutput)
        {
            // First create the data folder if it does not already exist
            checkDataFolder();

            renameStorageFiles(); // this function will be here temporarily for the next few version, then it will be removed to keep a cleaner code base

            // debug
            if (Config.networkDumpFile != "")
            {
                NetDump.Instance.start(Config.networkDumpFile);
            }

            NetworkUtils.configureNetwork();

            char node_type = 'M'; // TODO TODO TODO TODO change this to 'W' or 'C' after the upgrade

            if (Config.disableMiner)
            {
                node_type = 'M';
            }

            // Check if we're in worker-only mode
            if (Config.workerOnly)
            {
                // Enable miner
                Config.disableMiner = false;
                node_type           = 'W';
                CoreConfig.simultaneousConnectedNeighbors = 4;
            }

            // Generate presence list
            PresenceList.generatePresenceList(Config.publicServerIP, node_type);

            // Initialize storage
            Storage.prepareStorage();

            ActivityStorage.prepareStorage();

            // Initialize the block chain
            blockChain = new BlockChain();

            //runDiffTests();
            //return;

            // Create the block processor and sync
            blockProcessor = new BlockProcessor();
            blockSync      = new BlockSync();

            // Start the HTTP JSON API server
            apiServer = new APIServer();

            if (IXICore.Platform.onMono() == false && !Config.disableWebStart)
            {
                System.Diagnostics.Process.Start("http://localhost:" + Config.apiPort);
            }

            miner = new Miner();

            // Start the network queue
            NetworkQueue.start();

            // prepare stats screen
            Config.verboseConsoleOutput = verboseConsoleOutput;
            Logging.consoleOutput       = verboseConsoleOutput;
            Logging.flush();
            if (Config.verboseConsoleOutput == false)
            {
                statsConsoleScreen.clearScreen();
            }

            // Distribute genesis funds
            IxiNumber genesisFunds = new IxiNumber(Config.genesisFunds);

            // Check if this is a genesis node
            if (genesisFunds > (long)0)
            {
                Logging.info(String.Format("Genesis {0} specified. Starting operation.", genesisFunds));

                distributeGenesisFunds(genesisFunds);

                genesisNode = true;
                blockProcessor.resumeOperation();
                serverStarted = true;
                if (!isMasterNode())
                {
                    Logging.info("Network server is not enabled in modes other than master node.");
                }
                else
                {
                    NetworkServer.beginNetworkOperations();
                }
            }
            else
            {
                if (File.Exists(Config.genesisFile))
                {
                    Block genesis = new Block(Crypto.stringToHash(File.ReadAllText(Config.genesisFile)));
                    blockChain.setGenesisBlock(genesis);
                }
                ulong lastLocalBlockNum = Meta.Storage.getLastBlockNum();
                if (lastLocalBlockNum > 6)
                {
                    lastLocalBlockNum = lastLocalBlockNum - 6;
                }
                if (Config.lastGoodBlock > 0 && Config.lastGoodBlock < lastLocalBlockNum)
                {
                    lastLocalBlockNum = Config.lastGoodBlock;
                }
                if (lastLocalBlockNum > 0)
                {
                    Block b = blockChain.getBlock(lastLocalBlockNum, true);
                    if (b != null)
                    {
                        CoreConfig.minRedactedWindowSize = CoreConfig.getRedactedWindowSize(b.version);
                        CoreConfig.redactedWindowSize    = CoreConfig.getRedactedWindowSize(b.version);
                    }
                }

                if (Config.recoverFromFile)
                {
                    Block b = Meta.Storage.getBlock(lastLocalBlockNum);
                    blockSync.onHelloDataReceived(b.blockNum, b.blockChecksum, b.version, b.walletStateChecksum, b.getUniqueSignatureCount(), lastLocalBlockNum);
                }
                else
                {
                    ulong blockNum = WalletStateStorage.restoreWalletState(lastLocalBlockNum);
                    if (blockNum > 0)
                    {
                        Block b = blockChain.getBlock(blockNum, true);
                        if (b != null)
                        {
                            blockSync.onHelloDataReceived(blockNum, b.blockChecksum, b.version, b.walletStateChecksum, b.getUniqueSignatureCount(), lastLocalBlockNum);
                        }
                        else
                        {
                            walletState.clear();
                        }
                    }
                    else
                    {
                        blockSync.lastBlockToReadFromStorage = lastLocalBlockNum;
                    }

                    // Start the server for ping purposes
                    serverStarted = true;
                    if (!isMasterNode())
                    {
                        Logging.info("Network server is not enabled in modes other than master node.");
                    }
                    else
                    {
                        NetworkServer.beginNetworkOperations();
                    }

                    // Start the network client manager
                    NetworkClientManager.start();
                }
            }

            PresenceList.startKeepAlive();

            TLC = new ThreadLiveCheck();
            // Start the maintenance thread
            maintenanceThread      = new Thread(performMaintenance);
            maintenanceThread.Name = "Node_Maintenance_Thread";
            maintenanceThread.Start();
        }
Esempio n. 5
0
        // Returns the most recent block without a PoW flag in the redacted blockchain
        private void searchForBlock()
        {
            lock (solvedBlocks)
            {
                List <ulong> tmpSolvedBlocks = new List <ulong>(solvedBlocks);
                foreach (ulong blockNum in tmpSolvedBlocks)
                {
                    Block b = Node.blockChain.getBlock(blockNum, false, false);
                    if (b == null || b.powField != null)
                    {
                        solvedBlocks.Remove(blockNum);
                    }
                }
            }

            Block candidate_block = null;

            List <Block> blockList = null;

            int block_offset = 1;

            if (Node.blockChain.Count > (long)CoreConfig.getRedactedWindowSize())
            {
                block_offset = 1000;
            }

            if (searchMode == BlockSearchMode.lowestDifficulty)
            {
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => x.difficulty).ToList();
            }
            else if (searchMode == BlockSearchMode.randomLowestDifficulty)
            {
                Random rnd = new Random();
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => x.difficulty).Skip(rnd.Next(500)).ToList();
            }
            else if (searchMode == BlockSearchMode.latestBlock)
            {
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderByDescending(x => x.blockNum).ToList();
            }
            else if (searchMode == BlockSearchMode.random)
            {
                Random rnd = new Random();
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => rnd.Next()).ToList();
            }

            // Check if the block list exists
            if (blockList == null)
            {
                Logging.error("No block list found while searching. Likely an incorrect miner block search mode.");
                return;
            }

            // Go through each block in the list
            foreach (Block block in blockList)
            {
                if (block.powField == null)
                {
                    ulong solved = 0;
                    lock (solvedBlocks)
                    {
                        solved = solvedBlocks.Find(x => x == block.blockNum);
                    }

                    // Check if this block is in the solved list
                    if (solved > 0)
                    {
                        // Do nothing at this point
                    }
                    else
                    {
                        // Block is not solved, select it
                        candidate_block = block;
                        break;
                    }
                }
            }

            if (candidate_block == null)
            {
                // No blocks with empty PoW field found, wait a bit
                Thread.Sleep(1000);
                return;
            }

            currentBlockNum        = candidate_block.blockNum;
            currentBlockDifficulty = candidate_block.difficulty;
            currentBlockVersion    = candidate_block.version;
            currentHashCeil        = getHashCeilFromDifficulty(currentBlockDifficulty);

            activeBlock = candidate_block;
            byte[] block_checksum = activeBlock.blockChecksum;
            byte[] solver_address = Node.walletStorage.getPrimaryAddress();
            activeBlockChallenge = new byte[block_checksum.Length + solver_address.Length];
            System.Buffer.BlockCopy(block_checksum, 0, activeBlockChallenge, 0, block_checksum.Length);
            System.Buffer.BlockCopy(solver_address, 0, activeBlockChallenge, block_checksum.Length, solver_address.Length);

            blockFound = true;

            return;
        }
Esempio n. 6
0
        // Static function used by the getMiningBlock API call
        public static Block getMiningBlock(BlockSearchMode searchMode)
        {
            Block candidate_block = null;

            List <Block> blockList = null;

            int block_offset = 1;

            if (Node.blockChain.Count > (long)CoreConfig.getRedactedWindowSize())
            {
                block_offset = 1000;
            }

            if (searchMode == BlockSearchMode.lowestDifficulty)
            {
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => x.difficulty).ToList();
            }
            else if (searchMode == BlockSearchMode.randomLowestDifficulty)
            {
                Random rnd = new Random();
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => x.difficulty).Skip(rnd.Next(500)).ToList();
            }
            else if (searchMode == BlockSearchMode.latestBlock)
            {
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderByDescending(x => x.blockNum).ToList();
            }
            else if (searchMode == BlockSearchMode.random)
            {
                Random rnd = new Random();
                blockList = Node.blockChain.getBlocks(block_offset, (int)Node.blockChain.Count - block_offset).Where(x => x.powField == null).OrderBy(x => rnd.Next()).ToList();
            }
            // Check if the block list exists
            if (blockList == null)
            {
                Logging.error("No block list found while searching.");
                return(null);
            }

            // Go through each block in the list
            foreach (Block block in blockList)
            {
                if (block.powField == null)
                {
                    ulong solved = 0;
                    lock (solvedBlocks)
                    {
                        solved = solvedBlocks.Find(x => x == block.blockNum);
                    }

                    // Check if this block is in the solved list
                    if (solved > 0)
                    {
                        // Do nothing at this point
                    }
                    else
                    {
                        // Block is not solved, select it
                        candidate_block = block;
                        break;
                    }
                }
            }

            return(candidate_block);
        }