Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ==> market.cpp <==
- // 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<uint256, CProduct> mapMyProducts;
- map<uint256, CProduct> 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<map<uint256, CProduct>::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<typename T>
- 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<unsigned short> 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<unsigned short> 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<unsigned short>& vAtoms, bool fOrigin)
- {
- CReviewDB reviewdb;
- map<uint256, vector<unsigned short> > pmapPropagate[2];
- pmapPropagate[0][hashUserStart] = vAtoms;
- for (int side = 0; !pmapPropagate[side].empty(); side = 1 - side)
- {
- map<uint256, vector<unsigned short> >& mapFrom = pmapPropagate[side];
- map<uint256, vector<unsigned short> >& mapTo = pmapPropagate[1 - side];
- for (map<uint256, vector<unsigned short> >::iterator mi = mapFrom.begin(); mi != mapFrom.end(); ++mi)
- {
- const uint256& hashUser = (*mi).first;
- const vector<unsigned short>& 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<CReview> 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<unsigned short> 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;
- }
- ==> market.h <==
- // 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.
- class CUser;
- class CReview;
- class CProduct;
- static const unsigned int nFlowthroughRate = 2;
- bool AdvertInsert(const CProduct& product);
- void AdvertErase(const CProduct& product);
- bool AddAtomsAndPropagate(uint256 hashUserStart, const vector<unsigned short>& vAtoms, bool fOrigin);
- class CUser
- {
- public:
- vector<unsigned short> vAtomsIn;
- vector<unsigned short> vAtomsNew;
- vector<unsigned short> vAtomsOut;
- vector<uint256> vLinksOut;
- CUser()
- {
- }
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(vAtomsIn);
- READWRITE(vAtomsNew);
- READWRITE(vAtomsOut);
- READWRITE(vLinksOut);
- )
- void SetNull()
- {
- vAtomsIn.clear();
- vAtomsNew.clear();
- vAtomsOut.clear();
- vLinksOut.clear();
- }
- uint256 GetHash() const { return SerializeHash(*this); }
- int GetAtomCount() const
- {
- return (vAtomsIn.size() + vAtomsNew.size());
- }
- void AddAtom(unsigned short nAtom, bool fOrigin);
- };
- class CReview
- {
- public:
- int nVersion;
- uint256 hashTo;
- map<string, string> mapValue;
- vector<unsigned char> vchPubKeyFrom;
- vector<unsigned char> vchSig;
- // memory only
- unsigned int nTime;
- int nAtoms;
- CReview()
- {
- nVersion = 1;
- hashTo = 0;
- nTime = 0;
- nAtoms = 0;
- }
- IMPLEMENT_SERIALIZE
- (
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- if (!(nType & SER_DISK))
- READWRITE(hashTo);
- READWRITE(mapValue);
- READWRITE(vchPubKeyFrom);
- if (!(nType & SER_GETHASH))
- READWRITE(vchSig);
- )
- uint256 GetHash() const { return SerializeHash(*this); }
- uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
- uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
- bool AcceptReview();
- };
- class CProduct
- {
- public:
- int nVersion;
- CAddress addr;
- map<string, string> mapValue;
- map<string, string> mapDetails;
- vector<pair<string, string> > vOrderForm;
- unsigned int nSequence;
- vector<unsigned char> vchPubKeyFrom;
- vector<unsigned char> vchSig;
- // disk only
- int nAtoms;
- // memory only
- set<unsigned int> setSources;
- CProduct()
- {
- nVersion = 1;
- nAtoms = 0;
- nSequence = 0;
- }
- IMPLEMENT_SERIALIZE
- (
- READWRITE(this->nVersion);
- nVersion = this->nVersion;
- READWRITE(addr);
- READWRITE(mapValue);
- if (!(nType & SER_GETHASH))
- {
- READWRITE(mapDetails);
- READWRITE(vOrderForm);
- READWRITE(nSequence);
- }
- READWRITE(vchPubKeyFrom);
- if (!(nType & SER_GETHASH))
- READWRITE(vchSig);
- if (nType & SER_DISK)
- READWRITE(nAtoms);
- )
- uint256 GetHash() const { return SerializeHash(*this); }
- uint256 GetSigHash() const { return SerializeHash(*this, SER_GETHASH|SER_SKIPSIG); }
- uint256 GetUserHash() const { return Hash(vchPubKeyFrom.begin(), vchPubKeyFrom.end()); }
- bool CheckSignature();
- bool CheckProduct();
- };
- extern map<uint256, CProduct> mapProducts;
- extern CCriticalSection cs_mapProducts;
- extern map<uint256, CProduct> mapMyProducts;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement