From 6a5397380c39027605f9b8d214cf69f852568b94 Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 11:19:54 +0100 Subject: [PATCH 1/7] Add refund to listfutureswaphistory --- src/validation.cpp | 6 ++++-- test/functional/feature_futures.py | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 0b9da9c623..b733fee474 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3381,7 +3381,7 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache CTokenAmount destination{tokenDUSD->first, total}; cache.AddBalance(key.owner, destination); cache.StoreFuturesDestValues(key, {destination, static_cast(pindex->nHeight)}); - LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Owner %s source %s destination %s\n", + LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Payment Owner %s source %s destination %s\n", key.owner.GetHex(), futuresValues.source.ToString(), destination.ToString()); } catch (const std::out_of_range&) { unpaidContracts.emplace(key, futuresValues); @@ -3399,9 +3399,11 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache // Refund unpaid contracts for (const auto& [key, value] : unpaidContracts) { - cache.EraseFuturesUserValues(key); cache.SubBalance(*contractAddressValue, value.source); cache.AddBalance(key.owner, value.source); + cache.StoreFuturesDestValues(key, {value.source, static_cast(pindex->nHeight)}); + LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Refund Owner %s source %s destination %s\n", + key.owner.GetHex(), value.source.ToString(), value.source.ToString()); balances.Sub(value.source); } diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index 7a0dfeb72c..cf4dc21b7b 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -858,6 +858,12 @@ def unpaid_contract(self): next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) + # Check refund in history + result = self.nodes[0].listfutureswaphistory() + assert_equal(result[0]['address'], address) + assert_equal(result[0]['source'], f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}') + assert_equal(result[0]['destination'], f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}') + # Check user has been refunded result = self.nodes[0].getaccount(address) assert_equal(result, [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) @@ -889,7 +895,7 @@ def rpc_history(self): # Check all swaps present result = self.nodes[0].listfutureswaphistory('all') - assert_equal(len(result), 20) + assert_equal(len(result), 21) # Check swap by specific address result = self.nodes[0].listfutureswaphistory(self.list_history[0]['swaps'][0]['address']) @@ -901,7 +907,7 @@ def rpc_history(self): # Check all wallet swaps present, still all of them! result = self.nodes[0].listfutureswaphistory('mine') - assert_equal(len(result), 20) + assert_equal(len(result), 21) # Check limit working result = self.nodes[0].listfutureswaphistory('all', {'limit': 1}) From 7852dc3c1464115ecea6a4684808cfc88e51feee Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 11:47:26 +0100 Subject: [PATCH 2/7] Update getburninfo to only display future swap balance after execution --- src/masternodes/rpc_accounts.cpp | 26 +++++++++++++++++++++++--- test/functional/feature_futures.py | 4 ++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index 755f3944e9..67986ea5cf 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -1868,9 +1868,6 @@ UniValue getburninfo(const JSONRPCRequest& request) { auto paybacks = attributes->GetValue(liveKey, CTokenPayback{}); paybackfees = std::move(paybacks.tokensFee); paybacktokens = std::move(paybacks.tokensPayback); - - liveKey = {AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Tokens}; - dfi2203Tokens = attributes->GetValue(liveKey, CBalances{}); } result.pushKV("dfipaybackfee", ValueFromAmount(dfiPaybackFee)); @@ -1887,6 +1884,29 @@ UniValue getburninfo(const JSONRPCRequest& request) { } } result.pushKV("emissionburn", ValueFromAmount(burnt)); + + const auto blockAndReward = GetFuturesBlockAndReward(); + if (!blockAndReward) { + return result; + } + + const auto currentHeight = ::ChainActive().Height(); + const uint32_t startPeriod = currentHeight - (currentHeight % blockAndReward->first); + + pcustomcsview->ForEachFuturesDestValues([&](const CFuturesUserKey& key, const CFuturesUserValue& destination) { + const auto source = pcustomcsview->GetFuturesUserValues(key); + if (!source) { + return true; + } + + // Exclude refunds + if (source.val->source != destination.source) { + dfi2203Tokens.Add(source.val->source); + } + + return true; + }, {startPeriod, {}, std::numeric_limits::max()}); + result.pushKV("dfip2203", AmountsToJSON(dfi2203Tokens.balances)); return result; diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index cf4dc21b7b..f959200cdb 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -300,6 +300,10 @@ def test_dtoken_to_dusd(self): assert_equal(result['values'][0]['source'], f'{Decimal("1.00000000")}@{self.symbolTWTR}') assert_equal(result['values'][0]['destination'], self.symbolDUSD) + # Check DFI2203 amounts do not show up as burns yet + result = self.nodes[0].getburninfo() + assert_equal(result['dfip2203'], []) + # Move to next futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) From ddd19f4f3ba24c4a8685825f786af5082e88897f Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 11:57:34 +0100 Subject: [PATCH 3/7] Allow future swap destination token to be set with name and int --- src/masternodes/rpc_accounts.cpp | 22 ++++++++++++++++++---- src/rpc/client.cpp | 2 -- test/functional/feature_futures.py | 8 ++++---- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index 67986ea5cf..b19667f4fe 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -2061,7 +2061,7 @@ UniValue futureswap(const JSONRPCRequest& request) { { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address to fund contract and receive resulting token"}, {"amount", RPCArg::Type::STR, RPCArg::Optional::NO, "Amount to send in amount@token format"}, - {"destination", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Expected dToken if DUSD supplied"}, + {"destination", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Expected dToken if DUSD supplied"}, {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "A json array of json objects", { @@ -2100,7 +2100,14 @@ UniValue futureswap(const JSONRPCRequest& request) { msg.source = DecodeAmount(pwallet->chain(), request.params[1], ""); if (!request.params[2].isNull()) { - msg.destination = request.params[2].get_int(); + DCT_ID destTokenID{}; + + const auto destToken = pcustomcsview->GetTokenGuessId(request.params[2].getValStr(), destTokenID); + if (!destToken) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Destination token not found"); + } + + msg.destination = destTokenID.v; } // Encode @@ -2146,7 +2153,7 @@ UniValue withdrawfutureswap(const JSONRPCRequest& request) { { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Address used to fund contract with"}, {"amount", RPCArg::Type::STR, RPCArg::Optional::NO, "Amount to withdraw in amount@token format"}, - {"destination", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "The dToken if DUSD supplied"}, + {"destination", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "The dToken if DUSD supplied"}, {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "A json array of json objects", { @@ -2184,7 +2191,14 @@ UniValue withdrawfutureswap(const JSONRPCRequest& request) { msg.withdraw = true; if (!request.params[2].isNull()) { - msg.destination = request.params[2].get_int(); + DCT_ID destTokenID{}; + + const auto destToken = pcustomcsview->GetTokenGuessId(request.params[2].getValStr(), destTokenID); + if (!destToken) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Destination token not found"); + } + + msg.destination = destTokenID.v; } // Encode diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 9136385b65..5bec1b704d 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -215,9 +215,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "accounttoaccount", 2, "inputs" }, { "accounttoutxos", 1, "to" }, { "accounttoutxos", 2, "inputs" }, - { "futureswap", 2, "destination"}, { "futureswap", 3, "inputs"}, - { "withdrawfutureswap", 2, "destination"}, { "withdrawfutureswap", 3, "inputs"}, { "icx_createorder", 0, "order" }, diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index f959200cdb..c1332d9222 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -366,13 +366,13 @@ def test_dusd_to_dtoken(self): self.nodes[0].generate(1) # Create user futures contracts - self.nodes[0].futureswap(address_msft, f'{self.prices[3]["premiumPrice"]}@{self.symbolDUSD}', int(self.idMSFT)) + self.nodes[0].futureswap(address_msft, f'{self.prices[3]["premiumPrice"]}@{self.symbolDUSD}', self.idMSFT) self.nodes[0].generate(1) - self.nodes[0].futureswap(address_twtr, f'{self.prices[2]["premiumPrice"]}@{self.symbolDUSD}', int(self.idTWTR)) + self.nodes[0].futureswap(address_twtr, f'{self.prices[2]["premiumPrice"]}@{self.symbolDUSD}', self.idTWTR) self.nodes[0].generate(1) - self.nodes[0].futureswap(address_googl, f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}', int(self.idGOOGL)) + self.nodes[0].futureswap(address_googl, f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}', self.symbolGOOGL) self.nodes[0].generate(1) - self.nodes[0].futureswap(address_tsla, f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}', int(self.idTSLA)) + self.nodes[0].futureswap(address_tsla, f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}', self.symbolTSLA) self.nodes[0].generate(1) # List user futures contracts From 5c7f8943cb21cb9249a001175955fa0b8985e5ef Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 12:59:26 +0100 Subject: [PATCH 4/7] Add burn entry to Gov vars live --- src/masternodes/govvariables/attributes.cpp | 5 +++-- src/masternodes/govvariables/attributes.h | 3 ++- src/masternodes/mn_checks.cpp | 2 +- src/validation.cpp | 14 ++++++++++-- test/functional/feature_futures.py | 24 ++++++++++++++++----- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/masternodes/govvariables/attributes.cpp b/src/masternodes/govvariables/attributes.cpp index 383908f825..ed41e86d57 100644 --- a/src/masternodes/govvariables/attributes.cpp +++ b/src/masternodes/govvariables/attributes.cpp @@ -146,7 +146,8 @@ const std::map>& ATTRIBUTES::displayKeys { AttributeTypes::Live, { {EconomyKeys::PaybackDFITokens, "dfi_payback_tokens"}, - {EconomyKeys::DFIP2203Tokens, "dfip_tokens"}, + {EconomyKeys::DFIP2203Current, "dfip2203_current"}, + {EconomyKeys::DFIP2203Burned, "dfip2203_burned"}, } }, }; @@ -394,7 +395,7 @@ Res ATTRIBUTES::RefundFuturesContracts(CCustomCSView &mnview, const uint32_t hei return contractAddressValue; } - CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Tokens}; + CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Current}; auto balances = GetValue(liveKey, CBalances{}); for (const auto& [key, value] : userFuturesValues) { diff --git a/src/masternodes/govvariables/attributes.h b/src/masternodes/govvariables/attributes.h index f7f32ec4db..75cad78450 100644 --- a/src/masternodes/govvariables/attributes.h +++ b/src/masternodes/govvariables/attributes.h @@ -29,7 +29,8 @@ enum ParamIDs : uint8_t { enum EconomyKeys : uint8_t { PaybackDFITokens = 'a', PaybackTokens = 'b', - DFIP2203Tokens = 'c', + DFIP2203Current = 'c', + DFIP2203Burned = 'd', }; enum DFIPKeys : uint8_t { diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index 8453585a21..d989163521 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -1520,7 +1520,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor return contractAddressValue; } - CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Tokens}; + CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Current}; auto balances = attributes->GetValue(liveKey, CBalances{}); if (obj.withdraw) { diff --git a/src/validation.cpp b/src/validation.cpp index b733fee474..57179955e9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3342,6 +3342,10 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache return true; }); + CDataStructureV0 burnKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Burned}; + + auto burned = attributes->GetValue(burnKey, CBalances{}); + const uint32_t startHeight = pindex->nHeight - blockPeriod; std::map unpaidContracts; cache.ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues){ @@ -3363,6 +3367,7 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache const auto total = DivideAmounts(futuresValues.source.nValue, premiumPrice); CTokenAmount destination{destId, total}; cache.AddBalance(key.owner, destination); + burned.Add(futuresValues.source); cache.StoreFuturesDestValues(key, {destination, static_cast(pindex->nHeight)}); LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Owner %s source %s destination %s\n", key.owner.GetHex(), futuresValues.source.ToString(), destination.ToString()); @@ -3380,6 +3385,7 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache const auto total = MultiplyAmounts(futuresValues.source.nValue, discountPrice); CTokenAmount destination{tokenDUSD->first, total}; cache.AddBalance(key.owner, destination); + burned.Add(futuresValues.source); cache.StoreFuturesDestValues(key, {destination, static_cast(pindex->nHeight)}); LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Payment Owner %s source %s destination %s\n", key.owner.GetHex(), futuresValues.source.ToString(), destination.ToString()); @@ -3394,7 +3400,8 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache const auto contractAddressValue = GetFutureSwapContractAddress(); assert(contractAddressValue); - CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Tokens}; + CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Current}; + auto balances = attributes->GetValue(liveKey, CBalances{}); // Refund unpaid contracts @@ -3407,10 +3414,13 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache balances.Sub(value.source); } + attributes->attributes[burnKey] = burned; + if (!unpaidContracts.empty()) { attributes->attributes[liveKey] = balances; - cache.SetVariable(*attributes); } + + cache.SetVariable(*attributes); } void CChainState::ProcessOracleEvents(const CBlockIndex* pindex, CCustomCSView& cache, const CChainParams& chainparams){ diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index c1332d9222..fb93bfe1bc 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -304,6 +304,11 @@ def test_dtoken_to_dusd(self): result = self.nodes[0].getburninfo() assert_equal(result['dfip2203'], []) + # Check DFI2203 address on listgovs, current shows pending, burn should be empty. + result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] + assert_equal(result['v0/live/economy/dfip2203_current'], [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert('v0/live/economy/dfip2203_burned' not in result) + # Move to next futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) @@ -326,7 +331,7 @@ def test_dtoken_to_dusd(self): # Check DFI2203 address on listgovs result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] - assert_equal(result['v0/live/economy/dfip_tokens'], [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_current'], [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on getburninfo result = self.nodes[0].getburninfo() @@ -410,6 +415,15 @@ def test_dusd_to_dtoken(self): assert_equal(result['values'][0]['source'], f'{self.prices[3]["premiumPrice"]}@{self.symbolDUSD}') assert_equal(result['values'][0]['destination'], self.symbolMSFT) + # Check new DFI2203 amounts do not show up as burns yet + result = self.nodes[0].getburninfo() + assert_equal(result['dfip2203'], [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + + # Check DFI2203 address on listgovs, current shows pending, new swaps should not show up on burn. + result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] + assert_equal(result['v0/live/economy/dfip2203_current'], [f'3992.10000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_burned'], [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + # Move to next futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) @@ -432,7 +446,7 @@ def test_dusd_to_dtoken(self): # Check DFI2203 address on listgovs result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] - assert_equal(result['v0/live/economy/dfip_tokens'], [f'3992.10000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_current'], [f'3992.10000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on getburninfo result = self.nodes[0].getburninfo() @@ -667,7 +681,7 @@ def check_withdrawals(self): # Check DFI2203 address on listgovs result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] - assert_equal(result['v0/live/economy/dfip_tokens'], [f'7468.64999999@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_current'], [f'7468.64999999@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on getburninfo result = self.nodes[0].getburninfo() @@ -835,7 +849,7 @@ def check_gov_var_change(self): # Check DFI2203 address on listgovs result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] - assert_equal(result['v0/live/economy/dfip_tokens'], [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_current'], [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on getburninfo result = self.nodes[0].getburninfo() @@ -878,7 +892,7 @@ def unpaid_contract(self): # Check DFI2203 address on listgovs result = self.nodes[0].listgovs()[8][0]['ATTRIBUTES'] - assert_equal(result['v0/live/economy/dfip_tokens'], [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) + assert_equal(result['v0/live/economy/dfip2203_current'], [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on getburninfo result = self.nodes[0].getburninfo() From a57de04c2403b1fba02bc93d5c311a3710ed801e Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 15:06:46 +0100 Subject: [PATCH 5/7] Remove future swap history, add history to account history. --- src/masternodes/accounts.cpp | 24 +-- src/masternodes/accounts.h | 5 +- src/masternodes/govvariables/attributes.cpp | 29 ++- src/masternodes/masternodes.h | 2 +- src/masternodes/mn_checks.cpp | 10 +- src/masternodes/mn_checks.h | 6 +- src/masternodes/mn_rpc.cpp | 4 +- src/masternodes/mn_rpc.h | 2 +- src/masternodes/rpc_accounts.cpp | 217 +------------------- src/masternodes/rpc_oracles.cpp | 6 +- src/rpc/client.cpp | 1 - src/validation.cpp | 40 ++-- test/functional/feature_futures.py | 134 ++++++------ 13 files changed, 139 insertions(+), 341 deletions(-) diff --git a/src/masternodes/accounts.cpp b/src/masternodes/accounts.cpp index 2b79fb5368..bef8fe94d8 100644 --- a/src/masternodes/accounts.cpp +++ b/src/masternodes/accounts.cpp @@ -101,7 +101,7 @@ uint32_t CAccountsView::GetBalancesHeight(CScript const & owner) Res CAccountsView::StoreFuturesUserValues(const CFuturesUserKey& key, const CFuturesUserValue& futures) { - if (!WriteBy(key, futures)) { + if (!WriteBy(key, futures)) { return Res::Err("Failed to store futures"); } @@ -110,12 +110,12 @@ Res CAccountsView::StoreFuturesUserValues(const CFuturesUserKey& key, const CFut void CAccountsView::ForEachFuturesUserValues(std::function callback, const CFuturesUserKey& start) { - ForEach(callback, start); + ForEach(callback, start); } Res CAccountsView::EraseFuturesUserValues(const CFuturesUserKey& key) { - if (!EraseBy(key)) { + if (!EraseBy(key)) { return Res::Err("Failed to erase futures"); } @@ -125,7 +125,7 @@ Res CAccountsView::EraseFuturesUserValues(const CFuturesUserKey& key) boost::optional CAccountsView::GetMostRecentFuturesHeight() { const CFuturesUserKey key{std::numeric_limits::max(), {}, std::numeric_limits::max()}; - auto it = LowerBound(key); + auto it = LowerBound(key); if (it.Valid()) { return it.Key().height; } @@ -133,25 +133,11 @@ boost::optional CAccountsView::GetMostRecentFuturesHeight() return {}; } -Res CAccountsView::StoreFuturesDestValues(const CFuturesUserKey& key, const CFuturesUserValue& destination) -{ - if (!WriteBy(key, destination)) { - return Res::Err("Failed to store futures destination"); - } - - return Res::Ok(); -} - ResVal CAccountsView::GetFuturesUserValues(const CFuturesUserKey& key) { CFuturesUserValue source; - if (!ReadBy(key, source)) { + if (!ReadBy(key, source)) { return Res::Err("Failed to read futures source"); } return {source, Res::Ok()}; } - -void CAccountsView::ForEachFuturesDestValues(std::function callback, const CFuturesUserKey& start) -{ - ForEach(callback, start); -} diff --git a/src/masternodes/accounts.h b/src/masternodes/accounts.h index fe259f17c5..a720df62cb 100644 --- a/src/masternodes/accounts.h +++ b/src/masternodes/accounts.h @@ -70,18 +70,15 @@ class CAccountsView : public virtual CStorageView Res UpdateBalancesHeight(CScript const & owner, uint32_t height); Res StoreFuturesUserValues(const CFuturesUserKey& key, const CFuturesUserValue& futures); - Res StoreFuturesDestValues(const CFuturesUserKey& key, const CFuturesUserValue& destination); ResVal GetFuturesUserValues(const CFuturesUserKey& key); Res EraseFuturesUserValues(const CFuturesUserKey& key); boost::optional GetMostRecentFuturesHeight(); void ForEachFuturesUserValues(std::function callback, const CFuturesUserKey& start = {}); - void ForEachFuturesDestValues(std::function callback, const CFuturesUserKey& start = {}); // tags struct ByBalanceKey { static constexpr uint8_t prefix() { return 'a'; } }; struct ByHeightKey { static constexpr uint8_t prefix() { return 'b'; } }; - struct ByFuturesSourceKey { static constexpr uint8_t prefix() { return 'J'; } }; - struct ByFuturesDestKey { static constexpr uint8_t prefix() { return 's'; } }; + struct ByFuturesSwapKey { static constexpr uint8_t prefix() { return 'J'; } }; private: Res SetBalance(CScript const & owner, CTokenAmount amount); diff --git a/src/masternodes/govvariables/attributes.cpp b/src/masternodes/govvariables/attributes.cpp index ed41e86d57..f8af1de9da 100644 --- a/src/masternodes/govvariables/attributes.cpp +++ b/src/masternodes/govvariables/attributes.cpp @@ -4,8 +4,11 @@ #include -#include /// ValueFromAmount +#include /// CAccountsHistoryWriter #include /// CCustomCSView +#include /// CustomTxType + +#include /// ValueFromAmount #include extern UniValue AmountsToJSON(TAmounts const & diffs); @@ -371,14 +374,9 @@ Res ATTRIBUTES::RefundFuturesContracts(CCustomCSView &mnview, const uint32_t hei return Res::Ok(); } - const uint32_t startHeight = height - (height % blockPeriod); std::map userFuturesValues; mnview.ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues) { - if (key.height <= startHeight) { - return false; - } - if (tokenID != std::numeric_limits::max()) { if (futuresValues.source.nTokenId.v == tokenID || futuresValues.destination == tokenID) { userFuturesValues[key] = futuresValues; @@ -398,15 +396,19 @@ 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); + for (const auto& [key, value] : userFuturesValues) { - mnview.EraseFuturesUserValues(key); + view.EraseFuturesUserValues(key); - auto res = mnview.SubBalance(*contractAddressValue, value.source); + auto res = view.SubBalance(*contractAddressValue, value.source); if (!res) { return res; } - res = mnview.AddBalance(key.owner, value.source); + res = view.AddBalance(key.owner, value.source); if (!res) { return res; } @@ -417,6 +419,8 @@ Res ATTRIBUTES::RefundFuturesContracts(CCustomCSView &mnview, const uint32_t hei } } + view.Flush(); + attributes[liveKey] = balances; return Res::Ok(); @@ -686,13 +690,6 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height) if (GetValue(activeKey, false)) { return Res::Err("Cannot set block period while DFIP2203 is active"); } - - auto blockPeriod = boost::get(attribute.second); - const auto recentFuturesHeight = mnview.GetMostRecentFuturesHeight(); - - if (recentFuturesHeight && *recentFuturesHeight > height - (height % blockPeriod)) { - return Res::Err("Historical Futures contracts in this period"); - } } } } diff --git a/src/masternodes/masternodes.h b/src/masternodes/masternodes.h index b352d52913..3ab67523e3 100644 --- a/src/masternodes/masternodes.h +++ b/src/masternodes/masternodes.h @@ -363,7 +363,7 @@ class CCustomCSView CFoundationsDebtView :: Debt, CAnchorRewardsView :: BtcTx, CTokensView :: ID, Symbol, CreationTx, LastDctId, - CAccountsView :: ByBalanceKey, ByHeightKey, ByFuturesSourceKey, ByFuturesDestKey, + CAccountsView :: ByBalanceKey, ByHeightKey, ByFuturesSwapKey, CCommunityBalancesView :: ById, CUndosView :: ByUndoKey, CPoolPairView :: ByID, ByPair, ByShare, ByIDPair, ByPoolSwap, ByReserves, ByRewardPct, ByRewardLoanPct, diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index d989163521..81c4c3baec 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -79,6 +79,8 @@ std::string ToString(CustomTxType type) { case CustomTxType::PaybackLoan: return "PaybackLoan"; case CustomTxType::PaybackLoanV2: return "PaybackLoan"; case CustomTxType::AuctionBid: return "AuctionBid"; + case CustomTxType::FutureSwapExecution: return "FutureSwapExecution"; + case CustomTxType::FutureSwapRefund: return "FutureSwapRefund"; case CustomTxType::Reject: return "Reject"; case CustomTxType::None: return "None"; } @@ -162,6 +164,8 @@ CCustomTxMessage customTypeToMessage(CustomTxType txType) { case CustomTxType::PaybackLoan: return CLoanPaybackLoanMessage{}; case CustomTxType::PaybackLoanV2: return CLoanPaybackLoanV2Message{}; case CustomTxType::AuctionBid: return CAuctionBidMessage{}; + case CustomTxType::FutureSwapExecution: return CCustomTxMessageNone{}; + case CustomTxType::FutureSwapRefund: return CCustomTxMessageNone{}; case CustomTxType::Reject: return CCustomTxMessageNone{}; case CustomTxType::None: return CCustomTxMessageNone{}; } @@ -1524,15 +1528,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor auto balances = attributes->GetValue(liveKey, CBalances{}); if (obj.withdraw) { - const auto blockPeriod = attributes->GetValue(blockKey, CAmount{}); - const uint32_t startHeight = height - (height % blockPeriod); std::map userFuturesValues; mnview.ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues) { - if (key.height <= startHeight) { - return false; - } - if (key.owner == obj.owner && futuresValues.source.nTokenId == obj.source.nTokenId && futuresValues.destination == obj.destination) { diff --git a/src/masternodes/mn_checks.h b/src/masternodes/mn_checks.h index 298c3197c4..07a14eb129 100644 --- a/src/masternodes/mn_checks.h +++ b/src/masternodes/mn_checks.h @@ -101,7 +101,9 @@ enum class CustomTxType : uint8_t TakeLoan = 'X', PaybackLoan = 'H', PaybackLoanV2 = 'k', - AuctionBid = 'I' + AuctionBid = 'I', + FutureSwapExecution = 'q', + FutureSwapRefund = 'w', }; inline CustomTxType CustomTxCodeToType(uint8_t ch) { @@ -157,6 +159,8 @@ inline CustomTxType CustomTxCodeToType(uint8_t ch) { case CustomTxType::PaybackLoan: case CustomTxType::PaybackLoanV2: case CustomTxType::AuctionBid: + case CustomTxType::FutureSwapExecution: + case CustomTxType::FutureSwapRefund: case CustomTxType::Reject: case CustomTxType::None: return type; diff --git a/src/masternodes/mn_rpc.cpp b/src/masternodes/mn_rpc.cpp index d8de7e82d6..7515fef733 100644 --- a/src/masternodes/mn_rpc.cpp +++ b/src/masternodes/mn_rpc.cpp @@ -453,7 +453,7 @@ CWalletCoinsUnlocker GetWallet(const JSONRPCRequest& request) { return CWalletCoinsUnlocker{std::move(wallet)}; } -std::optional> GetFuturesBlockAndReward() +std::optional GetFuturesBlock() { LOCK(cs_main); @@ -474,7 +474,7 @@ std::optional> GetFuturesBlockAndReward() return {}; } - return std::pair{attributes->GetValue(blockKey, CAmount{}), attributes->GetValue(rewardKey, CAmount{})}; + return attributes->GetValue(blockKey, CAmount{}); } UniValue setgov(const JSONRPCRequest& request) { diff --git a/src/masternodes/mn_rpc.h b/src/masternodes/mn_rpc.h index 67cc490017..2621e61880 100644 --- a/src/masternodes/mn_rpc.h +++ b/src/masternodes/mn_rpc.h @@ -61,6 +61,6 @@ CAccounts SelectAccountsByTargetBalances(const CAccounts& accounts, const CBalan void execTestTx(const CTransaction& tx, uint32_t height, CTransactionRef optAuthTx = {}); CScript CreateScriptForHTLC(const JSONRPCRequest& request, uint32_t &blocks, std::vector& image); CPubKey PublickeyFromString(const std::string &pubkey); -std::optional> GetFuturesBlockAndReward(); +std::optional GetFuturesBlock(); #endif // DEFI_MASTERNODES_MN_RPC_H diff --git a/src/masternodes/rpc_accounts.cpp b/src/masternodes/rpc_accounts.cpp index b19667f4fe..598d73e1c3 100644 --- a/src/masternodes/rpc_accounts.cpp +++ b/src/masternodes/rpc_accounts.cpp @@ -1868,6 +1868,9 @@ UniValue getburninfo(const JSONRPCRequest& request) { auto paybacks = attributes->GetValue(liveKey, CTokenPayback{}); paybackfees = std::move(paybacks.tokensFee); paybacktokens = std::move(paybacks.tokensPayback); + + liveKey = {AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Burned}; + dfi2203Tokens = attributes->GetValue(liveKey, CBalances{}); } result.pushKV("dfipaybackfee", ValueFromAmount(dfiPaybackFee)); @@ -1884,29 +1887,6 @@ UniValue getburninfo(const JSONRPCRequest& request) { } } result.pushKV("emissionburn", ValueFromAmount(burnt)); - - const auto blockAndReward = GetFuturesBlockAndReward(); - if (!blockAndReward) { - return result; - } - - const auto currentHeight = ::ChainActive().Height(); - const uint32_t startPeriod = currentHeight - (currentHeight % blockAndReward->first); - - pcustomcsview->ForEachFuturesDestValues([&](const CFuturesUserKey& key, const CFuturesUserValue& destination) { - const auto source = pcustomcsview->GetFuturesUserValues(key); - if (!source) { - return true; - } - - // Exclude refunds - if (source.val->source != destination.source) { - dfi2203Tokens.Add(source.val->source); - } - - return true; - }, {startPeriod, {}, std::numeric_limits::max()}); - result.pushKV("dfip2203", AmountsToJSON(dfi2203Tokens.balances)); return result; @@ -2252,21 +2232,10 @@ UniValue listpendingfutureswaps(const JSONRPCRequest& request) { }.Check(request); UniValue listFutures{UniValue::VARR}; - const auto blockAndReward = GetFuturesBlockAndReward(); - if (!blockAndReward) { - return listFutures; - } LOCK(cs_main); - const auto currentHeight = ::ChainActive().Height(); - const auto startPeriod = currentHeight - (currentHeight % blockAndReward->first); - pcustomcsview->ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues){ - if (key.height <= startPeriod) { - return false; - } - CTxDestination dest; ExtractDestination(key.owner, dest); if (!IsValidDestination(dest)) { @@ -2322,30 +2291,20 @@ UniValue getpendingfutureswaps(const JSONRPCRequest& request) { }.Check(request); UniValue listValues{UniValue::VARR}; - const auto blockAndReward = GetFuturesBlockAndReward(); - if (!blockAndReward) { - return listValues; - } const auto owner = DecodeScript(request.params[0].get_str()); LOCK(cs_main); - const auto currentHeight = ::ChainActive().Height(); - const auto startPeriod = currentHeight - (currentHeight % blockAndReward->first); - std::vector storedFutures; pcustomcsview->ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues) { - if (key.height <= startPeriod) { - return false; - } if (key.owner == owner) { storedFutures.push_back(futuresValues); } return true; - }, {static_cast(currentHeight), owner, std::numeric_limits::max()}); + }, {static_cast(::ChainActive().Height()), owner, std::numeric_limits::max()}); for (const auto& item : storedFutures) { UniValue value{UniValue::VOBJ}; @@ -2377,173 +2336,6 @@ UniValue getpendingfutureswaps(const JSONRPCRequest& request) { } -UniValue listfutureswaphistory(const JSONRPCRequest& request) { - auto pwallet = GetWallet(request); - - RPCHelpMan{"listfutureswaphistory", - "\nReturns information about future swap history.\n", - { - {"owner", RPCArg::Type::STR, RPCArg::Optional::OMITTED, - "Single account ID (CScript or address) or reserved words: \"mine\" - to list history for all owned accounts or \"all\" to list whole DB (default = \"mine\")."}, - {"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", - { - {"maxBlockHeight", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, - "Optional height to iterate from (downto genesis block), (default = chaintip)."}, - {"depth", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, - "Maximum depth, from the genesis block is the default"}, - {"token", RPCArg::Type::STR, RPCArg::Optional::OMITTED, - "Filter by token"}, - {"limit", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, - "Maximum number of records to return, 100 by default"}, - }, - }, - }, - RPCResult{ - "[{},{}...] (array) Objects with future swap history information\n" - }, - RPCExamples{ - HelpExampleCli("listfutureswaphistory", "all '{\"maxBlockHeight\":160,\"depth\":10}'") - + HelpExampleRpc("listfutureswaphistory", "all, '{\"maxBlockHeight\":160,\"depth\":10}'") - }, - }.Check(request); - - - std::string accounts = "mine"; - if (request.params.size() > 0) { - accounts = request.params[0].getValStr(); - } - - if (!paccountHistoryDB) { - throw JSONRPCError(RPC_INVALID_REQUEST, "-acindex is needed for account history"); - } - - auto maxBlockHeight = std::numeric_limits::max(); - auto depth{maxBlockHeight}; - std::string tokenFilter; - uint32_t limit = 100; - - if (request.params.size() > 1) { - UniValue optionsObj = request.params[1].get_obj(); - RPCTypeCheckObj(optionsObj, - { - {"maxBlockHeight", UniValueType(UniValue::VNUM)}, - {"depth", UniValueType(UniValue::VNUM)}, - {"token", UniValueType(UniValue::VSTR)}, - {"limit", UniValueType(UniValue::VNUM)}, - }, true, true); - - if (!optionsObj["maxBlockHeight"].isNull()) { - maxBlockHeight = (uint32_t) optionsObj["maxBlockHeight"].get_int64(); - } - - if (!optionsObj["depth"].isNull()) { - depth = (uint32_t) optionsObj["depth"].get_int64(); - } - - if (!optionsObj["token"].isNull()) { - tokenFilter = optionsObj["token"].get_str(); - } - - if (!optionsObj["limit"].isNull()) { - limit = (uint32_t) optionsObj["limit"].get_int64(); - } - - if (limit == 0) { - limit = std::numeric_limits::max(); - } - } - - pwallet->BlockUntilSyncedToCurrentChain(); - - std::function isMatchOwner = [](const CScript &) { - return true; - }; - - DCT_ID tokenID{}; - - if (!tokenFilter.empty()) { - const auto token = pcustomcsview->GetTokenGuessId(tokenFilter, tokenID); - - if (!token) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Token %s does not exist.", tokenFilter)); - } - } - - CScript account{}; - auto isMine{false}; - auto filter{ISMINE_ALL}; - - if (accounts == "mine") { - isMine = true; - filter = ISMINE_SPENDABLE; - } else if (accounts != "all") { - account = DecodeScript(accounts); - isMatchOwner = [&account](CScript const & owner) { - return owner == account; - }; - } - - maxBlockHeight = std::min(maxBlockHeight, uint32_t(::ChainActive().Height())); - if (depth > maxBlockHeight) { - depth = maxBlockHeight; - } - - UniValue result(UniValue::VARR); - pcustomcsview->ForEachFuturesDestValues([&](const CFuturesUserKey& key, const CFuturesUserValue& destination) { - if (key.height < maxBlockHeight - depth) { - return false; - } - - if (!isMatchOwner(key.owner)) { - return true; - } - - if (isMine && !(IsMineCached(*pwallet, key.owner) & filter)) { - return true; - } - - const auto userValue = pcustomcsview->GetFuturesUserValues(key); - if (!userValue) { - return true; - } - - const auto& source = userValue.val->source; - - if (!tokenFilter.empty()) { - if (tokenID != source.nTokenId && tokenID != destination.source.nTokenId) { - return true; - } - } - - const auto sourceToken = pcustomcsview->GetToken(source.nTokenId); - if (!sourceToken) { - return true; - } - - const auto destToken = pcustomcsview->GetToken(destination.source.nTokenId); - if (!destToken) { - return true; - } - - CTxDestination dest; - if (!ExtractDestination(key.owner, dest)) { - return true; - } - - UniValue item(UniValue::VOBJ); - item.pushKV("height", static_cast(destination.destination)); - item.pushKV("address", EncodeDestination(dest)); - item.pushKV("source", GetDecimaleString(source.nValue) + '@' + sourceToken->symbol); - item.pushKV("destination", GetDecimaleString(destination.source.nValue) + '@' + destToken->symbol); - result.push_back(item); - - return --limit > 0; - }, {maxBlockHeight, account, std::numeric_limits::max()}); - - return result; -} - - static const CRPCCommand commands[] = { // category name actor (function) params @@ -2567,7 +2359,6 @@ static const CRPCCommand commands[] = {"accounts", "withdrawfutureswap", &withdrawfutureswap, {"address", "amount", "destination", "inputs"}}, {"accounts", "listpendingfutureswaps", &listpendingfutureswaps, {}}, {"accounts", "getpendingfutureswaps", &getpendingfutureswaps, {"address"}}, - {"accounts", "listfutureswaphistory", &listfutureswaphistory, {"owner", "options"}}, }; void RegisterAccountsRPCCommands(CRPCTable& tableRPC) { diff --git a/src/masternodes/rpc_oracles.cpp b/src/masternodes/rpc_oracles.cpp index 42ef3b8102..93b3c8c311 100644 --- a/src/masternodes/rpc_oracles.cpp +++ b/src/masternodes/rpc_oracles.cpp @@ -1140,12 +1140,12 @@ UniValue getfutureswapblock(const JSONRPCRequest& request) { const auto currentHeight = ::ChainActive().Height(); - const auto blockAndReward = GetFuturesBlockAndReward(); - if (!blockAndReward) { + const auto block = GetFuturesBlock(); + if (!block) { return 0; } - return currentHeight + (blockAndReward->first - (currentHeight % blockAndReward->first)); + return currentHeight + (*block - (currentHeight % *block)); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 5bec1b704d..48b8ab26b0 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -307,7 +307,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getaccounthistory", 2, "txn" }, { "listburnhistory", 0, "options" }, { "accounthistorycount", 1, "options" }, - { "listfutureswaphistory", 1, "options" }, { "setgov", 0, "variables" }, { "setgov", 1, "inputs" }, diff --git a/src/validation.cpp b/src/validation.cpp index 57179955e9..1b1e272a30 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3346,19 +3346,21 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache auto burned = attributes->GetValue(burnKey, CBalances{}); - const uint32_t startHeight = pindex->nHeight - blockPeriod; std::map unpaidContracts; - cache.ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues){ - if (key.height <= startHeight) { - return false; - } + std::set deletionPending; + + CHistoryWriters writers{paccountHistoryDB.get(), nullptr, nullptr}; + CAccountsHistoryWriter view(cache, pindex->nHeight, ~0u, {}, uint8_t(CustomTxType::FutureSwapExecution), &writers); - const auto source = cache.GetLoanTokenByID(futuresValues.source.nTokenId); + view.ForEachFuturesUserValues([&](const CFuturesUserKey& key, const CFuturesUserValue& futuresValues){ + deletionPending.insert(key); + + const auto source = view.GetLoanTokenByID(futuresValues.source.nTokenId); assert(source); if (source->symbol == "DUSD") { const DCT_ID destId{futuresValues.destination}; - const auto destToken = cache.GetLoanTokenByID(destId); + const auto destToken = view.GetLoanTokenByID(destId); assert(destToken); try { @@ -3366,9 +3368,8 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache if (premiumPrice > 0) { const auto total = DivideAmounts(futuresValues.source.nValue, premiumPrice); CTokenAmount destination{destId, total}; - cache.AddBalance(key.owner, destination); + view.AddBalance(key.owner, destination); burned.Add(futuresValues.source); - cache.StoreFuturesDestValues(key, {destination, static_cast(pindex->nHeight)}); LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Owner %s source %s destination %s\n", key.owner.GetHex(), futuresValues.source.ToString(), destination.ToString()); } @@ -3377,16 +3378,15 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache } } else { - const auto tokenDUSD = cache.GetToken("DUSD"); + const auto tokenDUSD = view.GetToken("DUSD"); assert(tokenDUSD); try { const auto& discountPrice = futuresPrices.at(futuresValues.source.nTokenId).discount; const auto total = MultiplyAmounts(futuresValues.source.nValue, discountPrice); CTokenAmount destination{tokenDUSD->first, total}; - cache.AddBalance(key.owner, destination); + view.AddBalance(key.owner, destination); burned.Add(futuresValues.source); - cache.StoreFuturesDestValues(key, {destination, static_cast(pindex->nHeight)}); LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Payment Owner %s source %s destination %s\n", key.owner.GetHex(), futuresValues.source.ToString(), destination.ToString()); } catch (const std::out_of_range&) { @@ -3397,6 +3397,8 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache return true; }, {static_cast(pindex->nHeight), {}, std::numeric_limits::max()}); + view.Flush(); + const auto contractAddressValue = GetFutureSwapContractAddress(); assert(contractAddressValue); @@ -3404,16 +3406,24 @@ void CChainState::ProcessFutures(const CBlockIndex* pindex, CCustomCSView& cache auto balances = attributes->GetValue(liveKey, CBalances{}); + CHistoryWriters refundWriters{paccountHistoryDB.get(), nullptr, nullptr}; + CAccountsHistoryWriter refundView(cache, pindex->nHeight, ~0u - 1, {}, uint8_t(CustomTxType::FutureSwapRefund), &refundWriters); + // Refund unpaid contracts for (const auto& [key, value] : unpaidContracts) { - cache.SubBalance(*contractAddressValue, value.source); - cache.AddBalance(key.owner, value.source); - cache.StoreFuturesDestValues(key, {value.source, static_cast(pindex->nHeight)}); + refundView.SubBalance(*contractAddressValue, value.source); + refundView.AddBalance(key.owner, value.source); LogPrint(BCLog::FUTURESWAP, "ProcessFutures(): Refund Owner %s source %s destination %s\n", key.owner.GetHex(), value.source.ToString(), value.source.ToString()); balances.Sub(value.source); } + refundView.Flush(); + + for (const auto& key : deletionPending) { + cache.EraseFuturesUserValues(key); + } + attributes->attributes[burnKey] = burned; if (!unpaidContracts.empty()) { diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index fb93bfe1bc..86bda75d6c 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -55,8 +55,9 @@ def run_test(self): def setup_test(self): - # Store address + # Store addresses self.address = self.nodes[0].get_genesis_keys().ownerAuthAddress + self.contract_address = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc' # Store interval self.futures_interval = 25 @@ -326,7 +327,7 @@ def test_dtoken_to_dusd(self): assert_equal(len(result['values']), 0) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on listgovs @@ -349,10 +350,10 @@ def test_dtoken_to_dusd(self): # Populate RPC check self.list_history.append({'height': self.nodes[0].getblockcount(), 'swaps': [ - {'address': address_tsla, 'source': f'{Decimal("1.00000000")}@{self.symbolTSLA}', 'destination': f'{self.prices[0]["discountPrice"]}@{self.symbolDUSD}'}, - {'address': address_googl, 'source': f'{Decimal("1.00000000")}@{self.symbolGOOGL}', 'destination': f'{self.prices[1]["discountPrice"]}@{self.symbolDUSD}'}, - {'address': address_twtr, 'source': f'{Decimal("1.00000000")}@{self.symbolTWTR}', 'destination': f'{self.prices[1]["discountPrice"]}@{self.symbolDUSD}'}, - {'address': address_msft, 'source': f'{Decimal("1.00000000")}@{self.symbolMSFT}', 'destination': f'{self.prices[3]["discountPrice"]}@{self.symbolDUSD}'}, + {'address': address_tsla, 'destination': f'{self.prices[0]["discountPrice"]}@{self.symbolDUSD}'}, + {'address': address_googl, 'destination': f'{self.prices[1]["discountPrice"]}@{self.symbolDUSD}'}, + {'address': address_twtr, 'destination': f'{self.prices[2]["discountPrice"]}@{self.symbolDUSD}'}, + {'address': address_msft, 'destination': f'{self.prices[3]["discountPrice"]}@{self.symbolDUSD}'}, ]}) def test_dusd_to_dtoken(self): @@ -441,7 +442,7 @@ def test_dusd_to_dtoken(self): assert_equal(len(result['values']), 0) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'3992.10000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on listgovs @@ -464,10 +465,10 @@ def test_dusd_to_dtoken(self): # Populate RPC check self.list_history.append({'height': self.nodes[0].getblockcount(), 'swaps': [ - {'address': address_tsla, 'source': f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}', 'destination': f'1.00000000@{self.symbolTSLA}'}, - {'address': address_googl, 'source': f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}', 'destination': f'1.00000000@{self.symbolGOOGL}'}, - {'address': address_twtr, 'source': f'{self.prices[2]["premiumPrice"]}@{self.symbolDUSD}', 'destination': f'1.00000000@{self.symbolTWTR}'}, - {'address': address_msft, 'source': f'{self.prices[3]["premiumPrice"]}@{self.symbolDUSD}', 'destination': f'1.00000000@{self.symbolMSFT}'}, + {'address': address_tsla, 'destination': f'1.00000000@{self.symbolTSLA}'}, + {'address': address_googl, 'destination': f'1.00000000@{self.symbolGOOGL}'}, + {'address': address_twtr, 'destination': f'1.00000000@{self.symbolTWTR}'}, + {'address': address_msft, 'destination': f'1.00000000@{self.symbolMSFT}'}, ]}) def check_swap_block_range(self): @@ -504,7 +505,7 @@ def check_swap_block_range(self): # Populate RPC check self.list_history.append({'height': self.nodes[0].getblockcount(), 'swaps': [ - {'address': address, 'source': f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}', 'destination': f'1.00000000@{self.symbolTSLA}'}, + {'address': address, 'destination': f'1.00000000@{self.symbolTSLA}'}, ]}) # Move to next futures block @@ -516,7 +517,7 @@ def check_swap_block_range(self): assert_equal(result, [f'913.50000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'4905.60000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) def check_multiple_swaps(self): @@ -562,7 +563,7 @@ def check_multiple_swaps(self): assert_equal(result, [f'2.00000000@{self.symbolTWTR}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'6810.30000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) def check_withdrawals(self): @@ -676,7 +677,7 @@ def check_withdrawals(self): assert_equal(result, [f'0.00000001@{self.symbolDUSD}', f'1.99999999@{self.symbolMSFT}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.64999999@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on listgovs @@ -709,7 +710,7 @@ def check_minimum_swaps(self): assert_equal(result, [f'{self.prices[0]["premiumPrice"] - Decimal("0.00000001")}@{self.symbolDUSD}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.65000000@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Create user futures contract to purchase one Satoshi of TSLA @@ -726,7 +727,7 @@ def check_minimum_swaps(self): assert_equal(result, [f'{self.prices[0]["premiumPrice"] - Decimal("0.00000001") - Decimal(min_purchase)}@{self.symbolDUSD}', f'0.00000001@{self.symbolTSLA}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.65000914@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) def check_gov_var_change(self): @@ -747,7 +748,7 @@ def check_gov_var_change(self): self.nodes[0].generate(1) # Check contract address has updated - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.65000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Test changing block period while DFIP2203 still active @@ -758,13 +759,9 @@ def check_gov_var_change(self): self.nodes[0].generate(1) # Check contract address has not changed, no refund on disabling DFIP2203. - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.65000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) - # Test changing block period to include historical future contracts - self.futures_interval = self.futures_interval * 2 - assert_raises_rpc_error(-32600, 'Historical Futures contracts in this period', self.nodes[0].setgov, {"ATTRIBUTES":{'v0/params/dfip2203/block_period':f'{self.futures_interval}'}}) - # Move to next futures block next_futures_block = self.nodes[0].getblockcount() + (self.futures_interval - (self.nodes[0].getblockcount() % self.futures_interval)) self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) @@ -795,6 +792,30 @@ def check_gov_var_change(self): self.nodes[0].setgov({"ATTRIBUTES":{'v0/params/dfip2203/active':'false'}}) self.nodes[0].generate(1) + # Check refunds show up in history + result = self.nodes[0].listaccounthistory('all', {"maxBlockHeight":self.nodes[0].getblockcount(), 'depth':0, 'txtype':'w'}) + assert_equal(result[0]['owner'], self.contract_address) + assert_equal(result[0]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[0]['type'], 'FutureSwapRefund') + assert_equal(result[0]['amounts'], [f'{-self.prices[0]["premiumPrice"] - self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) + if result[1]['owner'] == address_googl: + assert_equal(result[1]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[1]['type'], 'FutureSwapRefund') + assert_equal(result[1]['amounts'], [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) + assert_equal(result[2]['owner'], address_tsla) + assert_equal(result[2]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[2]['type'], 'FutureSwapRefund') + assert_equal(result[2]['amounts'], [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) + else: + assert_equal(result[1]['owner'], address_tsla) + assert_equal(result[1]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[1]['type'], 'FutureSwapRefund') + assert_equal(result[1]['amounts'], [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) + assert_equal(result[2]['owner'], address_googl) + assert_equal(result[2]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[2]['type'], 'FutureSwapRefund') + assert_equal(result[2]['amounts'], [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) + # Balances should be restored result = self.nodes[0].getaccount(address_tsla) assert_equal(result, [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) @@ -802,7 +823,7 @@ def check_gov_var_change(self): assert_equal(result, [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) # Check contract address remains the same - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'7468.65000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Enable DFIP2203 @@ -844,7 +865,7 @@ def check_gov_var_change(self): assert_equal(result, [f'1.00000000@{self.symbolTSLA}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on listgovs @@ -877,17 +898,20 @@ def unpaid_contract(self): self.nodes[0].generate(next_futures_block - self.nodes[0].getblockcount()) # Check refund in history - result = self.nodes[0].listfutureswaphistory() - assert_equal(result[0]['address'], address) - assert_equal(result[0]['source'], f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}') - assert_equal(result[0]['destination'], f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}') + result = self.nodes[0].listaccounthistory('all', {"maxBlockHeight":self.nodes[0].getblockcount(), 'depth':0}) + assert_equal(result[0]['owner'], self.contract_address) + assert_equal(result[0]['type'], 'FutureSwapRefund') + assert_equal(result[0]['amounts'], [f'{-self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) + assert_equal(result[1]['owner'], address) + assert_equal(result[1]['type'], 'FutureSwapRefund') + assert_equal(result[0]['amounts'], [f'{-self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) # Check user has been refunded result = self.nodes[0].getaccount(address) assert_equal(result, [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) # Check contract address - result = self.nodes[0].getaccount('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpsqgljc') + result = self.nodes[0].getaccount(self.contract_address) assert_equal(result, [f'8382.15000915@{self.symbolDUSD}', f'1.00000000@{self.symbolTSLA}', f'1.00000000@{self.symbolGOOGL}', f'1.00000000@{self.symbolTWTR}', f'1.00000000@{self.symbolMSFT}']) # Check DFI2203 address on listgovs @@ -902,41 +926,33 @@ def rpc_history(self): # Check some historical swaps for history in self.list_history: - result = self.nodes[0].listfutureswaphistory('all', {"maxBlockHeight":history['height'], "depth":1}) - swap_count = len(result) - assert_equal(len(result), swap_count) - for index in range(swap_count): - assert_equal(result[index]['height'], history['height']) - assert_equal(result[index]['address'], history['swaps'][index]['address']) - assert_equal(result[index]['source'], history['swaps'][index]['source']) - assert_equal(result[index]['destination'], history['swaps'][index]['destination']) + result = self.nodes[0].listaccounthistory('all', {"maxBlockHeight":history['height'], 'depth':0, 'txtype':'q'}) + for history_entry in history['swaps']: + found = False + for result_entry in result: + assert_equal(history['height'], result_entry['blockHeight']) + if result_entry['owner'] == history_entry['address']: + assert_equal(result_entry['owner'], history_entry['address']) + assert_equal(result_entry['type'], 'FutureSwapExecution') + assert_equal(result_entry['amounts'], [history_entry['destination']]) + found = True + assert(found) # Check all swaps present - result = self.nodes[0].listfutureswaphistory('all') - assert_equal(len(result), 21) + result = self.nodes[0].listaccounthistory('all', {'txtype':'q'}) + assert_equal(len(result), 15) - # Check swap by specific address - result = self.nodes[0].listfutureswaphistory(self.list_history[0]['swaps'][0]['address']) - assert_equal(len(result), 1) - assert_equal(result[0]['height'], self.list_history[0]['height']) - assert_equal(result[0]['address'], self.list_history[0]['swaps'][0]['address']) - assert_equal(result[0]['source'], self.list_history[0]['swaps'][0]['source']) - assert_equal(result[0]['destination'], self.list_history[0]['swaps'][0]['destination']) - - # Check all wallet swaps present, still all of them! - result = self.nodes[0].listfutureswaphistory('mine') - assert_equal(len(result), 21) + # Check all swap refunds present + result = self.nodes[0].listaccounthistory('all', {'txtype':'w'}) + assert_equal(len(result), 7) - # Check limit working - result = self.nodes[0].listfutureswaphistory('all', {'limit': 1}) + # Check swap by specific address + result = self.nodes[0].listaccounthistory(self.list_history[0]['swaps'][0]['address'], {'txtype':'q'}) assert_equal(len(result), 1) + assert_equal(result[0]['blockHeight'], self.list_history[0]['height']) + assert_equal(result[0]['owner'], self.list_history[0]['swaps'][0]['address']) + assert_equal(result[0]['amounts'], [self.list_history[0]['swaps'][0]['destination']]) - # Filter on token - result = self.nodes[0].listfutureswaphistory('all', {'token': 'MSFT'}) - assert_equal(len(result), 3) - for history in result: - if history['source'].find('MSFT') == -1: - assert(history['destination'].find('MSFT') != -1) if __name__ == '__main__': FuturesTest().main() From bbb94bb1f651ba78b1191c621c743fcb70a64252 Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Tue, 29 Mar 2022 15:16:08 +0100 Subject: [PATCH 6/7] tests: Reduce duplication --- test/functional/feature_futures.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/functional/feature_futures.py b/test/functional/feature_futures.py index 86bda75d6c..e5dc4fabc4 100755 --- a/test/functional/feature_futures.py +++ b/test/functional/feature_futures.py @@ -798,22 +798,18 @@ def check_gov_var_change(self): assert_equal(result[0]['blockHeight'], self.nodes[0].getblockcount()) assert_equal(result[0]['type'], 'FutureSwapRefund') assert_equal(result[0]['amounts'], [f'{-self.prices[0]["premiumPrice"] - self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) + assert_equal(result[1]['type'], 'FutureSwapRefund') + assert_equal(result[2]['type'], 'FutureSwapRefund') + assert_equal(result[1]['blockHeight'], self.nodes[0].getblockcount()) + assert_equal(result[2]['blockHeight'], self.nodes[0].getblockcount()) if result[1]['owner'] == address_googl: - assert_equal(result[1]['blockHeight'], self.nodes[0].getblockcount()) - assert_equal(result[1]['type'], 'FutureSwapRefund') assert_equal(result[1]['amounts'], [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) assert_equal(result[2]['owner'], address_tsla) - assert_equal(result[2]['blockHeight'], self.nodes[0].getblockcount()) - assert_equal(result[2]['type'], 'FutureSwapRefund') assert_equal(result[2]['amounts'], [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) else: assert_equal(result[1]['owner'], address_tsla) - assert_equal(result[1]['blockHeight'], self.nodes[0].getblockcount()) - assert_equal(result[1]['type'], 'FutureSwapRefund') assert_equal(result[1]['amounts'], [f'{self.prices[0]["premiumPrice"]}@{self.symbolDUSD}']) assert_equal(result[2]['owner'], address_googl) - assert_equal(result[2]['blockHeight'], self.nodes[0].getblockcount()) - assert_equal(result[2]['type'], 'FutureSwapRefund') assert_equal(result[2]['amounts'], [f'{self.prices[1]["premiumPrice"]}@{self.symbolDUSD}']) # Balances should be restored From e0f9b0c21cd755906aedfd7ed267ed0a785e9400 Mon Sep 17 00:00:00 2001 From: Prasanna Loganathar Date: Wed, 30 Mar 2022 11:15:21 +0530 Subject: [PATCH 7/7] Fix lints and reorg file --- test/lint/lint-circular-dependencies.sh | 69 ++++++++++++------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh index 354c4a8cb3..785c924d85 100755 --- a/test/lint/lint-circular-dependencies.sh +++ b/test/lint/lint-circular-dependencies.sh @@ -9,73 +9,72 @@ export LC_ALL=C EXPECTED_CIRCULAR_DEPENDENCIES=( - "chainparamsbase -> util/system -> chainparamsbase" - "index/txindex -> validation -> index/txindex" - "policy/fees -> txmempool -> policy/fees" - "txmempool -> validation -> txmempool" - "wallet/coincontrol -> wallet/wallet -> wallet/coincontrol" - "wallet/fees -> wallet/wallet -> wallet/fees" - "wallet/wallet -> wallet/walletdb -> wallet/wallet" - "policy/fees -> txmempool -> validation -> policy/fees" - "txmempool -> validation -> validationinterface -> txmempool" - "wallet/ismine -> wallet/wallet -> wallet/ismine" "chain -> chainparams -> masternodes/mn_checks -> index/txindex -> chain" - "chain -> chainparams -> masternodes/mn_checks -> validation -> chain" "chain -> chainparams -> masternodes/mn_checks -> index/txindex -> txdb -> chain" + "chain -> chainparams -> masternodes/mn_checks -> masternodes/vaulthistory -> chain" + "chain -> chainparams -> masternodes/mn_checks -> validation -> chain" "chain -> chainparams -> masternodes/mn_checks -> validation -> versionbits -> chain" "chain -> chainparams -> masternodes/mn_checks -> validation -> wallet/wallet -> chain" - "chain -> chainparams -> masternodes/mn_checks -> masternodes/vaulthistory -> chain" "chainparams -> key_io -> chainparams" - "chainparams -> masternodes/mn_checks -> validation -> chainparams" - "chainparams -> masternodes/mn_checks -> index/txindex -> index/base -> chainparams" - "chainparams -> masternodes/mn_checks -> validation -> spv/spv_wrapper -> chainparams" - "chainparams -> masternodes/mn_checks -> validation -> wallet/wallet -> chainparams" "chainparams -> masternodes/mn_checks -> chainparams" + "chainparams -> masternodes/mn_checks -> index/txindex -> index/base -> chainparams" "chainparams -> masternodes/mn_checks -> masternodes/anchors -> chainparams" "chainparams -> masternodes/mn_checks -> masternodes/vaulthistory -> masternodes/vault -> chainparams" + "chainparams -> masternodes/mn_checks -> txmempool -> chainparams" + "chainparams -> masternodes/mn_checks -> validation -> chainparams" + "chainparams -> masternodes/mn_checks -> validation -> spv/spv_wrapper -> chainparams" + "chainparams -> masternodes/mn_checks -> validation -> wallet/wallet -> chainparams" + "chainparamsbase -> util/system -> chainparamsbase" "consensus/tx_verify -> masternodes/masternodes -> validation -> consensus/tx_verify" "consensus/tx_verify -> masternodes/mn_checks -> txmempool -> consensus/tx_verify" - "masternodes/govvariables/attributes -> masternodes/masternodes -> validation -> masternodes/govvariables/attributes" + "index/txindex -> validation -> index/txindex" + "masternodes/accountshistory -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/accountshistory" + "masternodes/accountshistory -> masternodes/masternodes -> validation -> masternodes/accountshistory" + "masternodes/anchors -> masternodes/masternodes -> masternodes/anchors" + "masternodes/anchors -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/anchors" + "masternodes/anchors -> masternodes/masternodes -> net_processing -> masternodes/anchors" + "masternodes/anchors -> spv/spv_wrapper -> masternodes/anchors" + "masternodes/anchors -> validation -> masternodes/anchors" "masternodes/govvariables/attributes -> masternodes/gv -> masternodes/govvariables/attributes" + "masternodes/govvariables/attributes -> masternodes/masternodes -> validation -> masternodes/govvariables/attributes" + "masternodes/govvariables/attributes -> masternodes/mn_checks -> masternodes/govvariables/attributes" "masternodes/govvariables/icx_takerfee_per_btc -> masternodes/gv -> masternodes/govvariables/icx_takerfee_per_btc" "masternodes/govvariables/loan_daily_reward -> masternodes/gv -> masternodes/govvariables/loan_daily_reward" + "masternodes/govvariables/loan_daily_reward -> masternodes/masternodes -> validation -> masternodes/govvariables/loan_daily_reward" "masternodes/govvariables/loan_liquidation_penalty -> masternodes/gv -> masternodes/govvariables/loan_liquidation_penalty" "masternodes/govvariables/loan_splits -> masternodes/gv -> masternodes/govvariables/loan_splits" "masternodes/govvariables/lp_daily_dfi_reward -> masternodes/gv -> masternodes/govvariables/lp_daily_dfi_reward" "masternodes/govvariables/lp_daily_dfi_reward -> masternodes/masternodes -> validation -> masternodes/govvariables/lp_daily_dfi_reward" + "masternodes/govvariables/lp_splits -> masternodes/gv -> masternodes/govvariables/lp_splits" "masternodes/govvariables/oracle_block_interval -> masternodes/gv -> masternodes/govvariables/oracle_block_interval" "masternodes/govvariables/oracle_block_interval -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/govvariables/oracle_block_interval" - "masternodes/govvariables/attributes -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/govvariables/attributes" "masternodes/govvariables/oracle_deviation -> masternodes/gv -> masternodes/govvariables/oracle_deviation" - "masternodes/govvariables/lp_splits -> masternodes/gv -> masternodes/govvariables/lp_splits" - "masternodes/govvariables/attributes -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/govvariables/attributes" - "masternodes/masternodes -> masternodes/oracles -> masternodes/masternodes" - "masternodes/govvariables/loan_daily_reward -> masternodes/masternodes -> validation -> masternodes/govvariables/loan_daily_reward" "masternodes/masternodes -> masternodes/mn_checks -> masternodes/masternodes" - "masternodes/masternodes -> validation -> masternodes/masternodes" + "masternodes/masternodes -> masternodes/mn_checks -> masternodes/vaulthistory -> masternodes/masternodes" + "masternodes/masternodes -> masternodes/oracles -> masternodes/masternodes" "masternodes/masternodes -> net_processing -> masternodes/masternodes" + "masternodes/masternodes -> validation -> masternodes/masternodes" "masternodes/masternodes -> wallet/wallet -> masternodes/masternodes" "masternodes/mn_checks -> txmempool -> masternodes/mn_checks" "masternodes/mn_checks -> validation -> masternodes/mn_checks" "masternodes/mn_checks -> validation -> wallet/wallet -> masternodes/mn_checks" - "masternodes/masternodes -> masternodes/mn_checks -> masternodes/vaulthistory -> masternodes/masternodes" - "masternodes/anchors -> spv/spv_wrapper -> masternodes/anchors" - "masternodes/anchors -> validation -> masternodes/anchors" - "masternodes/anchors -> masternodes/masternodes -> masternodes/anchors" - "masternodes/anchors -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/anchors" - "masternodes/anchors -> masternodes/masternodes -> net_processing -> masternodes/anchors" - "masternodes/accountshistory -> masternodes/masternodes -> masternodes/mn_checks -> masternodes/accountshistory" - "masternodes/accountshistory -> masternodes/masternodes -> validation -> masternodes/accountshistory" "net_processing -> validation -> net_processing" - "validation -> wallet/wallet -> validation" + "policy/fees -> txmempool -> policy/fees" + "policy/fees -> txmempool -> validation -> policy/fees" "policy/fees -> txmempool -> validation -> wallet/wallet -> policy/fees" "policy/fees -> txmempool -> validation -> wallet/wallet -> util/fees -> policy/fees" - "chainparams -> masternodes/mn_checks -> txmempool -> chainparams" - "pos_kernel -> validation -> pos_kernel" + "pos -> pos_kernel -> pos" "pos -> validation -> pos" "pos -> validation -> txdb -> pos" + "pos_kernel -> validation -> pos_kernel" "pos_kernel -> validation -> txdb -> pos_kernel" - "pos -> pos_kernel -> pos" + "txmempool -> validation -> txmempool" + "txmempool -> validation -> validationinterface -> txmempool" + "validation -> wallet/wallet -> validation" + "wallet/coincontrol -> wallet/wallet -> wallet/coincontrol" + "wallet/fees -> wallet/wallet -> wallet/fees" + "wallet/ismine -> wallet/wallet -> wallet/ismine" + "wallet/wallet -> wallet/walletdb -> wallet/wallet" ) EXIT_CODE=0