public override bool getBlocks(List <Hash> blockHashes, List <BlockDetails> blocks)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            if (blockHashes.Count == 0)
            {
                return(true);
            }

            logger.functorMethod(DEBUGGING) << "Get blocks by hash request came.";
            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                node.getBlocks(blockHashes, blocks, cb);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get blocks by hash: " << ec.message();
                throw std::system_error(ec);
            }

            Debug.Assert(blocks.Count == blockHashes.Count);
            return(true);
        }
        public override bool getTransactionsByPaymentId(Hash paymentId, List <TransactionDetails> transactions)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            logger.functorMethod(DEBUGGING) << "Get transactions by payment id " << paymentId << " request came.";

            List <Crypto.Hash> transactionHashes = new List <Crypto.Hash>();

            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                return(node.getTransactionHashesByPaymentId(paymentId, transactionHashes, cb));
            });

            var ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get transaction hashes: " << ec.message();
                throw std::system_error(ec);
            }

            if (transactionHashes.Count == 0)
            {
                return(false);
            }

            return(getTransactions(transactionHashes, transactions));
        }
        public override bool isSynchronized()
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            logger.functorMethod(DEBUGGING) << "Synchronization status request came.";
            bool syncStatus = false;

            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                node.isSynchronized(ref syncStatus, cb);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get synchronization status: " << ec.message();
                throw std::system_error(ec);
            }

            synchronized.store(syncStatus);
            return(syncStatus);
        }
示例#4
0
        private std::error_code write(IWriteBatch batch, bool sync)
        {
            rocksdb.WriteOptions writeOptions = new rocksdb.WriteOptions();
            writeOptions.sync = sync;

            rocksdb.WriteBatch             rocksdbBatch = new rocksdb.WriteBatch();
            List <Tuple <string, string> > rawData      = new List <Tuple <string, string> >(batch.extractRawDataToInsert());

            foreach (Tuple <string, string> kvPair in rawData)
            {
                rocksdbBatch.Put(new rocksdb.Slice(kvPair.Item1), new rocksdb.Slice(kvPair.Item2));
            }

            List <string> rawKeys = new List <string>(batch.extractRawKeysToRemove());

            foreach (string key in rawKeys)
            {
                rocksdbBatch.Delete(new rocksdb.Slice(key));
            }

            rocksdb.Status status = db.Write(writeOptions, rocksdbBatch);

            if (!status.ok())
            {
                logger(ERROR) << "Can't write to DB. " << status.ToString();
                return(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
            }
            else
            {
                return(std::error_code());
            }
        }
 public override ulong getRewardBlocksWindow()
 {
     if (state.load() != State.INITIALIZED)
     {
         throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
     }
     return(parameters.CRYPTONOTE_REWARD_BLOCKS_WINDOW);
 }
 public override bool addObserver(IBlockchainObserver observer)
 {
     if (state.load() != State.INITIALIZED)
     {
         throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
     }
     observersCounter.fetch_add(1);
     return(observerManager.add(observer));
 }
示例#7
0
        public override std::error_code writeSync(IWriteBatch batch)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.NOT_INITIALIZED));
            }

            return(write(batch, true));
        }
        public override void shutdown()
        {
            if (state.load() != State.INITIALIZED)
            {
                logger.functorMethod(ERROR) << "Shutdown called on not initialized BlockchainExplorer.";
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            node.removeObserver(this);
            asyncContextCounter.waitAsyncContextsFinish();
            state.store(State.NOT_INITIALIZED);
        }
示例#9
0
        public void shutdown()
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.NOT_INITIALIZED));
            }

            logger(INFO) << "Closing DB.";
            db.Flush(new rocksdb.FlushOptions());
            db.SyncWAL();
            db.reset();
            state.store(State.NOT_INITIALIZED);
        }
示例#10
0
//C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete':
//  RocksDBWrapper(const RocksDBWrapper&) = delete;
//C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete':
//  RocksDBWrapper(RocksDBWrapper&&) = delete;

//C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete':
//  RocksDBWrapper& operator =(const RocksDBWrapper&) = delete;
//C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete':
//  RocksDBWrapper& operator =(RocksDBWrapper&&) = delete;

        public void init(DataBaseConfig config)
        {
            if (state.load() != State.NOT_INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.ALREADY_INITIALIZED));
            }

            string dataDir = getDataDir(config);

            logger(INFO) << "Opening DB in " << dataDir;

            rocksdb.DB dbPtr;

            rocksdb.Options dbOptions = getDBOptions(config);
            rocksdb.Status  status    = rocksdb.DB.Open(dbOptions, dataDir, dbPtr);
            if (status.ok())
            {
                logger(INFO) << "DB opened in " << dataDir;
            }
            else if (!status.ok() && status.IsInvalidArgument())
            {
                logger(INFO) << "DB not found in " << dataDir << ". Creating new DB...";
                dbOptions.create_if_missing = true;
                rocksdb.Status status = rocksdb.DB.Open(dbOptions, dataDir, dbPtr);
                if (!status.ok())
                {
                    logger(ERROR) << "DB Error. DB can't be created in " << dataDir << ". Error: " << status.ToString();
                    throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
                }
            }
            else if (status.IsIOError())
            {
                logger(ERROR) << "DB Error. DB can't be opened in " << dataDir << ". Error: " << status.ToString();
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.IO_ERROR));
            }
            else
            {
                logger(ERROR) << "DB Error. DB can't be opened in " << dataDir << ". Error: " << status.ToString();
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
            }

            db.reset(dbPtr);
            state.store(State.INITIALIZED);
        }
