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

ICX hardfork fixes #599

Merged
merged 14 commits into from
Jul 9, 2021
30 changes: 30 additions & 0 deletions src/masternodes/icxorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,21 @@ std::unique_ptr<CICXOrderView::CICXSubmitDFCHTLCImpl> CICXOrderView::HasICXSubmi
return {};
}

bool CICXOrderView::ExistedICXSubmitDFCHTLC(uint256 const & offertxid, bool isPreEunosPaya)
{
bool result = false;

if (HasICXSubmitDFCHTLCOpen(offertxid))
result = true;
if (isPreEunosPaya)
return (result);
auto it = LowerBound<ICXSubmitDFCHTLCCloseKey>(TxidPairKey{offertxid, {}});
if (it.Valid() && it.Key().first == offertxid)
result = true;

return (result);
}

std::unique_ptr<CICXOrderView::CICXSubmitEXTHTLCImpl> CICXOrderView::GetICXSubmitEXTHTLCByCreationTx(const uint256 & txid) const
{
auto submitexthtlc = ReadBy<ICXSubmitEXTHTLCCreationTx,CICXSubmitEXTHTLCImpl>(txid);
Expand Down Expand Up @@ -358,6 +373,21 @@ std::unique_ptr<CICXOrderView::CICXSubmitEXTHTLCImpl> CICXOrderView::HasICXSubmi
return {};
}

bool CICXOrderView::ExistedICXSubmitEXTHTLC(uint256 const & offertxid, bool isPreEunosPaya)
{
bool result = false;

if (HasICXSubmitEXTHTLCOpen(offertxid))
result = true;
if (isPreEunosPaya)
return (result);
auto it = LowerBound<ICXSubmitEXTHTLCCloseKey>(TxidPairKey{offertxid, {}});
if (it.Valid() && it.Key().first == offertxid)
result = true;

return (result);
}

