From 97fd747de293b1303ad143aa83bdcec229266b19 Mon Sep 17 00:00:00 2001 From: miketout Date: Sun, 11 Sep 2022 17:40:44 -0700 Subject: [PATCH 01/11] Fix source of notarization protocol --- src/pbaas/notarization.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pbaas/notarization.cpp b/src/pbaas/notarization.cpp index 6520542eea3..65c990465c6 100644 --- a/src/pbaas/notarization.cpp +++ b/src/pbaas/notarization.cpp @@ -3560,14 +3560,14 @@ bool CPBaaSNotarization::ConfirmOrRejectNotarizations(CWallet *pWallet, } } else if (cnd.forks.size() && - (cnd.forks[0].size() > 2 || ConnectedChains.ThisChain().notarizationProtocol != CCurrencyDefinition::NOTARIZATION_AUTO)) + (cnd.forks[0].size() > 2 || pNotaryCurrency->notarizationProtocol != CCurrencyDefinition::NOTARIZATION_AUTO)) { bestFork = cnd.forks[0]; } bool isFirstConfirmedCND = cnd.vtx[cnd.lastConfirmed].second.IsBlockOneNotarization() || cnd.vtx[cnd.lastConfirmed].second.IsDefinitionNotarization(); - if ((bestFork.size() < ((ConnectedChains.ThisChain().notarizationProtocol == CCurrencyDefinition::NOTARIZATION_AUTO) ? 3 : 2)) || + if ((bestFork.size() < ((pNotaryCurrency->notarizationProtocol == CCurrencyDefinition::NOTARIZATION_AUTO) ? 3 : 2)) || (!isFirstConfirmedCND && !cnd.vtx[cnd.lastConfirmed].second.proofRoots.count(SystemID))) { return state.Error("insufficient validator confirmations"); From f7abe0767d99a3f05c34683e37dda930a10338fa Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 13:10:27 -0700 Subject: [PATCH 02/11] More validation on bridgekeeper returned data --- src/pbaas/notarization.cpp | 57 ++++++++++++++++++++++++++++++-------- src/pbaas/pbaas.cpp | 4 ++- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/pbaas/notarization.cpp b/src/pbaas/notarization.cpp index 65c990465c6..0d137db1224 100644 --- a/src/pbaas/notarization.cpp +++ b/src/pbaas/notarization.cpp @@ -2784,6 +2784,30 @@ bool CPBaaSNotarization::CreateEarnedNotarization(const CRPCChainData &externalS return state.Error(result.isNull() ? "no-notary" : "no-matching-proof-roots-found"); } + CProofRoot lastStableProofRoot(find_value(result, "laststableproofroot")); + + // work around race condition or Infura API issue under investigation in ETH bridge, where it does not confirm + // one of our proof roots, while at the same time returning identical data in laststableproofroot. + if (!lastConfirmedProofRoot.IsValid() && lastStableProofRoot.IsValid()) + { + for (int i = cnd.vtx.size() - 1; i >= 0; i--) + { + auto it = cnd.vtx[i].second.proofRoots.find(SystemID); + if (it != cnd.vtx[i].second.proofRoots.end()) + { + if (it->second.rootHeight < lastStableProofRoot.rootHeight) + { + break; + } + else if (it->second.rootHeight == lastStableProofRoot.rootHeight && + it->second == lastStableProofRoot && notaryIdx != i) + { + notaryIdx = i; + } + } + } + } + // now, we have the index for the transaction and notarization we agree with, a list of those we consider invalid, // and the most recent notarization to use when creating the new one const CTransaction &priorNotarizationTx = txes[notaryIdx].first; @@ -3451,10 +3475,6 @@ bool CPBaaSNotarization::ConfirmOrRejectNotarizations(CWallet *pWallet, std::vector> imsigner, watchonly; LOCK(pWallet->cs_wallet); pWallet->GetIdentities(pNotaryCurrency->notaries, mine, imsigner, watchonly); - if (!mine.size()) - { - return state.Error("no-notary"); - } } { @@ -3635,6 +3655,9 @@ bool CPBaaSNotarization::ConfirmOrRejectNotarizations(CWallet *pWallet, return state.Error(result.isNull() ? "no-notary" : "no-matching-notarization-found"); } + // get the index from the best fork to make it an index into cnd.vtx + notaryIdx = bestFork[notaryIdx]; + // take the lock again, now that we're back from calling out LOCK(cs_main); @@ -3726,24 +3749,24 @@ bool CPBaaSNotarization::ConfirmOrRejectNotarizations(CWallet *pWallet, indexKey.GetHex().c_str()); */ std::vector toRemove; std::map outputMap; - for (int i = 0; i < mempoolUnspent.size(); i++) + for (int j = 0; j < mempoolUnspent.size(); j++) { - if (mempoolUnspent[i].first.spending) + if (mempoolUnspent[j].first.spending) { - auto it = outputMap.find(COutPoint(mempoolUnspent[i].second.prevhash, mempoolUnspent[i].second.prevout)); + auto it = outputMap.find(COutPoint(mempoolUnspent[j].second.prevhash, mempoolUnspent[j].second.prevout)); if (it != outputMap.end()) { - it->second < i ? toRemove.push_back(it->second) : toRemove.push_back(i); - it->second < i ? toRemove.push_back(i) : toRemove.push_back(it->second); + it->second < j ? toRemove.push_back(it->second) : toRemove.push_back(j); + it->second < j ? toRemove.push_back(j) : toRemove.push_back(it->second); } else { - toRemove.push_back(i); + toRemove.push_back(j); } } else { - outputMap.insert(std::make_pair(COutPoint(mempoolUnspent[i].first.txhash, mempoolUnspent[i].first.index), i)); + outputMap.insert(std::make_pair(COutPoint(mempoolUnspent[j].first.txhash, mempoolUnspent[j].first.index), j)); } } for (auto it = toRemove.rbegin(); it != toRemove.rend(); it++) @@ -3790,6 +3813,15 @@ bool CPBaaSNotarization::ConfirmOrRejectNotarizations(CWallet *pWallet, LogPrintf("txid: %s:%d, nValue: %ld\n", oneSpend.txIn.prevout.hash.GetHex().c_str(), oneSpend.txIn.prevout.n, oneSpend.nValue); } } + for (int j = 0; j < evidenceVec.size(); j++) + { + auto &oneEvidenceVec = evidenceVec[j]; + LogPrintf("evidence vector: index #%d\n", j); + for (auto &oneEvidence : oneEvidenceVec) + { + LogPrintf("%s\n", oneEvidence.ToUniValue().write(1,2).c_str()); + } + } } CNotaryEvidence ne(ASSETCHAINS_CHAINID, cnd.vtx[idx].first, CNotaryEvidence::STATE_CONFIRMING); @@ -5281,6 +5313,7 @@ bool ValidateFinalizeNotarization(struct CCcontract_info *cp, Eval* eval, const return true; } } + return eval->Error("Invalid spend of confirmed finalization to transaction with no confirmed output"); } // get currency to determine system and notarization method @@ -5372,7 +5405,7 @@ bool ValidateFinalizeNotarization(struct CCcontract_info *cp, Eval* eval, const // TODO: HARDENING - complete // validate both rejection and confirmation // in order to finalize confirmation and not just rejection, we need to spend the last - // confirmed transaction. that means that if this finalization asserts it is confirmed, we must find the + // confirmed transaction. that means that if this finalization asserts it is confirmed, we must prove it if (newFinalization.IsConfirmed()) { } diff --git a/src/pbaas/pbaas.cpp b/src/pbaas/pbaas.cpp index 613ff88c99d..a5ff1dd337b 100644 --- a/src/pbaas/pbaas.cpp +++ b/src/pbaas/pbaas.cpp @@ -3339,7 +3339,9 @@ bool CConnectedChains::CheckVerusPBaaSAvailable() if (!chainInfo.isNull()) { params.push_back(EncodeDestination(CIdentityID(FirstNotaryChain().chainDefinition.GetID()))); - chainDef = find_value(RPCCallRoot("getcurrency", params), "result"); + chainDef = FirstNotaryChain().chainDefinition.launchSystemID == ASSETCHAINS_CHAINID ? + FirstNotaryChain().chainDefinition.ToUniValue() : + find_value(RPCCallRoot("getcurrency", params), "result"); if (!chainDef.isNull() && CheckVerusPBaaSAvailable(chainInfo, chainDef)) { From e8098bee54429f68d5e6d2f4990d03db6f443b67 Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 13:20:14 -0700 Subject: [PATCH 03/11] Log if we get a discrepancy in bestindex and laststableproofroot --- src/pbaas/notarization.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pbaas/notarization.cpp b/src/pbaas/notarization.cpp index 0d137db1224..8b4ad5b4113 100644 --- a/src/pbaas/notarization.cpp +++ b/src/pbaas/notarization.cpp @@ -2802,6 +2802,7 @@ bool CPBaaSNotarization::CreateEarnedNotarization(const CRPCChainData &externalS else if (it->second.rootHeight == lastStableProofRoot.rootHeight && it->second == lastStableProofRoot && notaryIdx != i) { + LogPrintf("%s: notarization was rejected with identical proof root to last stable: %s\n", __func__, cnd.vtx[i].second.ToUniValue().write(1,2).c_str()); notaryIdx = i; } } From 89006d39b4ba2b51d0097d1864669e288955731e Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 14:15:24 -0700 Subject: [PATCH 04/11] ETH NFT support --- src/core_write.cpp | 17 ++++++++++++++ src/key_io.cpp | 21 +++++++++++++++++ src/pbaas/crosschainrpc.h | 47 +++++++++------------------------------ 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/src/core_write.cpp b/src/core_write.cpp index f052d02ebe7..ebef0e23f3b 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -883,6 +883,14 @@ UniValue CReserveDeposit::ToUniValue() const return ret; } +UniValue CETHNFTAddress::ToUniValue() const +{ + UniValue ret(UniValue::VOBJ); + ret.pushKV("contract", "0x" + HexBytes(contractID.begin(), contractID.size())); + ret.pushKV("tokenid", "0x" + HexBytes(tokenID.begin(), tokenID.size())); + return ret; +} + UniValue CTransferDestination::ToUniValue() const { UniValue destVal = UniValue(UniValue::VOBJ); @@ -918,6 +926,15 @@ UniValue CTransferDestination::ToUniValue() const destVal.push_back(Pair("address", EncodeEthDestination(uint160(destination)))); break; + case CTransferDestination::DEST_ETHNFT: + { + CETHNFTAddress oneAddr; + bool success = false; + ::FromVector(destination, oneAddr, &success); + destVal.push_back(Pair("address", success ? oneAddr.ToUniValue() : UniValue(UniValue::VOBJ))); + break; + } + case CTransferDestination::DEST_FULLID: destVal.push_back(Pair("identity", CIdentity(destination).ToUniValue())); destVal.push_back(Pair("serializeddata", HexBytes(&(destination[0]), destination.size()))); diff --git a/src/key_io.cpp b/src/key_io.cpp index cb51d5e9478..d509c0dbaa9 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -740,6 +740,20 @@ CIdentity::CIdentity(const UniValue &uni) : CPrincipal(uni) } } +CETHNFTAddress::CETHNFTAddress(const UniValue &uni) +{ + std::string contractAddrStr = uni_get_str(find_value(uni, "contract")); + std::string TokenIDStr = uni_get_str(find_value(uni, "tokenid")); + + if (!(contractID = DecodeEthDestination(contractAddrStr)).IsNull() && + TokenIDStr.length() == 66 && + TokenIDStr.substr(0,2) == "0x" && + IsHex(TokenIDStr.substr(2,64))) + { + tokenID = uint256(ParseHex(TokenIDStr.substr(2,64))); + } +} + CTransferDestination::CTransferDestination(const UniValue &obj) : fees(0) { type = uni_get_int(find_value(obj, "type")); @@ -777,6 +791,13 @@ CTransferDestination::CTransferDestination(const UniValue &obj) : fees(0) break; } + case CTransferDestination::DEST_ETHNFT: + { + CETHNFTAddress ethNFTAddress(find_value(obj, "address")); + destination = ::AsVector(ethNFTAddress); + break; + } + case CTransferDestination::DEST_FULLID: { std::string serializedHex(uni_get_str(find_value(obj, "serializeddata"))); diff --git a/src/pbaas/crosschainrpc.h b/src/pbaas/crosschainrpc.h index d165796bb22..d4834d79fab 100644 --- a/src/pbaas/crosschainrpc.h +++ b/src/pbaas/crosschainrpc.h @@ -321,22 +321,8 @@ class CTransferDestination uint256 retTokenID; UniValue nftJSON(UniValue::VOBJ); nftJSON.read(destStr); - - std::string contractAddrStr = uni_get_str(find_value(nftJSON, "contract")); - std::string TokenIDStr = uni_get_str(find_value(nftJSON, "tokenid")); - - if (!(retContract = DecodeEthDestination(contractAddrStr)).IsNull() && - TokenIDStr.length() == 66 && - destStr.substr(0,2) == "0x" && - IsHex(TokenIDStr.substr(2,64))) - { - retTokenID = uint256S(TokenIDStr.substr(2,64)); - return std::make_pair(retContract, uint256S(TokenIDStr)); - } - else - { - return std::make_pair(uint160(), uint256()); - } + CETHNFTAddress retAddr(nftJSON); + return std::make_pair(retAddr.contractID, retAddr.tokenID); } static std::string EncodeEthNFTDestination(const uint160 ðContractID, const uint256 &tokenID) @@ -364,35 +350,22 @@ class CTransferDestination UniValue ToUniValue() const; }; -class CNFTAddress +class CETHNFTAddress { public: - uint32_t version; - CTransferDestination rootContractOrID; - std::vector shortHashes; - std::vector longHashes; - - enum EVersions { - VERSION_INVALID = 0, - VERSION_VERUSID = 1, - VERSION_FIRST = 1, - VERSION_DEFAULT = 1, - VERSION_LAST = 1 - }; + uint160 contractID; + uint256 tokenID; - CNFTAddress(const UniValue &uni); - CNFTAddress(uint32_t ver=VERSION_DEFAULT) : version(ver) {} - CNFTAddress(const CTransferDestination &rootDest, const std::vector &shorts, const std::vector &longs, uint32_t ver=VERSION_DEFAULT) : - version(ver), rootContractOrID(rootDest), shortHashes(shorts), longHashes(longs) {} + CETHNFTAddress() {} + CETHNFTAddress(const UniValue &uni); + CETHNFTAddress(const uint160 &contract, const uint256 &token) : contractID(contract), tokenID(token) {} ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(VARINT(version)); - READWRITE(rootContractOrID); - READWRITE(shortHashes); - READWRITE(longHashes); + READWRITE(contractID); + READWRITE(tokenID); } UniValue ToUniValue() const; From fd5f57daf46943a7db0694e710b2d59f755ead42 Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 14:19:07 -0700 Subject: [PATCH 05/11] Build fix --- src/pbaas/crosschainrpc.h | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/pbaas/crosschainrpc.h b/src/pbaas/crosschainrpc.h index d4834d79fab..8f238e462a8 100644 --- a/src/pbaas/crosschainrpc.h +++ b/src/pbaas/crosschainrpc.h @@ -161,6 +161,27 @@ class CNodeData } }; +class CETHNFTAddress +{ +public: + uint160 contractID; + uint256 tokenID; + + CETHNFTAddress() {} + CETHNFTAddress(const UniValue &uni); + CETHNFTAddress(const uint160 &contract, const uint256 &token) : contractID(contract), tokenID(token) {} + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(contractID); + READWRITE(tokenID); + } + + UniValue ToUniValue() const; +}; + class CTransferDestination { public: @@ -350,27 +371,6 @@ class CTransferDestination UniValue ToUniValue() const; }; -class CETHNFTAddress -{ -public: - uint160 contractID; - uint256 tokenID; - - CETHNFTAddress() {} - CETHNFTAddress(const UniValue &uni); - CETHNFTAddress(const uint160 &contract, const uint256 &token) : contractID(contract), tokenID(token) {} - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) { - READWRITE(contractID); - READWRITE(tokenID); - } - - UniValue ToUniValue() const; -}; - extern int64_t AmountFromValueNoErr(const UniValue& value); // convenience class for collections of currencies that supports comparisons, including ==, >, >=, <, <=, as well as addition, and subtraction From 82655273912c640fe8276ee9d02dff0d4377fc51 Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 14:26:05 -0700 Subject: [PATCH 06/11] Build fix --- src/key_io.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/key_io.cpp b/src/key_io.cpp index d509c0dbaa9..bc7392988e5 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -745,7 +745,7 @@ CETHNFTAddress::CETHNFTAddress(const UniValue &uni) std::string contractAddrStr = uni_get_str(find_value(uni, "contract")); std::string TokenIDStr = uni_get_str(find_value(uni, "tokenid")); - if (!(contractID = DecodeEthDestination(contractAddrStr)).IsNull() && + if (!(contractID = CTransferDestination::DecodeEthDestination(contractAddrStr)).IsNull() && TokenIDStr.length() == 66 && TokenIDStr.substr(0,2) == "0x" && IsHex(TokenIDStr.substr(2,64))) From 25d2bbe259e213a958a9de47d48e00b80b91036e Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 15:22:53 -0700 Subject: [PATCH 07/11] ETH NFT fix --- src/key_io.cpp | 1 + src/pbaas/identity.cpp | 2 +- src/pbaas/pbaas.cpp | 31 ++++++++++++++----------------- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/key_io.cpp b/src/key_io.cpp index bc7392988e5..a3daaa4ed43 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -1233,6 +1233,7 @@ CScript CIdentity::IdentityUpdateOutputScript(uint32_t height, const std::vector if (IsRevoked()) { + // TODO: HARDENING for next testnet reset and mainnet release version, remove primary when revoked ret = MakeMofNCCScript(1, primary, recovery, indexDests); } else diff --git a/src/pbaas/identity.cpp b/src/pbaas/identity.cpp index dedc438f6be..63c1e556e4c 100644 --- a/src/pbaas/identity.cpp +++ b/src/pbaas/identity.cpp @@ -2154,7 +2154,7 @@ bool PrecheckIdentityPrimary(const CTransaction &tx, int32_t outNum, CValidation // consider the signature unfulfilled if ((PBAAS_TESTMODE && (!(IsVerusActive() || ConnectedChains.ThisChain().name == "Gravity") || height >= TESTNET_FORK_HEIGHT)) && identity.HasTokenizedControl()) { - if (!(oneP.m == 1 && oneP.n > 1)) + if (!(oneP.m == 1 && oneP.n >= oneP.m)) { std::string errorOut = "Invalid spend condition for tokenized control in: \"" + identity.name + "\""; return state.Error(errorOut.c_str()); diff --git a/src/pbaas/pbaas.cpp b/src/pbaas/pbaas.cpp index a5ff1dd337b..94e01fe648f 100644 --- a/src/pbaas/pbaas.cpp +++ b/src/pbaas/pbaas.cpp @@ -1900,27 +1900,24 @@ bool PrecheckCurrencyDefinition(const CTransaction &spendingTx, int32_t outNum, newCurrency.OPTION_GATEWAY_CONVERTER) && newCurrency.IsToken(); - if (newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT && - !(isNFTMappedCurrency && + if (!(newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT && + isNFTMappedCurrency && systemDef.proofProtocol == systemDef.PROOF_ETHNOTARIZATION && systemDef.IsGateway() && newCurrency.maxPreconvert.size() == 1 && newCurrency.maxPreconvert[0] == 0 && - newCurrency.GetTotalPreallocation() == 0)) - { - return state.Error("NFT mapped currency must have only 0 satoshi of supply and follow all definition rules"); - } - else if (newCurrency.IsNFTToken() && - !(isNFTMappedCurrency && - newCurrency.systemID == ASSETCHAINS_CHAINID && - ((newCurrency.GetTotalPreallocation() == 0 && - newCurrency.maxPreconvert.size() == 1 && - newCurrency.maxPreconvert[0] == 1) || - (newCurrency.GetTotalPreallocation() == 1 && - newCurrency.maxPreconvert.size() == 1 && - newCurrency.maxPreconvert[0] == 0)))) - { - return state.Error("Tokenized ID currency must have only 1 satoshi of supply as preallocation or convertible and follow all definition rules"); + newCurrency.GetTotalPreallocation() == 0) && + !(newCurrency.IsNFTToken() && + isNFTMappedCurrency && + newCurrency.systemID == ASSETCHAINS_CHAINID && + ((newCurrency.GetTotalPreallocation() == 0 && + newCurrency.maxPreconvert.size() == 1 && + newCurrency.maxPreconvert[0] == 1) || + (newCurrency.GetTotalPreallocation() == 1 && + newCurrency.maxPreconvert.size() == 1 && + newCurrency.maxPreconvert[0] == 0)))) + { + return state.Error("NFT mapped currency must have only " + std::string(newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT ? "0" : "1") + " satoshi of supply and follow all definition rules"); } // TODO: HARDENING - add hardening to ensure that no more than one satoshi at a time ever comes in from a bridge for an NFT mapped currency From efc19c0d5048bbc99c51cbfbd6bdcb9eddb6fe94 Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 15:26:08 -0700 Subject: [PATCH 08/11] Improve error message --- src/pbaas/pbaas.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/pbaas/pbaas.cpp b/src/pbaas/pbaas.cpp index 94e01fe648f..89f9bb0ce6d 100644 --- a/src/pbaas/pbaas.cpp +++ b/src/pbaas/pbaas.cpp @@ -1917,7 +1917,14 @@ bool PrecheckCurrencyDefinition(const CTransaction &spendingTx, int32_t outNum, newCurrency.maxPreconvert.size() == 1 && newCurrency.maxPreconvert[0] == 0)))) { - return state.Error("NFT mapped currency must have only " + std::string(newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT ? "0" : "1") + " satoshi of supply and follow all definition rules"); + if (newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT) + { + return state.Error("Ethereum NFT mapped currency must have 0 satoshis of supply, maxpreconversions of [0], and follow all definition rules"); + } + else + { + return state.Error("Tokenized ID control currency must have 1 satoshi of supply, and follow all definition rules"); + } } // TODO: HARDENING - add hardening to ensure that no more than one satoshi at a time ever comes in from a bridge for an NFT mapped currency From 89eaf4c7ce60f6f1d95e463633832f9ce6b56681 Mon Sep 17 00:00:00 2001 From: miketout Date: Mon, 12 Sep 2022 15:32:58 -0700 Subject: [PATCH 09/11] ETH and Tokenized ID control NFT fix --- src/pbaas/pbaas.cpp | 66 +++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/src/pbaas/pbaas.cpp b/src/pbaas/pbaas.cpp index 89f9bb0ce6d..adcb30f2155 100644 --- a/src/pbaas/pbaas.cpp +++ b/src/pbaas/pbaas.cpp @@ -1891,39 +1891,41 @@ bool PrecheckCurrencyDefinition(const CTransaction &spendingTx, int32_t outNum, systemDef = ConnectedChains.GetCachedCurrency(newCurrency.systemID); } - bool isNFTMappedCurrency = newCurrency.IsNFTToken() && - systemDef.IsValid() && - !(newCurrency.options & - newCurrency.OPTION_FRACTIONAL + - newCurrency.OPTION_GATEWAY + - newCurrency.OPTION_PBAAS + - newCurrency.OPTION_GATEWAY_CONVERTER) && - newCurrency.IsToken(); - - if (!(newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT && - isNFTMappedCurrency && - systemDef.proofProtocol == systemDef.PROOF_ETHNOTARIZATION && - systemDef.IsGateway() && - newCurrency.maxPreconvert.size() == 1 && - newCurrency.maxPreconvert[0] == 0 && - newCurrency.GetTotalPreallocation() == 0) && - !(newCurrency.IsNFTToken() && - isNFTMappedCurrency && - newCurrency.systemID == ASSETCHAINS_CHAINID && - ((newCurrency.GetTotalPreallocation() == 0 && - newCurrency.maxPreconvert.size() == 1 && - newCurrency.maxPreconvert[0] == 1) || - (newCurrency.GetTotalPreallocation() == 1 && - newCurrency.maxPreconvert.size() == 1 && - newCurrency.maxPreconvert[0] == 0)))) - { - if (newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT) - { - return state.Error("Ethereum NFT mapped currency must have 0 satoshis of supply, maxpreconversions of [0], and follow all definition rules"); - } - else + bool isNFTMappedCurrency = false; + if (newCurrency.IsNFTToken()) + { + isNFTMappedCurrency = newCurrency.IsNFTToken() && + systemDef.IsValid() && + !(newCurrency.options & + newCurrency.OPTION_FRACTIONAL + + newCurrency.OPTION_GATEWAY + + newCurrency.OPTION_PBAAS + + newCurrency.OPTION_GATEWAY_CONVERTER) && + newCurrency.IsToken(); + + if (!isNFTMappedCurrency || + (!(newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT && + systemDef.proofProtocol == systemDef.PROOF_ETHNOTARIZATION && + systemDef.IsGateway() && + newCurrency.maxPreconvert.size() == 1 && + newCurrency.maxPreconvert[0] == 0 && + newCurrency.GetTotalPreallocation() == 0) && + !(newCurrency.systemID == ASSETCHAINS_CHAINID && + ((newCurrency.GetTotalPreallocation() == 0 && + newCurrency.maxPreconvert.size() == 1 && + newCurrency.maxPreconvert[0] == 1) || + (newCurrency.GetTotalPreallocation() == 1 && + newCurrency.maxPreconvert.size() == 1 && + newCurrency.maxPreconvert[0] == 0))))) { - return state.Error("Tokenized ID control currency must have 1 satoshi of supply, and follow all definition rules"); + if (newCurrency.nativeCurrencyID.TypeNoFlags() == newCurrency.nativeCurrencyID.DEST_ETHNFT) + { + return state.Error("Ethereum NFT mapped currency must have 0 satoshis of supply, maxpreconversions of [0], and follow all definition rules"); + } + else + { + return state.Error("Tokenized ID control currency must have 1 satoshi of supply, and follow all definition rules"); + } } } From 304baee1613d4c9fc68900779698bf64eb9051ed Mon Sep 17 00:00:00 2001 From: Asher Dawes Date: Mon, 12 Sep 2022 15:44:56 -0700 Subject: [PATCH 10/11] Update deprecation height --- src/deprecation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deprecation.h b/src/deprecation.h index b262f876cc8..e14cec9762e 100644 --- a/src/deprecation.h +++ b/src/deprecation.h @@ -9,7 +9,7 @@ // * Shut down 20 weeks' worth of blocks after the estimated release block height. // * A warning is shown during the 2 weeks' worth of blocks prior to shut down. -static const int APPROX_RELEASE_HEIGHT = 2191000; +static const int APPROX_RELEASE_HEIGHT = 2197000; static const int WEEKS_UNTIL_DEPRECATION = 20; static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 60 * 24); From c17fe1dceb8698877981f9f34ed463b2a72a73d7 Mon Sep 17 00:00:00 2001 From: Asher Dawes Date: Mon, 12 Sep 2022 15:45:32 -0700 Subject: [PATCH 11/11] Update version --- .gitlab-ci.yml | 2 +- README.md | 2 +- doc/man/verus-cli/linux/README.txt | 2 +- doc/man/verus-cli/mac/README.txt | 2 +- doc/man/verus-cli/windows/README.txt | 2 +- src/version.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3ac6c228e2..5e136428d33 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,7 +7,7 @@ stages: ######################################################################################################################## variables: - VERSION: 0.9.4-2 + VERSION: 0.9.4-3 VERUS_CLI_ARM64_LINUX: Verus-CLI-Linux-v${VERSION}-arm64.tar.gz VERUS_CLI_LINUX_X86_64: Verus-CLI-Linux-v${VERSION}-x86_64.tar.gz diff --git a/README.md b/README.md index ca768d224e8..8a11b5b8233 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -## VerusCoin version 0.9.4-2 +## VerusCoin version 0.9.4-3 Arguably the world's most advanced technology, zero knowledge privacy-centric blockchain, Verus Coin brings Sapling performance and zero knowledge features to an intelligent system with interchain smart contracts and a completely original, combined proof of stake/proof of work consensus algorithm that solves the nothing at stake problem. With this and its approach towards CPU mining and ASICs, Verus Coin strives to be one of the most naturally decentralizing and attack resistant blockchains in existence. diff --git a/doc/man/verus-cli/linux/README.txt b/doc/man/verus-cli/linux/README.txt index 08a1908262b..19b3c5c0cdc 100644 --- a/doc/man/verus-cli/linux/README.txt +++ b/doc/man/verus-cli/linux/README.txt @@ -1,5 +1,5 @@ -VerusCoin Command Line Tools v0.9.4-2 +VerusCoin Command Line Tools v0.9.4-3 Contents: verusd - VerusCoin daemon diff --git a/doc/man/verus-cli/mac/README.txt b/doc/man/verus-cli/mac/README.txt index 41663a85e8c..b724f42cdc3 100644 --- a/doc/man/verus-cli/mac/README.txt +++ b/doc/man/verus-cli/mac/README.txt @@ -1,5 +1,5 @@ -VerusCoin Command Line Tools v0.9.4-2 +VerusCoin Command Line Tools v0.9.4-3 Contents: verusd - VerusCoin daemon. diff --git a/doc/man/verus-cli/windows/README.txt b/doc/man/verus-cli/windows/README.txt index ceffad66e34..0bb7f5a85a1 100644 --- a/doc/man/verus-cli/windows/README.txt +++ b/doc/man/verus-cli/windows/README.txt @@ -1,5 +1,5 @@ -VerusCoin Command Line Tools v0.9.4-2 +VerusCoin Command Line Tools v0.9.4-3 Contents: verusd.exe - VerusCoin daemon diff --git a/src/version.h b/src/version.h index a5507954904..fd74d8964b2 100644 --- a/src/version.h +++ b/src/version.h @@ -35,6 +35,6 @@ static const int MEMPOOL_GD_VERSION = 60002; static const int NO_BLOOM_VERSION = 170004; #define KOMODO_VERSION "0.2.1" -#define VERUS_VERSION "0.9.4-2" +#define VERUS_VERSION "0.9.4-3" #endif // BITCOIN_VERSION_H