示例#11
0
        /* This method is used by WalletService to determine if the mixin amount is correct
         * for the current block height */
        public static Tuple <bool, string, std::error_code> validate(uint mixin, uint height)
        {
            var(minMixin, maxMixin) = getMixinAllowableRange(height);

            std::stringstream str = new std::stringstream();

            if (mixin < minMixin)
            {
                str << "Mixin of " << (int)mixin << " under minimum mixin threshold of " << minMixin;
                return(new Tuple <bool, string, std::error_code>(false, str.str(), GlobalMembers.make_error_code(CryptoNote.error.MIXIN_BELOW_THRESHOLD)));
            }
            else if (mixin > maxMixin)
            {
                str << "Mixin of " << (int)mixin << " above maximum mixin threshold of " << maxMixin;
                return(new Tuple <bool, string, std::error_code>(false, str.str(), GlobalMembers.make_error_code(CryptoNote.error.MIXIN_ABOVE_THRESHOLD)));
            }

            return(new Tuple <bool, string, std::error_code>(true, string(), std::error_code()));
        }
        public override bool getBlocks(ulong timestampBegin, ulong timestampEnd, uint blocksNumberLimit, List <BlockDetails> blocks, ref uint blocksNumberWithinTimestamps)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            if (timestampBegin > timestampEnd)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.REQUEST_ERROR), "timestampBegin must not be greater than timestampEnd");
            }

            logger.functorMethod(DEBUGGING) << "Get blocks by timestamp " << timestampBegin << " - " << timestampEnd << " request came.";

            List <Hash> blockHashes = new List <Hash>();

            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                node.getBlockHashesByTimestamps(new ulong(timestampBegin), timestampEnd - timestampBegin + 1, blockHashes, cb);
            });
            var ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get blocks hashes by timestamps: " << ec.message();
                throw std::system_error(ec);
            }

            blocksNumberWithinTimestamps = (uint)blockHashes.Count;

            if (blocksNumberLimit < blocksNumberWithinTimestamps)
            {
//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent to the STL vector 'erase' method in C#:
                blockHashes.erase(std::next(blockHashes.GetEnumerator(), blocksNumberLimit), blockHashes.end());
            }

            if (blockHashes.Count == 0)
            {
                throw new System.Exception("block hashes not found");
            }

            return(getBlocks(blockHashes, blocks));
        }
        public override ulong getFullRewardMaxBlockSize(ushort majorVersion)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            if (majorVersion >= BLOCK_MAJOR_VERSION_3)
            {
                return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE);
            }
            else if (majorVersion == BLOCK_MAJOR_VERSION_2)
            {
                return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2);
            }
            else
            {
                return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
            }
        }
示例#14
0
        public static HttpResponse.HTTP_STATUS parseResponseStatusFromString(string status)
        {
            if (status == "200 OK" || status == "200 Ok")
            {
                return(CryptoNote.HttpResponse.STATUS_200);
            }
            else if (status == "404 Not Found")
            {
                return(CryptoNote.HttpResponse.STATUS_404);
            }
            else if (status == "500 Internal Server Error")
            {
                return(CryptoNote.HttpResponse.STATUS_500);
            }
            else
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL), "Unknown HTTP status code is given");
            }

            return(CryptoNote.HttpResponse.STATUS_200); //unaccessible
        }
        public override void init()
        {
            if (state.load() != State.NOT_INITIALIZED)
            {
                logger.functorMethod(ERROR) << "Init called on already initialized BlockchainExplorer.";
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.ALREADY_INITIALIZED));
            }

            if (!getBlockchainTop(ref knownBlockchainTop, false))
            {
                logger.functorMethod(ERROR) << "Can't get blockchain top.";
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR));
            }

            List <Crypto.Hash> knownPoolTransactionHashes = new List <Crypto.Hash>();
            bool isBlockchainActual;
            List <TransactionDetails> newTransactions     = new List <TransactionDetails>();
            List <Crypto.Hash>        removedTransactions = new List <Crypto.Hash>();
            StateRollback             stateRollback       = new StateRollback(state);

