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

DFIP2203 minted category and txn numbering #1177

Merged
merged 4 commits into from
Mar 31, 2022
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 src/interfaces/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class ChainImpl : public Chain
LOCK(cs_main);
return pcustomcsview->GetMasternode(nodeId);
}
std::unique_ptr<CToken> existTokenGuessId(const std::string & str, DCT_ID & id) const override
boost::optional<CTokensView::CTokenImpl> existTokenGuessId(const std::string & str, DCT_ID & id) const override
{
LOCK(cs_main);
return pcustomcsview->GetTokenGuessId(str, id);
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CFeeRate;
class CMasternode;
class CRPCCommand;
class CScheduler;
class CToken;
class CTokenImplementation;
class CValidationState;
class Coin;
class uint256;
Expand Down Expand Up @@ -152,7 +152,7 @@ class Chain

virtual bool mnCanSpend(const uint256 & nodeId, int height) const = 0;
virtual boost::optional<CMasternode> mnExists(const uint256 & nodeId) const = 0;
virtual std::unique_ptr<CToken> existTokenGuessId(const std::string & str, DCT_ID & id) const = 0;
virtual boost::optional<CTokenImplementation> existTokenGuessId(const std::string & str, DCT_ID & id) const = 0;

//! Estimate fraction of total transactions verified if blocks up to
//! the specified block hash are verified.
Expand Down
20 changes: 12 additions & 8 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ const std::map<uint8_t, std::map<uint8_t, std::string>>& ATTRIBUTES::displayKeys
{EconomyKeys::PaybackDFITokens, "dfi_payback_tokens"},
{EconomyKeys::DFIP2203Current, "dfip2203_current"},
{EconomyKeys::DFIP2203Burned, "dfip2203_burned"},
{EconomyKeys::DFIP2203Minted, "dfip2203_minted"},
}
},
};
Expand Down Expand Up @@ -396,31 +397,34 @@ Res ATTRIBUTES::RefundFuturesContracts(CCustomCSView &mnview, const uint32_t hei
CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Current};
auto balances = GetValue(liveKey, CBalances{});


CHistoryWriters writers{paccountHistoryDB.get(), nullptr, nullptr};
CAccountsHistoryWriter view(mnview, height, ~0u, {}, uint8_t(CustomTxType::FutureSwapRefund), &writers);
auto txn = std::numeric_limits<uint32_t>::max();

for (const auto& [key, value] : userFuturesValues) {
view.EraseFuturesUserValues(key);

auto res = view.SubBalance(*contractAddressValue, value.source);
mnview.EraseFuturesUserValues(key);

CHistoryWriters subWriters{paccountHistoryDB.get(), nullptr, nullptr};
CAccountsHistoryWriter subView(mnview, height, txn--, {}, uint8_t(CustomTxType::FutureSwapRefund), &subWriters);
auto res = subView.SubBalance(*contractAddressValue, value.source);
if (!res) {
return res;
}
subView.Flush();

res = view.AddBalance(key.owner, value.source);
CHistoryWriters addWriters{paccountHistoryDB.get(), nullptr, nullptr};
CAccountsHistoryWriter addView(mnview, height, txn--, {}, uint8_t(CustomTxType::FutureSwapRefund), &addWriters);
res = addView.AddBalance(key.owner, value.source);
if (!res) {
return res;
}
addView.Flush();

res = balances.Sub(value.source);
if (!res) {
return res;
}
}

view.Flush();

attributes[liveKey] = balances;

return Res::Ok();
Expand Down
1 change: 1 addition & 0 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ enum EconomyKeys : uint8_t {
PaybackTokens = 'b',
DFIP2203Current = 'c',
DFIP2203Burned = 'd',
DFIP2203Minted = 'e',
};

