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

Oracle development #287

Merged
merged 4 commits into from
Apr 21, 2021
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
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ AX_BOOST_CHRONO
dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic
dnl counter implementations. In 1.63 and later the std::atomic approach is default.
m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro
BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS"
BOOST_CPPFLAGS="-DBOOST_MPL_CFG_NO_PREPROCESSED_HEADERS -DBOOST_MPL_LIMIT_LIST_SIZE=50 -DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS"

if test x$use_reduce_exports = xyes; then
AC_MSG_CHECKING([for working boost reduced exports])
Expand Down
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ DEFI_CORE_H = \
masternodes/poolpairs.h \
masternodes/undo.h \
masternodes/undos.h \
masternodes/oracles.h \
memusage.h \
merkleblock.h \
miner.h \
Expand Down Expand Up @@ -366,6 +367,7 @@ libdefi_server_a_SOURCES = \
masternodes/accountshistory.cpp \
masternodes/anchors.cpp \
masternodes/criminals.cpp \
masternodes/oracles.cpp \
masternodes/govvariables/lp_daily_dfi_reward.cpp \
masternodes/govvariables/lp_splits.cpp \
masternodes/gv.cpp \
Expand All @@ -378,6 +380,7 @@ libdefi_server_a_SOURCES = \
masternodes/rpc_masternodes.cpp \
masternodes/rpc_tokens.cpp \
masternodes/rpc_poolpair.cpp \
masternodes/rpc_oracles.cpp \
masternodes/tokens.cpp \
masternodes/poolpairs.cpp \
masternodes/undos.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ DEFI_TESTS =\
test/multisig_tests.cpp \
test/net_tests.cpp \
test/netbase_tests.cpp \
test/oracles_tests.cpp \
test/pmt_tests.cpp \
test/policyestimator_tests.cpp \
test/pow_tests.cpp \
Expand Down
6 changes: 1 addition & 5 deletions src/amount.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,7 @@ struct CTokenAmount { // simple std::pair is less informative
CAmount nValue;

std::string ToString() const {
const bool sign = nValue < 0;
const int64_t n_abs = (sign ? -nValue : nValue);
const int64_t quotient = n_abs / COIN;
const int64_t remainder = n_abs % COIN;
return strprintf("%s%d.%08d@%d", sign ? "-" : "", quotient, remainder, nTokenId.v);
return strprintf("%s@%d", GetDecimaleString(nValue), nTokenId.v);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on this change?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate code in GetDecimaleString

}

Res Add(CAmount amount) {
Expand Down
6 changes: 3 additions & 3 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,9 @@ class CDevNetParams : public CChainParams {
consensus.BayfrontMarinaHeight = 0;
consensus.BayfrontGardensHeight = 0;
consensus.ClarkeQuayHeight = 0;
consensus.DakotaHeight = 0;
consensus.DakotaCrescentHeight = 0;
consensus.EunosHeight = 0;
consensus.DakotaHeight = 10;
consensus.DakotaCrescentHeight = 10;
consensus.EunosHeight = 10;

consensus.pos.diffLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.pos.nTargetTimespan = 5 * 60; // 5 min == 10 blocks
Expand Down
2 changes: 2 additions & 0 deletions src/masternodes/masternodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <masternodes/tokens.h>
#include <masternodes/undos.h>
#include <masternodes/poolpairs.h>
#include <masternodes/oracles.h>
#include <masternodes/gv.h>
#include <uint256.h>
#include <wallet/ismine.h>
Expand Down Expand Up @@ -244,6 +245,7 @@ class CCustomCSView
, public CPoolPairView
, public CGovView
, public CAnchorConfirmsView
, public COracleView
{
public:
// Increase version when underlaying tables are changed
Expand Down
103 changes: 94 additions & 9 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <masternodes/anchors.h>
#include <masternodes/balances.h>
#include <masternodes/mn_checks.h>
#include <masternodes/oracles.h>
#include <masternodes/res.h>

#include <arith_uint256.h>
Expand All @@ -21,8 +22,6 @@
#include <validation.h>

#include <algorithm>
#include <sstream>
#include <cstring>

using namespace std;

Expand All @@ -45,9 +44,14 @@ std::string ToString(CustomTxType type) {
case CustomTxType::AccountToAccount: return "AccountToAccount";
case CustomTxType::AnyAccountsToAccounts: return "AnyAccountsToAccounts";
case CustomTxType::SetGovVariable: return "SetGovVariable";
case CustomTxType::AppointOracle: return "AppointOracle";
case CustomTxType::RemoveOracleAppoint: return "RemoveOracleAppoint";
case CustomTxType::UpdateOracleAppoint: return "UpdateOracleAppoint";
case CustomTxType::SetOracleData: return "SetOracleData";
case CustomTxType::AutoAuthPrep: return "AutoAuth";
default: return "None";
case CustomTxType::None: return "None";
}
return "None";
}

static ResVal<CBalances> BurntTokens(CTransaction const & tx) {
Expand Down Expand Up @@ -108,8 +112,14 @@ CCustomTxMessage customTypeToMessage(CustomTxType txType) {
case CustomTxType::AccountToAccount: return CAccountToAccountMessage{};
case CustomTxType::AnyAccountsToAccounts: return CAnyAccountsToAccountsMessage{};
case CustomTxType::SetGovVariable: return CGovernanceMessage{};
default: return CCustomTxMessageNone{};
}
case CustomTxType::AppointOracle: return CAppointOracleMessage{};
case CustomTxType::RemoveOracleAppoint: return CRemoveOracleAppointMessage{};
case CustomTxType::UpdateOracleAppoint: return CUpdateOracleAppointMessage{};
case CustomTxType::SetOracleData: return CSetOracleDataMessage{};
case CustomTxType::AutoAuthPrep: return CCustomTxMessageNone{};
case CustomTxType::None: return CCustomTxMessageNone{};
}
return CCustomTxMessageNone{};
}

extern std::string ScriptToString(CScript const& script);
Expand Down Expand Up @@ -141,6 +151,13 @@ class CCustomMetadataParseVisitor : public boost::static_visitor<Res>
return Res::Ok();
}

Res isPostEunosFork() const {
if(static_cast<int>(height) < consensus.EunosHeight) {
return Res::Err("called before Eunos height");
}
return Res::Ok();
}

template<typename T>
Res serialize(T& obj) const {
CDataStream ss(metadata, SER_NETWORK, PROTOCOL_VERSION);
Expand Down Expand Up @@ -292,6 +309,26 @@ class CCustomMetadataParseVisitor : public boost::static_visitor<Res>
return Res::Ok();
}

Res operator()(CAppointOracleMessage& obj) const {
auto res = isPostEunosFork();
return !res ? res : serialize(obj);
}

Res operator()(CRemoveOracleAppointMessage& obj) const {
auto res = isPostEunosFork();
return !res ? res : serialize(obj);
}

Res operator()(CUpdateOracleAppointMessage& obj) const {
auto res = isPostEunosFork();
return !res ? res : serialize(obj);
}

Res operator()(CSetOracleDataMessage& obj) const {
auto res = isPostEunosFork();
return !res ? res : serialize(obj);
}

Res operator()(CCustomTxMessageNone&) const {
return Res::Ok();
}
Expand Down Expand Up @@ -485,6 +522,20 @@ class CCustomTxVisitor : public boost::static_visitor<Res>
}
return Res::Ok();
}