std::unique_ptr<CICXOrderView::CICXClaimDFCHTLCImpl> CICXOrderView::GetICXClaimDFCHTLCByCreationTx(uint256 const & txid) const
{
auto claimdfchtlc = ReadBy<ICXClaimDFCHTLCCreationTx,CICXClaimDFCHTLCImpl>(txid);
Expand Down
3 changes: 3 additions & 0 deletions src/masternodes/icxorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ class CICXOrderView : public virtual CStorageView {
void ForEachICXSubmitDFCHTLCClose(std::function<bool (TxidPairKey const &, uint8_t)> callback, uint256 const & offertxid = uint256());
void ForEachICXSubmitDFCHTLCExpire(std::function<bool (StatusKey const &, uint8_t)> callback, uint32_t const & height = 0);
std::unique_ptr<CICXSubmitDFCHTLCImpl> HasICXSubmitDFCHTLCOpen(uint256 const & offertxid);
bool ExistedICXSubmitDFCHTLC(uint256 const & offertxid, bool isPreEunosPaya);


//SubmitEXTHTLC
std::unique_ptr<CICXSubmitEXTHTLCImpl> GetICXSubmitEXTHTLCByCreationTx(uint256 const & txid) const;
Expand All @@ -422,6 +424,7 @@ class CICXOrderView : public virtual CStorageView {
void ForEachICXSubmitEXTHTLCClose(std::function<bool (TxidPairKey const &, uint8_t)> callback, uint256 const & offertxid = uint256());
void ForEachICXSubmitEXTHTLCExpire(std::function<bool (StatusKey const &, uint8_t)> callback, uint32_t const & height = 0);
std::unique_ptr<CICXSubmitEXTHTLCImpl> HasICXSubmitEXTHTLCOpen(uint256 const & offertxid);
bool ExistedICXSubmitEXTHTLC(uint256 const & offertxid, bool isPreEunosPaya);

//ClaimDFCHTLC
std::unique_ptr<CICXClaimDFCHTLCImpl> GetICXClaimDFCHTLCByCreationTx(uint256 const & txid) const;
Expand Down
84 changes: 66 additions & 18 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ class CCustomMetadataParseVisitor : public boost::static_visitor<Res>
return Res::Ok();
}

Res isPostEunosPayaFork() const {
if(static_cast<int>(height) < consensus.EunosPayaHeight) {
return Res::Err("called before EunosPaya height");
}
return Res::Ok();
}

template<typename T>
Res serialize(T& obj) const {
CDataStream ss(metadata, SER_NETWORK, PROTOCOL_VERSION);
Expand Down Expand Up @@ -448,9 +455,12 @@ class CCustomTxVisitor : public boost::static_visitor<Res>
}

Res CheckICXTx() const {
if (tx.vout.size() != 2) {
if (static_cast<int>(height) < consensus.EunosPayaHeight && tx.vout.size() != 2) {
return Res::Err("malformed tx vouts ((wrong number of vouts)");
}
if (static_cast<int>(height) >= consensus.EunosPayaHeight && tx.vout[0].nValue != 0) {
return Res::Err("malformed tx vouts, first vout must be OP_RETURN vout with value 0");
}
return Res::Ok();
}

Expand Down Expand Up @@ -1259,15 +1269,27 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor

srcAddr = CScript(order->creationTx.begin(), order->creationTx.end());

CScript offerTxidAddr(offer->creationTx.begin(), offer->creationTx.end());

CAmount calcAmount(static_cast<CAmount>((arith_uint256(submitdfchtlc.amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
if (calcAmount > offer->amount)
return Res::Err("amount must be lower or equal the offer one");

CScript offerTxidAddr(offer->creationTx.begin(), offer->creationTx.end());

//calculating adjusted takerFee
CAmount BTCAmount(static_cast<CAmount>((arith_uint256(submitdfchtlc.amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
auto takerFee = CalculateTakerFee(BTCAmount);
CAmount takerFee = offer->takerFee;
//EunosPaya: calculating adjusted takerFee only if amount in htlc different than in offer
if (static_cast<int>(height) >= consensus.EunosPayaHeight)
{
if (calcAmount < offer->amount)
{
CAmount BTCAmount(static_cast<CAmount>((arith_uint256(submitdfchtlc.amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
takerFee = static_cast<CAmount>((arith_uint256(BTCAmount) * arith_uint256(offer->takerFee) / arith_uint256(offer->amount)).GetLow64());
}
}
else
{
CAmount BTCAmount(static_cast<CAmount>((arith_uint256(submitdfchtlc.amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
takerFee = CalculateTakerFee(BTCAmount);
}

// refund the rest of locked takerFee if there is difference
if (offer->takerFee - takerFee) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If this value is negative then still have problem

Copy link
Contributor Author

@Mixa84 Mixa84 Jul 8, 2021

Choose a reason for hiding this comment

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

It will go into else before EunosPaya, and after it will enter the if and calculate the takerFee as ratio of the current one so offer->takerFee - takerFee will never be negative.
We must preserve old functioning before the fork so that we do not create a hardfork before EunosPaya or when syncing from scratch.

Expand Down Expand Up @@ -1362,7 +1384,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor

CAmount calcAmount(static_cast<CAmount>((arith_uint256(dfchtlc->amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
if (submitexthtlc.amount != calcAmount)
return Res::Err("amount %d must be equal to calculated dfchtlc amount %d", submitexthtlc.amount, calcAmount);
return Res::Err("amount must be equal to calculated dfchtlc amount");

if (submitexthtlc.hash != dfchtlc->hash)
return Res::Err("Invalid hash, external htlc hash is different than dfc htlc hash");
Expand All @@ -1383,14 +1405,26 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
if (submitexthtlc.timeout < CICXSubmitEXTHTLC::MINIMUM_TIMEOUT)
return Res::Err("timeout must be greater than %d", CICXSubmitEXTHTLC::MINIMUM_TIMEOUT - 1);

CScript offerTxidAddr(offer->creationTx.begin(), offer->creationTx.end());

CAmount calcAmount(static_cast<CAmount>((arith_uint256(submitexthtlc.amount) * arith_uint256(order->orderPrice) / arith_uint256(COIN)).GetLow64()));
if (calcAmount > offer->amount)
return Res::Err("amount must be lower or equal the offer one");

CScript offerTxidAddr(offer->creationTx.begin(), offer->creationTx.end());

//calculating adjusted takerFee
auto takerFee = CalculateTakerFee(submitexthtlc.amount);
CAmount takerFee = offer->takerFee;
//EunosPaya: calculating adjusted takerFee only if amount in htlc different than in offer
if (static_cast<int>(height) >= consensus.EunosPayaHeight)
{
if (calcAmount < offer->amount)
{
CAmount BTCAmount(static_cast<CAmount>((arith_uint256(offer->amount) * arith_uint256(COIN) / arith_uint256(order->orderPrice)).GetLow64()));
takerFee = static_cast<CAmount>((arith_uint256(submitexthtlc.amount) * arith_uint256(offer->takerFee) / arith_uint256(BTCAmount)).GetLow64());
}
}
else
{
takerFee = CalculateTakerFee(submitexthtlc.amount);
}

// refund the rest of locked takerFee if there is difference
if (offer->takerFee - takerFee) {
Expand Down Expand Up @@ -1454,7 +1488,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
return Res::Err("order with creation tx %s does not exists!", offer->orderTx.GetHex());

auto exthtlc = mnview.HasICXSubmitEXTHTLCOpen(dfchtlc->offerTx);
if (!exthtlc)
if (static_cast<int>(height) < consensus.EunosPayaHeight && !exthtlc)
return Res::Err("cannot claim, external htlc for this offer does not exists or expired!");

// claim DFC HTLC to receiveAddress
Expand Down Expand Up @@ -1513,7 +1547,15 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
if (!res)
return res;

return mnview.ICXCloseEXTHTLC(*exthtlc, CICXSubmitEXTHTLC::STATUS_CLOSED);
if (static_cast<int>(height) >= consensus.EunosPayaHeight)
{
if (exthtlc)
return mnview.ICXCloseEXTHTLC(*exthtlc, CICXSubmitEXTHTLC::STATUS_CLOSED);
else
return (Res::Ok());
}
else
return mnview.ICXCloseEXTHTLC(*exthtlc, CICXSubmitEXTHTLC::STATUS_CLOSED);
}

Res operator()(const CICXCloseOrderMessage& obj) const {
Expand Down Expand Up @@ -1589,7 +1631,10 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
offer->closeTx = closeoffer.creationTx;
offer->closeHeight = closeoffer.creationHeight;

if (order->orderType == CICXOrder::TYPE_INTERNAL && !mnview.HasICXSubmitDFCHTLCOpen(offer->creationTx)) {
bool isPreEunosPaya = static_cast<int>(height) < consensus.EunosPayaHeight;

if (order->orderType == CICXOrder::TYPE_INTERNAL && !mnview.ExistedICXSubmitDFCHTLC(offer->creationTx, isPreEunosPaya))
{
// subtract takerFee from txidAddr and return to owner
CScript txidAddr(offer->creationTx.begin(), offer->creationTx.end());
CalculateOwnerRewards(offer->ownerAddress);
Expand All @@ -1601,10 +1646,13 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor
// subtract the balance from txidAddr and return to owner
CScript txidAddr(offer->creationTx.begin(), offer->creationTx.end());
CalculateOwnerRewards(offer->ownerAddress);
res = ICXTransfer(order->idToken, offer->amount, txidAddr, offer->ownerAddress);
if (!res)
return res;
if (!mnview.HasICXSubmitEXTHTLCOpen(offer->creationTx))
if (isPreEunosPaya)
{
res = ICXTransfer(order->idToken, offer->amount, txidAddr, offer->ownerAddress);
if (!res)
return res;
}
if (!mnview.ExistedICXSubmitEXTHTLC(offer->creationTx, isPreEunosPaya))
{
res = ICXTransfer(DCT_ID{0}, offer->takerFee, txidAddr, offer->ownerAddress);
if (!res)
Expand Down
13 changes: 8 additions & 5 deletions src/masternodes/rpc_icxorderbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1196,15 +1196,19 @@ UniValue icxlistorders(const JSONRPCRequest& request) {
size_t limit = 50;
std::string tokenSymbol, chain;
uint256 orderTxid;
bool closed = false;
bool closed = false, offers = false;

RPCTypeCheck(request.params, {UniValue::VOBJ}, false);
if (request.params.size() > 0)
{
UniValue byObj = request.params[0].get_obj();
if (!byObj["token"].isNull()) tokenSymbol = trim_ws(byObj["token"].getValStr());
if (!byObj["chain"].isNull()) chain = trim_ws(byObj["chain"].getValStr());
if (!byObj["orderTx"].isNull()) orderTxid = uint256S(byObj["orderTx"].getValStr());
if (!byObj["orderTx"].isNull())
{
orderTxid = uint256S(byObj["orderTx"].getValStr());
offers = true;
}
if (!byObj["limit"].isNull()) limit = (size_t) byObj["limit"].get_int64();
if (!byObj["closed"].isNull()) closed = byObj["closed"].get_bool();
}
Expand Down Expand Up @@ -1244,7 +1248,7 @@ UniValue icxlistorders(const JSONRPCRequest& request) {

return ret;
}
else if (!orderTxid.IsNull())
else if (offers)
{
auto offerkeylambda = [&](CICXOrderView::TxidPairKey const & key, uint8_t status) {
if (key.first != orderTxid)
Expand Down Expand Up @@ -1291,8 +1295,7 @@ UniValue icxlisthtlcs(const JSONRPCRequest& request) {
{
{"offerTx",RPCArg::Type::STR, RPCArg::Optional::NO, "Offer txid for which to list all HTLCS"},
{"limit", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Maximum number of orders to return (default: 20)"},
{"refunded", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Display refunded HTLC (default: false)"},
{"claimed", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Display claimed HTLCs (default: false)"},
{"closed", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Display also claimed, expired and refunded HTLCs (default: false)"},

},
},
Expand Down
10 changes: 6 additions & 4 deletions src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2627,6 +2627,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
// close expired orders, refund all expired DFC HTLCs at this block height
if (pindex->nHeight >= chainparams.GetConsensus().EunosHeight)
{
bool isPreEunosPaya = pindex->nHeight < chainparams.GetConsensus().EunosPayaHeight;

cache.ForEachICXOrderExpire([&](CICXOrderView::StatusKey const & key, uint8_t status) {

if (static_cast<int>(key.first) != pindex->nHeight)
Expand Down Expand Up @@ -2671,8 +2673,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
CScript txidAddr(offer->creationTx.begin(),offer->creationTx.end());
CTokenAmount takerFee{DCT_ID{0}, offer->takerFee};

if ((order->orderType == CICXOrder::TYPE_INTERNAL && !cache.HasICXSubmitDFCHTLCOpen(offer->creationTx)) ||
(order->orderType == CICXOrder::TYPE_EXTERNAL && !cache.HasICXSubmitEXTHTLCOpen(offer->creationTx)))
if ((order->orderType == CICXOrder::TYPE_INTERNAL && !cache.ExistedICXSubmitDFCHTLC(offer->creationTx, isPreEunosPaya)) ||
(order->orderType == CICXOrder::TYPE_EXTERNAL && !cache.ExistedICXSubmitEXTHTLC(offer->creationTx, isPreEunosPaya)))
{
auto res = cache.SubBalance(txidAddr,takerFee);
if (!res)
Expand Down Expand Up @@ -2710,7 +2712,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl

if (status == CICXSubmitDFCHTLC::STATUS_EXPIRED && order->orderType == CICXOrder::TYPE_INTERNAL)
{
if (!cache.HasICXSubmitEXTHTLCOpen(dfchtlc->offerTx))
if (!cache.ExistedICXSubmitEXTHTLC(dfchtlc->offerTx, isPreEunosPaya))
{
CTokenAmount makerDeposit{DCT_ID{0}, offer->takerFee};
cache.CalculateOwnerRewards(order->ownerAddress,pindex->nHeight);
Expand Down Expand Up @@ -2765,7 +2767,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl

if (status == CICXSubmitEXTHTLC::STATUS_EXPIRED && order->orderType == CICXOrder::TYPE_EXTERNAL)
{
if (!cache.HasICXSubmitDFCHTLCOpen(exthtlc->offerTx))
if (!cache.ExistedICXSubmitDFCHTLC(exthtlc->offerTx, isPreEunosPaya))
{
CTokenAmount makerDeposit{DCT_ID{0}, offer->takerFee};
cache.CalculateOwnerRewards(order->ownerAddress,pindex->nHeight);
Expand Down
Loading