//C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created:
//ORIGINAL LINE: if (!getPoolState(knownPoolTransactionHashes, knownBlockchainTop.hash, isBlockchainActual, newTransactions, removedTransactions))
            if (!getPoolState(knownPoolTransactionHashes, new Crypto.Hash(knownBlockchainTop.hash), ref isBlockchainActual, newTransactions, removedTransactions))
            {
                logger.functorMethod(ERROR) << "Can't get pool state.";
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR));
            }

            Debug.Assert(removedTransactions.Count == 0);

            if (node.addObserver(this))
            {
                stateRollback.commit();
            }
            else
            {
                logger.functorMethod(ERROR) << "Can't add observer to node.";
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR));
            }
        }
示例#16
0
        private void readWord(std::istream stream, string word)
        {
            char c;

            stream.get(c);
            while (stream.good() && c != ' ' && c != '\r')
            {
                word += c;
                stream.get(c);
            }

            GlobalMembers.throwIfNotGood(stream);

            if (c == '\r')
            {
                stream.get(c);
                if (c != '\n')
                {
                    throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL));
                }
            }
        }
        public override bool getPoolState(List <Hash> knownPoolTransactionHashes, Hash knownBlockchainTopHash, ref bool isBlockchainActual, List <TransactionDetails> newTransactions, List <Hash> removedTransactions)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            logger.functorMethod(DEBUGGING) << "Get pool state request came.";
            List <std::unique_ptr <ITransactionReader> > rawNewTransactions = new List <std::unique_ptr <ITransactionReader> >();

            NodeRequest new request((INodeOriginal.Callback callback) =>
            {
                List <Hash> hashes = new List <Hash>();
                foreach (Hash hash in knownPoolTransactionHashes)
                {
                    hashes.Add(std::move(hash));
                }

                node.getPoolSymmetricDifference(std::move(hashes), reinterpret_cast <Hash&>(knownBlockchainTopHash), ref isBlockchainActual, rawNewTransactions, removedTransactions, callback);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get pool state: " << ec.message();
                throw std::system_error(ec);
            }

            List <Hash> newTransactionsHashes = new List <Hash>();

            foreach (var rawTransaction in rawNewTransactions)
            {
                Hash transactionHash = rawTransaction.getTransactionHash();
                newTransactionsHashes.Add(std::move(transactionHash));
            }

            return(getTransactions(newTransactionsHashes, newTransactions));
        }
示例#18
0
        public override std::error_code read(IReadBatch batch)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw new System.Exception("Not initialized.");
            }

            rocksdb.ReadOptions readOptions = new rocksdb.ReadOptions();

            List <string>        rawKeys   = new List <string>(batch.getRawKeys());
            List <rocksdb.Slice> keySlices = new List <rocksdb.Slice>();

            keySlices.Capacity = rawKeys.Count;
            foreach (string key in rawKeys)
            {
                keySlices.emplace_back(new rocksdb.Slice(key));
            }

            List <string> values = new List <string>();

            values.Capacity = rawKeys.Count;
            List <rocksdb.Status> statuses = db.MultiGet(readOptions, keySlices, values);

            std::error_code error        = new std::error_code();
            List <bool>     resultStates = new List <bool>();

            foreach (rocksdb  in :Status & status : statuses)
            {
                if (!status.ok() && !status.IsNotFound())
                {
                    return(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
                }
                resultStates.Add(status.ok());
            }

            batch.submitRawResult(values, resultStates);
            return(std::error_code());
        }
示例#19
0
        public void destroy(DataBaseConfig config)
        {
            if (state.load() != State.NOT_INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.ALREADY_INITIALIZED));
            }

            string dataDir = getDataDir(config);

            logger(WARNING) << "Destroying DB in " << dataDir;

            rocksdb.Options dbOptions = getDBOptions(config);
            rocksdb.Status  status    = rocksdb.DestroyDB(dataDir, dbOptions);

            if (status.ok())
            {
                logger(WARNING) << "DB destroyed in " << dataDir;
            }
            else
            {
                logger(ERROR) << "DB Error. DB can't be destroyed in " << dataDir << ". Error: " << status.ToString();
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
            }
        }
示例#20
0
        private bool readHeader(std::istream stream, string name, string value)
        {
            char c;
            bool isName = true;

            stream.get(c);
            while (stream.good() && c != '\r')
            {
                if (c == ':')
                {
                    if (stream.peek() == ' ')
                    {
                        stream.get(c);
                    }

                    if (string.IsNullOrEmpty(name))
                    {
                        throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.EMPTY_HEADER));
                    }

                    if (isName)
                    {
                        isName = false;
                        stream.get(c);
                        continue;
                    }
                }

                if (isName)
                {
                    name += c;
                    stream.get(c);
                }
                else
                {
                    value += c;
                    stream.get(c);
                }
            }

            GlobalMembers.throwIfNotGood(stream);

            stream.get(c);
            if (c != '\n')
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL));
            }

            std::transform(name.GetEnumerator(), name.end(), name.GetEnumerator(), global::tolower);

            c = stream.peek();
            if (c == '\r')
            {
                stream.get(c).get(c);
                if (c != '\n')
                {
                    throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL));
                }

                return(false); //no more headers
            }

            return(true);
        }