From 5ce650382352c1503f40abf08129ada69402af55 Mon Sep 17 00:00:00 2001 From: bitflash-coin Date: Tue, 4 Aug 2026 06:34:32 -0700 Subject: public commit --- src/market.cpp | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 src/market.cpp (limited to 'src/market.cpp') diff --git a/src/market.cpp b/src/market.cpp new file mode 100644 index 0000000..e5d34f4 --- /dev/null +++ b/src/market.cpp @@ -0,0 +1,264 @@ +// Copyright (c) 2009 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" + + + + + + + + + + +// +// Global state variables +// + +//// later figure out how these are persisted +map mapMyProducts; + + + + +map mapProducts; +CCriticalSection cs_mapProducts; + +bool AdvertInsert(const CProduct& product) +{ + uint256 hash = product.GetHash(); + bool fNew = false; + bool fUpdated = false; + + CRITICAL_BLOCK(cs_mapProducts) + { + // Insert or find existing product + pair::iterator, bool> item = mapProducts.insert(make_pair(hash, product)); + CProduct* pproduct = &(*(item.first)).second; + fNew = item.second; + + // Update if newer + if (product.nSequence > pproduct->nSequence) + { + *pproduct = product; + fUpdated = true; + } + } + + //if (fNew) + // NotifyProductAdded(hash); + //else if (fUpdated) + // NotifyProductUpdated(hash); + + return (fNew || fUpdated); +} + +void AdvertErase(const CProduct& product) +{ + uint256 hash = product.GetHash(); + CRITICAL_BLOCK(cs_mapProducts) + mapProducts.erase(hash); + //NotifyProductDeleted(hash); +} + + + + + + + + + + + + + + + + + + + +template +unsigned int Union(T& v1, T& v2) +{ + // v1 = v1 union v2 + // v1 and v2 must be sorted + // returns the number of elements added to v1 + + ///// need to check that this is equivalent, then delete this comment + //vector vUnion(v1.size() + v2.size()); + //vUnion.erase(set_union(v1.begin(), v1.end(), + // v2.begin(), v2.end(), + // vUnion.begin()), + // vUnion.end()); + + T vUnion; + vUnion.reserve(v1.size() + v2.size()); + set_union(v1.begin(), v1.end(), + v2.begin(), v2.end(), + back_inserter(vUnion)); + unsigned int nAdded = vUnion.size() - v1.size(); + if (nAdded > 0) + v1 = vUnion; + return nAdded; +} + +void CUser::AddAtom(unsigned short nAtom, bool fOrigin) +{ + // Ignore duplicates + if (binary_search(vAtomsIn.begin(), vAtomsIn.end(), nAtom) || + find(vAtomsNew.begin(), vAtomsNew.end(), nAtom) != vAtomsNew.end()) + return; + + //// instead of zero atom, should change to free atom that propagates, + //// limited to lower than a certain value like 5 so conflicts quickly + // The zero atom never propagates, + // new atoms always propagate through the user that created them + if (nAtom == 0 || fOrigin) + { + vector vTmp(1, nAtom); + Union(vAtomsIn, vTmp); + if (fOrigin) + vAtomsOut.push_back(nAtom); + return; + } + + vAtomsNew.push_back(nAtom); + + if (vAtomsNew.size() >= nFlowthroughRate || vAtomsOut.empty()) + { + // Select atom to flow through to vAtomsOut + vAtomsOut.push_back(vAtomsNew[GetRand(vAtomsNew.size())]); + + // Merge vAtomsNew into vAtomsIn + sort(vAtomsNew.begin(), vAtomsNew.end()); + Union(vAtomsIn, vAtomsNew); + vAtomsNew.clear(); + } +} + +bool AddAtomsAndPropagate(uint256 hashUserStart, const vector& vAtoms, bool fOrigin) +{ + CReviewDB reviewdb; + map > pmapPropagate[2]; + pmapPropagate[0][hashUserStart] = vAtoms; + + for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side) + { + map >& mapFrom = pmapPropagate[side]; + map >& mapTo = pmapPropagate[1 - side]; + + for (map >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi) + { + const uint256& hashUser = (*mi).first; + const vector& vReceived = (*mi).second; + + ///// this would be a lot easier on the database if it put the new atom at the beginning of the list, + ///// so the change would be right next to the vector size. + + // Read user + CUser user; + reviewdb.ReadUser(hashUser, user); + unsigned int nIn = user.vAtomsIn.size(); + unsigned int nNew = user.vAtomsNew.size(); + unsigned int nOut = user.vAtomsOut.size(); + + // Add atoms received + foreach(unsigned short nAtom, vReceived) + user.AddAtom(nAtom, fOrigin); + fOrigin = false; + + // Don't bother writing to disk if no changes + if (user.vAtomsIn.size() == nIn && user.vAtomsNew.size() == nNew) + continue; + + // Propagate + if (user.vAtomsOut.size() > nOut) + foreach(const uint256& hash, user.vLinksOut) + mapTo[hash].insert(mapTo[hash].end(), user.vAtomsOut.begin() + nOut, user.vAtomsOut.end()); + + // Write back + if (!reviewdb.WriteUser(hashUser, user)) + return false; + } + mapFrom.clear(); + } + return true; +} + + + + + + +bool CReview::AcceptReview() +{ + // Timestamp + nTime = GetTime(); + + // Check signature + if (!CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)) + return false; + + CReviewDB reviewdb; + + // Add review text to recipient + vector vReviews; + reviewdb.ReadReviews(hashTo, vReviews); + vReviews.push_back(*this); + if (!reviewdb.WriteReviews(hashTo, vReviews)) + return false; + + // Add link from sender + CUser user; + uint256 hashFrom = Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); + reviewdb.ReadUser(hashFrom, user); + user.vLinksOut.push_back(hashTo); + if (!reviewdb.WriteUser(hashFrom, user)) + return false; + + reviewdb.Close(); + + // Propagate atoms to recipient + vector vZeroAtom(1, 0); + if (!AddAtomsAndPropagate(hashTo, user.vAtomsOut.size() ? user.vAtomsOut : vZeroAtom, false)) + return false; + + return true; +} + + + + + +bool CProduct::CheckSignature() +{ + return (CKey::Verify(vchPubKeyFrom, GetSigHash(), vchSig)); +} + +bool CProduct::CheckProduct() +{ + if (!CheckSignature()) + return false; + + // Make sure it's a summary product + if (!mapDetails.empty() || !vOrderForm.empty()) + return false; + + // Look up seller's atom count + CReviewDB reviewdb("r"); + CUser user; + reviewdb.ReadUser(GetUserHash(), user); + nAtoms = user.GetAtomCount(); + reviewdb.Close(); + + ////// delme, this is now done by AdvertInsert + //// Store to memory + //CRITICAL_BLOCK(cs_mapProducts) + // mapProducts[GetHash()] = *this; + + return true; +} -- cgit v1.2.3