Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement OLE-300 #1300

Merged
merged 3 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ QT_RES_FONTS = \
QT_RES_ICONS = \
qt/res/icons/add.png \
qt/res/icons/address-book.png \
qt/res/icons/balances.png \
qt/res/icons/bitcoin.ico \
qt/res/icons/bitcoin_testnet.ico \
qt/res/icons/bitcoin.png \
Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddArg("-omniuiwalletscope", "Max. transactions to show in trade and transaction history (default: 65535)", false, OptionsCategory::OMNI);
argsman.AddArg("-omnishowblockconsensushash", "Calculate and log the consensus hash for the specified block", false, OptionsCategory::OMNI);
argsman.AddArg("-omniuseragent", "Show Omni and Omni version in user agent string (default: 1)", false, OptionsCategory::OMNI);
argsman.AddArg("-omnisafeaddresses", "Enforce using of Omni safe address over segwit and taproot (default: 1)", false, OptionsCategory::OMNI);

#if HAVE_DECL_FORK
argsman.AddArg("-daemon", strprintf("Run in the background as a daemon and accept commands (default: %d)", DEFAULT_DAEMON), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
Expand Down
10 changes: 3 additions & 7 deletions src/omnicore/dbstolist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <omnicore/convert.h>
#include <omnicore/dbstolist.h>
#include <omnicore/log.h>
#include <omnicore/script.h>
#include <omnicore/sp.h>
#include <omnicore/walletutils.h>

Expand All @@ -28,7 +29,6 @@

using mastercore::atoi;
using mastercore::IsMyAddress;
using mastercore::isPropertyDivisible;

CMPSTOList::CMPSTOList(const fs::path& path, bool fWipe)
{
Expand Down Expand Up @@ -95,12 +95,8 @@ void CMPSTOList::getRecipients(const uint256 txid, std::string filterAddress, Un
return; //(something went wrong)
}
UniValue recipient(UniValue::VOBJ);
recipient.pushKV("address", recipientAddress);
if (isPropertyDivisible(propertyId)) {
recipient.pushKV("amount", FormatDivisibleMP(amount));
} else {
recipient.pushKV("amount", FormatIndivisibleMP(amount));
}
recipient.pushKV("address", TryEncodeOmniAddress(recipientAddress));
recipient.pushKV("amount", FormatMP(propertyId, amount));
*total += amount;
recipientArray->push_back(recipient);
}
Expand Down
60 changes: 24 additions & 36 deletions src/omnicore/dbtradelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
#include <omnicore/dbtradelist.h>
#include <omnicore/log.h>
#include <omnicore/mdex.h>
#include <omnicore/script.h>
#include <omnicore/sp.h>

#include <chain.h>
#include <chainparams.h>
#include <consensus/amount.h>
#include <fs.h>
#include <reverse_iterator.h>
#include <uint256.h>
#include <util/strencodings.h>
#include <validation.h>
Expand Down Expand Up @@ -177,14 +179,14 @@ bool CMPTradeList::getMatchingTrades(const uint256& txid, uint32_t propertyId, U
trade.pushKV("blocktime", pBlockIndex->GetBlockTime());
}
if (prop1 == propertyId) {
trade.pushKV("address", address1);
trade.pushKV("address", TryEncodeOmniAddress(address1));
trade.pushKV("amountsold", strAmount1);
trade.pushKV("amountreceived", strAmount2);
trade.pushKV("tradingfee", strTradingFee);
totalReceived += amount2;
totalSold += amount1;
} else {
trade.pushKV("address", address2);
trade.pushKV("address", TryEncodeOmniAddress(address2));
trade.pushKV("amountsold", strAmount2PlusFee);
trade.pushKV("amountreceived", strAmount1);
trade.pushKV("tradingfee", FormatMP(prop1, 0)); // not the liquidity taker so no fee for this participant - include attribute for standardness
Expand Down Expand Up @@ -242,15 +244,10 @@ void CMPTradeList::getTradesForAddress(const std::string& address, std::vector<u
}
}

static bool CompareTradePair(const std::pair<int64_t, UniValue>& firstJSONObj, const std::pair<int64_t, UniValue>& secondJSONObj)
{
return firstJSONObj.first > secondJSONObj.first;
}

// obtains an array of matching trades with pricing and volume details for a pair sorted by blocknumber
void CMPTradeList::getTradesForPair(uint32_t propertyIdSideA, uint32_t propertyIdSideB, UniValue& responseArray, uint64_t count)
{
if (!pdb) return;
if (!pdb || !count) return;
leveldb::Iterator* it = NewIterator();
std::vector<std::pair<int64_t, UniValue> > vecResponse;
bool propertyIdSideAIsDivisible = isPropertyDivisible(propertyIdSideA);
Expand Down Expand Up @@ -292,8 +289,14 @@ void CMPTradeList::getTradesForPair(uint32_t propertyIdSideA, uint32_t propertyI

rational_t unitPrice(amountReceived, amountSold);
rational_t inversePrice(amountSold, amountReceived);
if (!propertyIdSideAIsDivisible) unitPrice = unitPrice / COIN;
if (!propertyIdSideBIsDivisible) inversePrice = inversePrice / COIN;
if (propertyIdSideAIsDivisible && !propertyIdSideBIsDivisible) {
unitPrice *= COIN;
inversePrice /= COIN;
}
if (!propertyIdSideAIsDivisible && propertyIdSideBIsDivisible) {
unitPrice /= COIN;
inversePrice *= COIN;
}
std::string unitPriceStr = xToString(unitPrice); // TODO: not here!
std::string inversePriceStr = xToString(inversePrice);

Expand All @@ -307,38 +310,23 @@ void CMPTradeList::getTradesForPair(uint32_t propertyIdSideA, uint32_t propertyI
trade.pushKV("unitprice", unitPriceStr);
trade.pushKV("inverseprice", inversePriceStr);
trade.pushKV("sellertxid", sellerTxid.GetHex());
trade.pushKV("selleraddress", sellerAddress);
if (propertyIdSideAIsDivisible) {
trade.pushKV("amountsold", FormatDivisibleMP(amountSold));
} else {
trade.pushKV("amountsold", FormatIndivisibleMP(amountSold));
}
if (propertyIdSideBIsDivisible) {
trade.pushKV("amountreceived", FormatDivisibleMP(amountReceived));
} else {
trade.pushKV("amountreceived", FormatIndivisibleMP(amountReceived));
}
trade.pushKV("selleraddress", TryEncodeOmniAddress(sellerAddress));
trade.pushKV("amountsold", FormatMP(propertyIdSideA, amountSold));
trade.pushKV("amountreceived", FormatMP(propertyIdSideB, amountReceived));
trade.pushKV("matchingtxid", matchingTxid.GetHex());
trade.pushKV("matchingaddress", matchingAddress);
trade.pushKV("matchingaddress", TryEncodeOmniAddress(matchingAddress));
vecResponse.push_back(std::make_pair(blockNum, trade));
}

// sort the response most recent first before adding to the array
std::sort(vecResponse.begin(), vecResponse.end(), CompareTradePair);
uint64_t processed = 0;
for (std::vector<std::pair<int64_t, UniValue> >::iterator it = vecResponse.begin(); it != vecResponse.end(); ++it) {
responseArray.push_back(it->second);
processed++;
if (processed >= count) break;
std::sort(vecResponse.begin(), vecResponse.end(), [](auto& lhs, auto& rhs) {
return lhs.first > rhs.first;
});
if (vecResponse.size() > count) {
vecResponse.resize(count);
}

std::vector<UniValue> responseArrayValues = responseArray.getValues();
std::reverse(responseArrayValues.begin(), responseArrayValues.end());
responseArray.clear();
for (std::vector<UniValue>::iterator it = responseArrayValues.begin(); it != responseArrayValues.end(); ++it) {
responseArray.push_back(*it);
for (auto& [_, value] : reverse_iterate(vecResponse)) {
responseArray.push_back(std::move(value));
}

delete it;
}

Expand Down
62 changes: 61 additions & 1 deletion src/omnicore/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <util/strencodings.h>

#include <omnicore/omnicore.h>
#include <omnicore/script.h>
#include <omnicore/utilsbitcoin.h>

#include <consensus/consensus.h>
#include <txmempool.h>
Expand Down Expand Up @@ -266,13 +268,14 @@ UniValue getaddressbalance(const JSONRPCRequest& request)
CAmount balance = 0;
CAmount received = 0;
CAmount immature = 0;
auto height = mastercore::GetHeight();

for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) {
if (it->second > 0) {
received += it->second;
}
balance += it->second;
if (it->first.txindex == 0 && ((::ChainActive().Height() - it->first.blockHeight) < COINBASE_MATURITY))
if (it->first.txindex == 0 && ((height - it->first.blockHeight) < COINBASE_MATURITY))
immature += it->second;
}

Expand Down Expand Up @@ -716,6 +719,61 @@ static UniValue clearmempool(const JSONRPCRequest& request)
return removed;
}

static UniValue omni_encodeaddress(const JSONRPCRequest& request)
{
RPCHelpMan{"omni_encodeaddress",
"\nReturns the omni address which corresponds to bitcoin one.\n"
"\nThe function is useful to convert bitcoin address to receive Omni tokens.\n"
"\nWARNING: Do not use this function to convert destination address (i.e. when you send tokens)\n"
"\ndestination might be a custodial wallet where private key isn't available\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "bech32 encodded address\n"}
},
RPCResult{
RPCResult::Type::STR, "address", "omni encoded address"
},
RPCExamples{
HelpExampleCli("omni_encodeaddress", "bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl")
+ HelpExampleRpc("omni_encodeaddress", "bc1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl")
}
}.Check(request);

auto dest = DecodeDestination(request.params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_MISC_ERROR, "Address is not valid");
}
if (dest.index() < 3) {
throw JSONRPCError(RPC_MISC_ERROR, "Address needs to be bech32");
}
return EncodeOmniDestination(dest);
}