enum DFIPKeys : uint8_t {
Expand Down
23 changes: 12 additions & 11 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,24 +1095,25 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
Res operator()(const CMintTokensMessage& obj) const {
// check auth and increase balance of token's owner
for (const auto& kv : obj.balances) {
DCT_ID tokenId = kv.first;
const DCT_ID& tokenId = kv.first;

auto token = mnview.GetToken(kv.first);
auto token = mnview.GetToken(tokenId);
if (!token) {
return Res::Err("token %s does not exist!", tokenId.ToString());
}
auto tokenImpl = static_cast<const CTokenImplementation&>(*token);

auto mintable = MintableToken(tokenId, tokenImpl);
auto mintable = MintableToken(tokenId, *token);
if (!mintable) {
return std::move(mintable);
}
auto minted = mnview.AddMintedTokens(tokenImpl.creationTx, kv.second);

auto minted = mnview.AddMintedTokens(tokenId, kv.second);
if (!minted) {
return minted;
}

CalculateOwnerRewards(*mintable.val);
auto res = mnview.AddBalance(*mintable.val, CTokenAmount{kv.first, kv.second});
auto res = mnview.AddBalance(*mintable.val, CTokenAmount{tokenId, kv.second});
if (!res) {
return res;
}
Expand Down Expand Up @@ -2786,7 +2787,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
{
if (auto collaterals = mnview.GetVaultCollaterals(obj.vaultId))
{
boost::optional<std::pair<DCT_ID, std::unique_ptr<CToken>>> tokenDUSD;
boost::optional<std::pair<DCT_ID, boost::optional<CTokensView::CTokenImpl>>> tokenDUSD;
if (static_cast<int>(height) >= consensus.FortCanningRoadHeight) {
tokenDUSD = mnview.GetToken("DUSD");
}
Expand Down Expand Up @@ -2852,7 +2853,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
uint64_t totalLoansActivePrice = 0, totalLoansNextPrice = 0;
for (const auto& kv : obj.amounts.balances)
{
DCT_ID tokenId = kv.first;
const DCT_ID& tokenId = kv.first;
auto loanToken = mnview.GetLoanTokenByID(tokenId);
if (!loanToken)
return Res::Err("Loan token with id (%s) does not exist!", tokenId.ToString());
Expand Down Expand Up @@ -2892,7 +2893,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return Res::Err("Exceed maximum loans");
}

res = mnview.AddMintedTokens(loanToken->creationTx, kv.second);
res = mnview.AddMintedTokens(tokenId, kv.second);
if (!res)
return res;

Expand All @@ -2904,7 +2905,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return res;
}

boost::optional<std::pair<DCT_ID, std::unique_ptr<CToken>>> tokenDUSD;
boost::optional<std::pair<DCT_ID, boost::optional<CTokensView::CTokenImpl>>> tokenDUSD;
if (static_cast<int>(height) >= consensus.FortCanningRoadHeight) {
tokenDUSD = mnview.GetToken("DUSD");
}
Expand Down Expand Up @@ -3118,7 +3119,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor

if (paybackTokenId == loanTokenId)
{
res = mnview.SubMintedTokens(loanToken->creationTx, subLoan);
res = mnview.SubMintedTokens(loanTokenId, subLoan);
if (!res)
return res;

Expand Down
5 changes: 2 additions & 3 deletions src/masternodes/rpc_icxorderbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,10 @@ UniValue icxcreateorder(const JSONRPCRequest& request) {
{
LOCK(cs_main);
DCT_ID idToken;
std::unique_ptr<CToken> token;

if (order.orderType == CICXOrder::TYPE_INTERNAL)
{
token = pcustomcsview->GetTokenGuessId(tokenFromSymbol, idToken);
auto token = pcustomcsview->GetTokenGuessId(tokenFromSymbol, idToken);
if (!token)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Token %s does not exist!", tokenFromSymbol));
order.idToken = idToken;
Expand All @@ -303,7 +302,7 @@ UniValue icxcreateorder(const JSONRPCRequest& request) {
}
else
{
token = pcustomcsview->GetTokenGuessId(tokenToSymbol, idToken);
auto token = pcustomcsview->GetTokenGuessId(tokenToSymbol, idToken);
if (!token)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Token %s does not exist!", tokenToSymbol));
order.idToken = idToken;
Expand Down
5 changes: 2 additions & 3 deletions src/masternodes/rpc_loan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ UniValue setLoanTokenToJSON(CLoanSetLoanTokenImplementation const& loanToken, DC
if (!token)
return (UniValue::VNULL);

loanTokenObj.pushKV("token", tokenToJSON(tokenId, *static_cast<CTokenImplementation*>(token.get()), true));
loanTokenObj.pushKV("token", tokenToJSON(tokenId, *token, true));
loanTokenObj.pushKV("fixedIntervalPriceId", loanToken.fixedIntervalPriceId.first + "/" + loanToken.fixedIntervalPriceId.second);
loanTokenObj.pushKV("interest", ValueFromAmount(loanToken.interest));

Expand Down Expand Up @@ -131,9 +131,8 @@ UniValue setcollateraltoken(const JSONRPCRequest& request) {
LOCK(cs_main);

DCT_ID idToken;
std::unique_ptr<CToken> token;

token = pcustomcsview->GetTokenGuessId(tokenSymbol, idToken);
auto token = pcustomcsview->GetTokenGuessId(tokenSymbol, idToken);
if (!token)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Token %s does not exist!", tokenSymbol));
collToken.idToken = idToken;
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/rpc_tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ UniValue gettoken(const JSONRPCRequest& request) {
DCT_ID id;
auto token = pcustomcsview->GetTokenGuessId(request.params[0].getValStr(), id);
if (token) {
return tokenToJSON(id, *static_cast<CTokenImplementation*>(token.get()), true);
return tokenToJSON(id, *token, true);
}
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Token not found");
}
Expand Down
48 changes: 21 additions & 27 deletions src/masternodes/tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@ std::string trim_ws(std::string const & str)
return str.substr(first, (last - first + 1));
}

std::unique_ptr<CToken> CTokensView::GetToken(DCT_ID id) const
boost::optional<CTokensView::CTokenImpl> CTokensView::GetToken(DCT_ID id) const
{
if (auto tokenImpl = ReadBy<ID, CTokenImpl>(id)) {
return MakeUnique<CTokenImpl>(*tokenImpl);
}

return {};
return ReadBy<ID, CTokenImpl>(id);
}

boost::optional<std::pair<DCT_ID, std::unique_ptr<CToken> > > CTokensView::GetToken(const std::string & symbolKey) const
boost::optional<std::pair<DCT_ID, boost::optional<CTokensView::CTokenImpl>>> CTokensView::GetToken(const std::string & symbolKey) const
{
DCT_ID id;
if (ReadBy<Symbol, std::string>(symbolKey, id)) {
Expand All @@ -55,7 +51,7 @@ boost::optional<std::pair<DCT_ID, CTokensView::CTokenImpl> > CTokensView::GetTok
return {};
}

std::unique_ptr<CToken> CTokensView::GetTokenGuessId(const std::string & str, DCT_ID & id) const
boost::optional<CTokensView::CTokenImpl> CTokensView::GetTokenGuessId(const std::string & str, DCT_ID & id) const
{
std::string const key = trim_ws(str);

Expand All @@ -71,13 +67,13 @@ std::unique_ptr<CToken> CTokensView::GetTokenGuessId(const std::string & str, DC
auto pair = GetTokenByCreationTx(tx);
if (pair) {
id = pair->first;
return MakeUnique<CTokenImpl>(pair->second);
return pair->second;
}
} else {
auto pair = GetToken(key);
if (pair) {
id = pair->first;
return std::move(pair->second);
return pair->second;
}
}
return {};
Expand Down Expand Up @@ -245,39 +241,37 @@ Res CTokensView::BayfrontFlagsCleanup()
return Res::Ok();
}

Res CTokensView::AddMintedTokens(const uint256 &tokenTx, CAmount const & amount)
Res CTokensView::AddMintedTokens(DCT_ID const &id, CAmount const & amount)
{
auto pair = GetTokenByCreationTx(tokenTx);
if (!pair) {
return Res::Err("token with creationTx %s does not exist!", tokenTx.ToString());
auto tokenImpl = GetToken(id);
if (!tokenImpl) {
return Res::Err("token with id %d does not exist!", id.v);
}
CTokenImpl & tokenImpl = pair->second;

auto resMinted = SafeAdd(tokenImpl.minted, amount);
if (!resMinted.ok) {
auto resMinted = SafeAdd(tokenImpl->minted, amount);
if (!resMinted) {
return Res::Err("overflow when adding to minted");
}
tokenImpl.minted = *resMinted.val;
tokenImpl->minted = resMinted;

WriteBy<ID>(pair->first, tokenImpl);
WriteBy<ID>(id, *tokenImpl);
return Res::Ok();
}

Res CTokensView::SubMintedTokens(const uint256 &tokenTx, CAmount const & amount)
Res CTokensView::SubMintedTokens(DCT_ID const &id, CAmount const & amount)
{
auto pair = GetTokenByCreationTx(tokenTx);
if (!pair) {
return Res::Err("token with creationTx %s does not exist!", tokenTx.ToString());
auto tokenImpl = GetToken(id);
if (!tokenImpl) {
return Res::Err("token with id %d does not exist!", id.v);
}
CTokenImpl & tokenImpl = pair->second;

auto resMinted = tokenImpl.minted - amount;
auto resMinted = tokenImpl->minted - amount;
if (resMinted < 0) {
return Res::Err("not enough tokens exist to subtract this amount");
}
tokenImpl.minted = resMinted;
tokenImpl->minted = resMinted;

WriteBy<ID>(pair->first, tokenImpl);
WriteBy<ID>(id, *tokenImpl);
return Res::Ok();
}

Expand Down
10 changes: 5 additions & 5 deletions src/masternodes/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ class CTokensView : public virtual CStorageView
static const unsigned char DB_TOKEN_LASTID; // = 'L';

using CTokenImpl = CTokenImplementation;
std::unique_ptr<CToken> GetToken(DCT_ID id) const;
boost::optional<std::pair<DCT_ID, std::unique_ptr<CToken>>> GetToken(std::string const & symbol) const;
boost::optional<CTokenImpl> GetToken(DCT_ID id) const;
boost::optional<std::pair<DCT_ID, boost::optional<CTokensView::CTokenImpl>>> GetToken(std::string const & symbol) const;
// the only possible type of token (with creationTx) is CTokenImpl
boost::optional<std::pair<DCT_ID, CTokenImpl>> GetTokenByCreationTx(uint256 const & txid) const;
std::unique_ptr<CToken> GetTokenGuessId(const std::string & str, DCT_ID & id) const;
boost::optional<CTokensView::CTokenImpl> GetTokenGuessId(const std::string & str, DCT_ID & id) const;

void ForEachToken(std::function<bool(DCT_ID const &, CLazySerialize<CTokenImpl>)> callback, DCT_ID const & start = DCT_ID{0});

Expand All @@ -156,8 +156,8 @@ class CTokensView : public virtual CStorageView
Res UpdateToken(uint256 const & tokenTx, CToken const & newToken, bool isPreBayfront);

Res BayfrontFlagsCleanup();
Res AddMintedTokens(uint256 const & tokenTx, CAmount const & amount);
Res SubMintedTokens(uint256 const & tokenTx, CAmount const & amount);
Res AddMintedTokens(DCT_ID const & id, CAmount const & amount);
Res SubMintedTokens(DCT_ID const & id, CAmount const & amount);

// tags
struct ID { static constexpr uint8_t prefix() { return 'T'; } };
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/rawtransaction_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ ResVal<CTokenAmount> GuessTokenAmount(interfaces::Chain const & chain, std::stri
return {{tokenId, parsed.val->first}, Res::Ok()};
} catch (...) {
// assuming it's token symbol, read DCT_ID from DB
std::unique_ptr<CToken> token = chain.existTokenGuessId(parsed.val->second, tokenId);
auto token = chain.existTokenGuessId(parsed.val->second, tokenId);
if (!token) {
return Res::Err("Invalid Defi token: %s", parsed.val->second);
}
Expand Down
Loading