git / moonbite-core / src/libmw/include/mw/consensus/Amount.h · raw

#pragma once#include <amount.h>#include <mw/exceptions/ValidationException.h>#include <boost/optional.hpp>#include <limits>namespace AmountUtil{inline bool IsValidMoney(const CAmount amount) noexcept{    return MoneyRange(amount);}inline bool IsValidAmountRange(const CAmount amount) noexcept{    return amount >= -MAX_MONEY && amount <= MAX_MONEY;}inline void ValidateMoney(const CAmount amount){    if (!IsValidMoney(amount)) {        ThrowValidation(EConsensusError::AMOUNT_OUT_OF_RANGE);    }}inline void ValidateAmountRange(const CAmount amount){    if (!IsValidAmountRange(amount)) {        ThrowValidation(EConsensusError::AMOUNT_OUT_OF_RANGE);    }}inline boost::optional<CAmount> TrySafeAdd(const CAmount lhs, const CAmount rhs) noexcept{    if ((rhs > 0 && lhs > std::numeric_limits<CAmount>::max() - rhs)        || (rhs < 0 && lhs < std::numeric_limits<CAmount>::min() - rhs))    {        return boost::none;    }    return lhs + rhs;}inline CAmount SafeAdd(const CAmount lhs, const CAmount rhs){    const auto sum = TrySafeAdd(lhs, rhs);    if (!sum) {        ThrowValidation(EConsensusError::AMOUNT_OUT_OF_RANGE);    }    return *sum;}inline boost::optional<CAmount> TrySafeSubtract(const CAmount lhs, const CAmount rhs) noexcept{    if ((rhs > 0 && lhs < std::numeric_limits<CAmount>::min() + rhs)        || (rhs < 0 && lhs > std::numeric_limits<CAmount>::max() + rhs))    {        return boost::none;    }    return lhs - rhs;}inline CAmount SafeSubtract(const CAmount lhs, const CAmount rhs){    const auto difference = TrySafeSubtract(lhs, rhs);    if (!difference) {        ThrowValidation(EConsensusError::AMOUNT_OUT_OF_RANGE);    }    return *difference;}inline uint64_t UnsignedAbs(const CAmount amount){    return amount >= 0 ? static_cast<uint64_t>(amount) : static_cast<uint64_t>(-(amount + 1)) + 1;}} // namespace AmountUtil