static UniValue omni_decodeaddress(const JSONRPCRequest& request)
{
RPCHelpMan{"omni_decodeaddress",
"\nReturns the bitcoin address which corresponds to omni one.\n"
"\nThe function is useful to get btc address for omni encoded address.\n"
"\nWARNING: Do not use this function to convert destination address (i.e. when you send tokens)\n"
"\ndestination might be a custodial wallet where private key isn't available\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "bech32 encodded address\n"}
},
RPCResult{
RPCResult::Type::STR, "address", "btc encoded address"
},
RPCExamples{
HelpExampleCli("omni_decodeaddress", "o1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl")
+ HelpExampleRpc("omni_decodeaddress", "o1q09vm5lfy0j5reeulh4x5752q25uqqvz34hufdl")
}
}.Check(request);

auto dest = DecodeOmniDestination(request.params[0].get_str());
if (!IsValidDestination(dest)) {
throw JSONRPCError(RPC_MISC_ERROR, "Address is not valid or not bech32");
}
return EncodeDestination(dest);
}

void RegisterOmniMiscRPCCommands(CRPCTable &t)
{
// clang-format off
Expand All @@ -729,6 +787,8 @@ void RegisterOmniMiscRPCCommands(CRPCTable &t)
{ "util", "getaddressmempool", &getaddressmempool, {"addresses"} },
{ "util", "getblockhashes", &getblockhashes, {"high","low","options"} },
{ "util", "getspentinfo", &getspentinfo, {"argument"} },
{ "util", "omni_encodeaddress", &omni_encodeaddress, {"address"} },
{ "util", "omni_decodeaddress", &omni_decodeaddress, {"address"} },
};
// clang-format on