Res normalizeTokenCurrencyPair(std::set<CTokenCurrencyPair>& tokenCurrency) const {
std::set<CTokenCurrencyPair> trimmed;
for (const auto& pair : tokenCurrency) {
auto token = trim_ws(pair.first).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
auto currency = trim_ws(pair.second).substr(0, CToken::MAX_TOKEN_SYMBOL_LENGTH);
if (token.empty() || currency.empty()) {
return Res::Err("empty token / currency");
}
trimmed.emplace(token, currency);
}
tokenCurrency = std::move(trimmed);
return Res::Ok();
}
};

class CCustomTxApplyVisitor : public CCustomTxVisitor
Expand Down Expand Up @@ -941,6 +992,43 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return Res::Ok();
}

Res operator()(const CAppointOracleMessage& obj) const {
if (!HasFoundationAuth()) {
return Res::Err("tx not from foundation member");
}
auto msg = obj;
auto res = normalizeTokenCurrencyPair(msg.availablePairs);
return !res ? res : mnview.AppointOracle(tx.GetHash(), COracle(msg));
}

Res operator()(const CUpdateOracleAppointMessage& obj) const {
if (!HasFoundationAuth()) {
return Res::Err("tx not from foundation member");
}
auto msg = obj.newOracleAppoint;
auto res = normalizeTokenCurrencyPair(msg.availablePairs);
return !res ? res : mnview.UpdateOracle(obj.oracleId, COracle(msg));
}

