Skip to content

Commit

Permalink
Fix accounting of burntoken tx in getburninfo (#1659)
Browse files Browse the repository at this point in the history
* Fix accounting of burntoken tx in getburninfo. Make 'from' as optional when consortium member burning.

* Resolve comment

* Change error response

Co-authored-by: Shoham Chakraborty <[email protected]>

* Fix test

Co-authored-by: Shoham Chakraborty <[email protected]>
Co-authored-by: Prasanna Loganathar <[email protected]>
  • Loading branch information
3 people authored Jan 4, 2023
1 parent 4acdcb0 commit 90c05a0
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 13 deletions.
16 changes: 15 additions & 1 deletion src/masternodes/rpc_accounts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,7 @@ UniValue getburninfo(const JSONRPCRequest& request) {

CBalances burntTokens;
CBalances consortiumTokens;
CBalances nonConsortiumTokens;
CBalances dexfeeburn;
CBalances paybackfees;
CBalances paybackFee;
Expand Down Expand Up @@ -1905,7 +1906,7 @@ UniValue getburninfo(const JSONRPCRequest& request) {
if (value.category == uint8_t(CustomTxType::BurnToken))
{
for (auto const & diff : value.diff) {
consortiumTokens.Add({diff.first, diff.second});
nonConsortiumTokens.Add({diff.first, diff.second});
}
return true;
}
Expand All @@ -1919,6 +1920,19 @@ UniValue getburninfo(const JSONRPCRequest& request) {

burnView->ForEachAccountHistory(calculateBurnAmounts);

CDataStructureV0 liveKey = {AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::ConsortiumMinted};
auto balances = attributes->GetValue(liveKey, CConsortiumGlobalMinted{});

for (auto const & token: nonConsortiumTokens.balances)
{
TAmounts amount;
amount[token.first] = balances[token.first].burnt;
consortiumTokens.AddBalances(amount);
}

nonConsortiumTokens.SubBalances(consortiumTokens.balances);
burntTokens.AddBalances(nonConsortiumTokens.balances);

UniValue result(UniValue::VOBJ);
result.pushKV("address", ScriptToString(burnAddress));
result.pushKV("amount", ValueFromAmount(burntDFI));
Expand Down
43 changes: 34 additions & 9 deletions src/masternodes/rpc_tokens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ UniValue burntokens(const JSONRPCRequest& request) {
{"metadata", RPCArg::Type::OBJ, RPCArg::Optional::NO, "",
{
{"amounts", RPCArg::Type::STR, RPCArg::Optional::NO, "Amount as json string, or array. Example: '[ \"amount@token\" ]'"},
{"from", RPCArg::Type::STR, RPCArg::Optional::NO, "Address containing tokens to be burned."},
{"from", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Address containing tokens to be burned."},
{"context", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Additional data necessary for specific burn type"},
}
},
Expand Down Expand Up @@ -841,18 +841,43 @@ UniValue burntokens(const JSONRPCRequest& request) {
CBurnTokensMessage burnedTokens;
UniValue metaObj = request.params[0].get_obj();

burnedTokens.burnType = CBurnTokensMessage::BurnType::TokenBurn;

if (!metaObj["amounts"].isNull())
burnedTokens.amounts = DecodeAmounts(pwallet->chain(), metaObj["amounts"].getValStr(), "");
else
throw JSONRPCError(RPC_INVALID_PARAMETER,"Invalid parameters, argument \"amounts\" must not be null");
if (!metaObj["from"].isNull())
burnedTokens.from = DecodeScript(metaObj["from"].getValStr());
else
throw JSONRPCError(RPC_INVALID_PARAMETER,"Invalid parameters, argument \"from\" must not be null");
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters, argument \"amounts\" must not be null");

if (burnedTokens.amounts.balances.size() == 1 && metaObj["from"].isNull() && metaObj["context"].isNull()) {
auto attributes = pcustomcsview->GetAttributes();

if (attributes) {
CDataStructureV0 enableKey{AttributeTypes::Param, ParamIDs::Feature, DFIPKeys::ConsortiumEnabled};
if (attributes->GetValue(enableKey, false)) {
CDataStructureV0 membersKey{AttributeTypes::Consortium,
burnedTokens.amounts.balances.begin()->first.v,
ConsortiumKeys::MemberValues};
auto members = attributes->GetValue(membersKey, CConsortiumMembers{});

for (const auto &member : members) {
if (IsMineCached(*pwallet, member.second.ownerAddress)) {
burnedTokens.from = member.second.ownerAddress;
break;
}
}
}
}
if (burnedTokens.from.empty())
throw JSONRPCError(RPC_INVALID_PARAMETER, "No valid addresses could be found, use the \"from\" argument to set address to burn from");
} else {
if (!metaObj["from"].isNull())
burnedTokens.from = DecodeScript(metaObj["from"].getValStr());
else
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters, argument \"from\" must not be null");

burnedTokens.burnType = CBurnTokensMessage::BurnType::TokenBurn;
if (!metaObj["context"].isNull())
burnedTokens.context = DecodeScript(metaObj["context"].getValStr());
if (!metaObj["context"].isNull())
burnedTokens.context = DecodeScript(metaObj["context"].getValStr());
}

UniValue const & txInputs = request.params[2];

Expand Down
15 changes: 12 additions & 3 deletions test/functional/feature_consortium.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ def run_test(self):
self.nodes[0].generate(1)
self.sync_blocks()

self.nodes[0].minttokens(["2@" + symbolBTC])

self.nodes[0].createtoken({
"symbol": symbolDOGE,
"name": "DOGE token",
Expand Down Expand Up @@ -217,10 +219,15 @@ def run_test(self):
assert_equal(attribs['v0/live/economy/consortium_members/2/01/supply'], Decimal('2.00000000'))

assert_raises_rpc_error(-32600, "You will exceed your maximum mint limit for " + symbolDOGE + " token by minting this amount!", self.nodes[2].minttokens, ["3.00000001@" + symbolDOGE])
assert_raises_rpc_error(-8, "No valid addresses could be found, use the \"from\" argument to set address to burn from", self.nodes[0].burntokens, {'amounts': "1.00000000@" + symbolBTC})

self.nodes[0].burntokens({
'amounts': "2@" + symbolBTC,
'from': account0,
})

self.nodes[2].burntokens({
'amounts': "1@" + symbolDOGE,
'from': account2,
})

self.nodes[2].generate(1)
Expand Down Expand Up @@ -314,7 +321,7 @@ def run_test(self):

attribs = self.nodes[0].getgov('ATTRIBUTES')['ATTRIBUTES']
assert_equal(attribs['v0/consortium/' + idDOGE + '/members'], {"01":{"name":"account2DOGE","ownerAddress": account2,"backingId":"ebf634ef7143bc5466995a385b842649b2037ea89d04d469bfa5ec29daf7d1cf","mintLimit":Decimal('5.00000000'),"mintLimitDaily":Decimal('5.00000000'),"status":1},"02":{"name":"account1DOGE","ownerAddress": account1,"backingId":"ebf634ef7143bc5466995a385b842649b2037ea89d04d469bfa5ec29daf7d1cf","mintLimit":Decimal('5.00000000'),"mintLimitDaily":Decimal('5.00000000'),"status":0}})
assert_equal(self.nodes[0].getburninfo(), {'address': 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG', 'amount': Decimal('0E-8'), 'tokens': [], 'consortiumtokens': ['2.00000000@DOGE'], 'feeburn': Decimal('2.00000000'), 'auctionburn': Decimal('0E-8'), 'paybackburn': [], 'dexfeetokens': [], 'dfipaybackfee': Decimal('0E-8'), 'dfipaybacktokens': [], 'paybackfees': [], 'paybacktokens': [], 'emissionburn': Decimal('4923.76500000'), 'dfip2203': [], 'dfip2206f': []})
assert_equal(self.nodes[0].getburninfo(), {'address': 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG', 'amount': Decimal('0E-8'), 'tokens': ['2.00000000@BTC', '0.50000000@DOGE'], 'consortiumtokens': ['1.50000000@DOGE'], 'feeburn': Decimal('2.00000000'), 'auctionburn': Decimal('0E-8'), 'paybackburn': [], 'dexfeetokens': [], 'dfipaybackfee': Decimal('0E-8'), 'dfipaybacktokens': [], 'paybackfees': [], 'paybacktokens': [], 'emissionburn': Decimal('4923.76500000'), 'dfip2203': [], 'dfip2206f': []})

assert_raises_rpc_error(-32600, "Cannot mint token, not an active member of consortium for DOGE!", self.nodes[2].minttokens, ["1@" + symbolDOGE])

Expand All @@ -330,7 +337,6 @@ def run_test(self):
# burn to check that total minted is checked against max limit
self.nodes[2].burntokens({
'amounts': "6@" + symbolBTC,
'from': account2,
})
self.nodes[2].generate(1)
self.sync_blocks()
Expand Down Expand Up @@ -418,6 +424,7 @@ def run_test(self):
assert_raises_rpc_error(-32600, "You will exceed your daily mint limit for " + symbolBTC + " token by minting this amount", self.nodes[3].minttokens, ["1@" + symbolBTC])

# burn to check that burning from address of a member for different token does not get counted when burning other tokens
assert_raises_rpc_error(-8, "No valid addresses could be found, use the \"from\" argument to set address to burn from", self.nodes[1].burntokens, {'amounts': "0.10000000@" + symbolBTC})
self.nodes[1].burntokens({
'amounts': "0.1@" + symbolBTC,
'from': account1,
Expand Down Expand Up @@ -526,6 +533,8 @@ def run_test(self):
assert_raises_rpc_error(-5, "Amount must be positive or -1", self.nodes[0].setgov, {
"ATTRIBUTES": {'v0/consortium/' + idBTC + '/mint_limit': '-2'}})

assert_equal(self.nodes[0].getburninfo(), {'address': 'mfburnZSAM7Gs1hpDeNaMotJXSGA7edosG', 'amount': Decimal('0E-8'), 'tokens': ['2.10000000@BTC', '0.50000000@DOGE'], 'consortiumtokens': ['6.10000000@BTC', '1.50000000@DOGE'], 'feeburn': Decimal('2.00000000'), 'auctionburn': Decimal('0E-8'), 'paybackburn': [], 'dexfeetokens': [], 'dfipaybackfee': Decimal('0E-8'), 'dfipaybacktokens': [], 'paybackfees': [], 'paybacktokens': [], 'emissionburn': Decimal('5386.81500000'), 'dfip2203': [], 'dfip2206f': []})

# Price feeds
price_feed = [
{"currency": "USD", "token": "TSLA"},
Expand Down

0 comments on commit 90c05a0

Please sign in to comment.