Expand Down
39 changes: 15 additions & 24 deletions src/omnicore/omnicore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,27 +170,18 @@ std::set<std::string> wallet_addresses;

extern void DoWarning(const bilingual_str& warning);

bool fOmniSafeAddresses = false;

std::string mastercore::strMPProperty(uint32_t propertyId)
{
std::string str = "*unknown*";

// test user-token
if (0x80000000 & propertyId) {
str = strprintf("Test token: %d : 0x%08X", 0x7FFFFFFF & propertyId, propertyId);
return strprintf("Test token: %d : 0x%08X", 0x7FFFFFFF & propertyId, propertyId);
} else {
switch (propertyId) {
case OMNI_PROPERTY_BTC: str = "BTC";
break;
case OMNI_PROPERTY_MSC: str = "OMN";
break;
case OMNI_PROPERTY_TMSC: str = "TOMN";
break;
default:
str = strprintf("SP token: %d", propertyId);
}
return getTokenLabel(propertyId);
}

return str;
return "*unknown*";
}

std::string FormatDivisibleShortMP(int64_t n)
Expand Down Expand Up @@ -428,17 +419,15 @@ bool mastercore::isAddressFrozen(const std::string& address, uint32_t propertyId

std::string mastercore::getTokenLabel(uint32_t propertyId)
{
std::string tokenStr;
if (propertyId < 3) {
if (propertyId == 1) {
tokenStr = " OMNI";
} else {
tokenStr = " TOMNI";
}
} else {
tokenStr = strprintf(" SPT#%d", propertyId);
static const auto isMainnet = MainNet();
switch (propertyId) {
case OMNI_PROPERTY_BTC: return "BTC";
case OMNI_PROPERTY_MSC: return "OMN";
case OMNI_PROPERTY_TMSC: return "TOMN";
case OMNI_PROPERTY_EMAID: if (isMainnet) return "EMAID"; break;
case OMNI_PROPERTY_USDT: if (isMainnet) return "USDT"; break;
}
return tokenStr;
return strprintf("SPT#%d", propertyId);
}

// get total tokens for a property
Expand Down Expand Up @@ -1900,6 +1889,8 @@ int mastercore_init()
PrintToLog("Exodus balance after initialization: %s\n", FormatDivisibleMP(exodus_balance));
}

fOmniSafeAddresses = gArgs.GetBoolArg("-omnisafeaddresses", MainNet());

PrintToConsole("Omni Core initialization completed\n");

return 0;
Expand Down
12 changes: 9 additions & 3 deletions src/omnicore/omnicore.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,11 @@ enum TransactionType {
#define PKT_ERROR_NFT (-85000)
#define PKT_ERROR_SEND_MANY (-86000)

#define OMNI_PROPERTY_BTC 0
#define OMNI_PROPERTY_MSC 1
#define OMNI_PROPERTY_TMSC 2
#define OMNI_PROPERTY_BTC 0
#define OMNI_PROPERTY_MSC 1
#define OMNI_PROPERTY_TMSC 2
#define OMNI_PROPERTY_EMAID 3 // MaidSafeCoin
#define OMNI_PROPERTY_USDT 31 // Tether USD

/** Number formatting related functions. */
std::string FormatDivisibleMP(int64_t amount, bool fSign = false);
Expand Down Expand Up @@ -158,8 +160,12 @@ extern std::map<uint32_t, int64_t> global_balance_reserved;
//! Vector containing a list of properties relative to the wallet
extern std::set<uint32_t> global_wallet_property_list;

extern std::set<std::string> wallet_addresses;

extern CFeeRate minRelayTxFee;

extern bool fOmniSafeAddresses;

extern std::optional<std::reference_wrapper<node::NodeContext>> g_context;

int64_t GetTokenBalance(const std::string& address, uint32_t propertyId, TallyType ttype);
Expand Down
Loading