Res operator()(const CRemoveOracleAppointMessage& obj) const {
if (!HasFoundationAuth()) {
return Res::Err("tx not from foundation member");
}
return mnview.RemoveOracle(obj.oracleId);
}

Res operator()(const CSetOracleDataMessage& obj) const {

auto oracle = mnview.GetOracleData(obj.oracleId);
if (!oracle) {
return Res::Err("failed to retrieve oracle <%s> from database", obj.oracleId.GetHex());
}
if (!HasAuth(oracle.val->oracleAddress)) {
return Res::Err("tx must have at least one input from account owner");
}
return mnview.SetOracleData(obj.oracleId, obj.timestamp, obj.tokenPrices);
}

Res operator()(const CCustomTxMessageNone&) const {
return Res::Ok();
}
Expand Down Expand Up @@ -1235,7 +1323,6 @@ ResVal<uint256> ApplyAnchorRewardTx(CCustomCSView & mnview, CTransaction const &
return { finMsg.btcTxHash, Res::Ok() };
}


ResVal<uint256> ApplyAnchorRewardTxPlus(CCustomCSView & mnview, CTransaction const & tx, int height, std::vector<unsigned char> const & metadata, Consensus::Params const & consensusParams)
{
if (height < consensusParams.DakotaHeight) {
Expand Down Expand Up @@ -1304,9 +1391,7 @@ ResVal<uint256> ApplyAnchorRewardTxPlus(CCustomCSView & mnview, CTransaction con
return { finMsg.btcTxHash, Res::Ok() };
}


bool IsMempooledCustomTxCreate(const CTxMemPool & pool, const uint256 & txid)
{
bool IsMempooledCustomTxCreate(const CTxMemPool &pool, const uint256 &txid) {
CTransactionRef ptx = pool.get(txid);
if (ptx) {
std::vector<unsigned char> dummy;
Expand Down
85 changes: 60 additions & 25 deletions src/masternodes/mn_checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,71 @@ enum CustomTxErrCodes : uint32_t {
Fatal = uint32_t(1) << 31 // not allowed to fail
};

enum class CustomTxType : unsigned char
enum class CustomTxType : uint8_t
{
None = 0,
// masternodes:
CreateMasternode = 'C',
ResignMasternode = 'R',
CreateMasternode = 'C',
ResignMasternode = 'R',
// custom tokens:
CreateToken = 'T',
MintToken = 'M',
UpdateToken = 'N', // previous type, only DAT flag triggers
UpdateTokenAny = 'n', // new type of token's update with any flags/fields possible
CreateToken = 'T',
MintToken = 'M',
UpdateToken = 'N', // previous type, only DAT flag triggers
UpdateTokenAny = 'n', // new type of token's update with any flags/fields possible
// dex orders - just not to overlap in future
// CreateOrder = 'O',
// DestroyOrder = 'E',
// MatchOrders = 'A',
//poolpair
CreatePoolPair = 'p',
UpdatePoolPair = 'u',
PoolSwap = 's',
AddPoolLiquidity = 'l',
RemovePoolLiquidity = 'r',
CreatePoolPair = 'p',
UpdatePoolPair = 'u',
PoolSwap = 's',
AddPoolLiquidity = 'l',
RemovePoolLiquidity = 'r',
// accounts
UtxosToAccount = 'U',
AccountToUtxos = 'b',
AccountToAccount = 'B',
AnyAccountsToAccounts = 'a',
UtxosToAccount = 'U',
AccountToUtxos = 'b',
AccountToAccount = 'B',
AnyAccountsToAccounts = 'a',
//set governance variable
SetGovVariable = 'G',
SetGovVariable = 'G',
// Auto auth TX
AutoAuthPrep = 'A',
AutoAuthPrep = 'A',
// oracles
AppointOracle = 'o',
RemoveOracleAppoint = 'h',
UpdateOracleAppoint = 't',
SetOracleData = 'y',
};

inline CustomTxType CustomTxCodeToType(unsigned char ch) {
constexpr const char txtypes[] = "CRTMNnpuslrUbBaGA";
if (memchr(txtypes, ch, sizeof(txtypes) - 1))
return static_cast<CustomTxType>(ch);
else
return CustomTxType::None;
inline CustomTxType CustomTxCodeToType(uint8_t ch) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will need to keep in mind this refactoring for the other PRs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bvbfan do you suggest we keep this change or revert to how it was before?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add ohty in txtypes say CRTMNnpuslrUbBaGAohty so refactor is better, i think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think so too, it's cleaner, ok approving this

auto type = static_cast<CustomTxType>(ch);
switch(type) {
case CustomTxType::CreateMasternode:
case CustomTxType::ResignMasternode:
case CustomTxType::CreateToken:
case CustomTxType::MintToken:
case CustomTxType::UpdateToken:
case CustomTxType::UpdateTokenAny:
case CustomTxType::CreatePoolPair:
case CustomTxType::UpdatePoolPair:
case CustomTxType::PoolSwap:
case CustomTxType::AddPoolLiquidity:
case CustomTxType::RemovePoolLiquidity:
case CustomTxType::UtxosToAccount:
case CustomTxType::AccountToUtxos:
case CustomTxType::AccountToAccount:
case CustomTxType::AnyAccountsToAccounts:
case CustomTxType::SetGovVariable:
case CustomTxType::AutoAuthPrep:
case CustomTxType::AppointOracle:
case CustomTxType::RemoveOracleAppoint:
case CustomTxType::UpdateOracleAppoint:
case CustomTxType::SetOracleData:
case CustomTxType::None:
return type;
}
return CustomTxType::None;
}

std::string ToString(CustomTxType type);
Expand Down Expand Up @@ -99,6 +126,10 @@ struct CLiquidityMessage;
struct CPoolSwapMessage;
struct CRemoveLiquidityMessage;
struct CUtxosToAccountMessage;
struct CAppointOracleMessage;
struct CRemoveOracleAppointMessage;
struct CUpdateOracleAppointMessage;
struct CSetOracleDataMessage;

struct CCreateMasterNodeMessage {
char operatorType;
Expand Down Expand Up @@ -203,7 +234,11 @@ typedef boost::variant<
CAccountToUtxosMessage,
CAccountToAccountMessage,
CAnyAccountsToAccountsMessage,
CGovernanceMessage
CGovernanceMessage,
CAppointOracleMessage,
CRemoveOracleAppointMessage,
CUpdateOracleAppointMessage,
CSetOracleDataMessage
> CCustomTxMessage;

CCustomTxMessage customTypeToMessage(CustomTxType txType);
Expand Down
Loading