forked from ElementsProject/elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
14af0b6
commit 10773c6
Showing
3 changed files
with
265 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
|
||
#include <asset.h> | ||
#include <assetsdir.h> | ||
#include <core_io.h> | ||
#include <policy/policy.h> | ||
|
||
|
||
CAmountMap& operator+=(CAmountMap& a, const CAmountMap& b) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) | ||
a[it->first] += it->second; | ||
return a; | ||
} | ||
|
||
CAmountMap& operator-=(CAmountMap& a, const CAmountMap& b) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) | ||
a[it->first] -= it->second; | ||
return a; | ||
} | ||
|
||
CAmountMap operator+(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
CAmountMap c; | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) | ||
c[it->first] += it->second; | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) | ||
c[it->first] += it->second; | ||
return c; | ||
} | ||
|
||
CAmountMap operator-(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
CAmountMap c; | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) | ||
c[it->first] += it->second; | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) | ||
c[it->first] -= it->second; | ||
return c; | ||
} | ||
|
||
bool operator<(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
bool smallerElement = false; | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) { | ||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0; | ||
if (aValue > it->second) | ||
return false; | ||
if (aValue < it->second) | ||
smallerElement = true; | ||
} | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) { | ||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0; | ||
if (it->second > bValue) | ||
return false; | ||
if (it->second < bValue) | ||
smallerElement = true; | ||
} | ||
return smallerElement; | ||
} | ||
|
||
bool operator<=(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) { | ||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0; | ||
if (aValue > it->second) | ||
return false; | ||
} | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) { | ||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0; | ||
if (it->second > bValue) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool operator>(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
bool largerElement = false; | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) { | ||
CAmount aValue = a.count(it->first) ? a.find(it->first)->second : 0; | ||
if (aValue < it->second) | ||
return false; | ||
if (aValue > it->second) | ||
largerElement = true; | ||
} | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) { | ||
CAmount bValue = b.count(it->first) ? b.find(it->first)->second : 0; | ||
if (it->second < bValue) | ||
return false; | ||
if (it->second > bValue) | ||
largerElement = true; | ||
} | ||
return largerElement; | ||
} | ||
|
||
bool operator>=(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) { | ||
if ((a.count(it->first) ? a.find(it->first)->second : 0) < it->second) | ||
return false; | ||
} | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) { | ||
if (it->second < (b.count(it->first) ? b.find(it->first)->second : 0)) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool operator==(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = a.begin(); it != a.end(); ++it) { | ||
if ((b.count(it->first) ? b.find(it->first)->second : 0) != it->second) | ||
return false; | ||
} | ||
for(std::map<CAsset, CAmount>::const_iterator it = b.begin(); it != b.end(); ++it) { | ||
if ((a.count(it->first) ? a.find(it->first)->second : 0) != it->second) | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
bool operator!=(const CAmountMap& a, const CAmountMap& b) | ||
{ | ||
return !(a == b); | ||
} | ||
|
||
bool hasNegativeValue(const CAmountMap& amount) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) { | ||
if (it->second < 0) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
bool hasNonPostiveValue(const CAmountMap& amount) | ||
{ | ||
for(std::map<CAsset, CAmount>::const_iterator it = amount.begin(); it != amount.end(); ++it) { | ||
if (it->second <= 0) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
CAmount valueFor(const CAmountMap& mapValue, const CAsset& asset) { | ||
CAmountMap::const_iterator it = mapValue.find(asset); | ||
if (it != mapValue.end()) { | ||
return it->second; | ||
} else { | ||
return CAmount(0); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
|
||
#ifndef BITCOIN_ASSET_H | ||
#define BITCOIN_ASSET_H | ||
|
||
#include <stdint.h> | ||
#include <uint256.h> | ||
#include <stdlib.h> | ||
|
||
#include <amount.h> | ||
#include <serialize.h> | ||
|
||
/** | ||
* Native Asset Issuance | ||
* | ||
* An asset identifier tag, a 256 bits serialized hash (sha256) defined | ||
* by the issuance transaction from which the output’s coins are derived. | ||
* Each output contains coins from a single asset/currency. | ||
* For the host currency, the similarly-calculated hash of the chain’s genesis | ||
* block is used instead. | ||
**/ | ||
struct CAsset { | ||
uint256 id; | ||
|
||
CAsset() { } | ||
explicit CAsset(const uint256& idIn) : id(idIn) { } | ||
explicit CAsset(const std::vector<unsigned char>& vchIDIn) : id(vchIDIn) { } | ||
|
||
ADD_SERIALIZE_METHODS; | ||
|
||
template <typename Stream, typename Operation> | ||
inline void SerializationOp(Stream& s, Operation ser_action) { | ||
READWRITE(id); | ||
} | ||
|
||
bool IsNull() const { return id.IsNull(); } | ||
void SetNull() { id.SetNull(); } | ||
|
||
unsigned char* begin() { return id.begin(); } | ||
unsigned char* end() { return id.end(); } | ||
const unsigned char* begin() const { return id.begin(); } | ||
const unsigned char* end() const { return id.end(); } | ||
|
||
std::string GetHex() const { return id.GetHex(); } | ||
void SetHex(const std::string& str) { id.SetHex(str); } | ||
|
||
friend bool operator==(const CAsset& a, const CAsset& b) | ||
{ | ||
return a.id == b.id; | ||
} | ||
|
||
friend bool operator!=(const CAsset& a, const CAsset& b) | ||
{ | ||
return !(a == b); | ||
} | ||
|
||
friend bool operator<(const CAsset& a, const CAsset& b) | ||
{ | ||
return a.id < b.id; | ||
} | ||
}; | ||
|
||
/** Used for consensus fee and general wallet accounting*/ | ||
typedef std::map<CAsset, CAmount> CAmountMap; | ||
|
||
CAmountMap& operator+=(CAmountMap& a, const CAmountMap& b); | ||
CAmountMap& operator-=(CAmountMap& a, const CAmountMap& b); | ||
CAmountMap operator+(const CAmountMap& a, const CAmountMap& b); | ||
CAmountMap operator-(const CAmountMap& a, const CAmountMap& b); | ||
|
||
// WARNING: Comparisons are only looking for *complete* ordering. | ||
// For strict inequality checks, if any entry would fail the non-strict | ||
// inequality, the comparison will fail. Therefore it is possible | ||
// that all inequality comparison checks may fail. | ||
// Therefore if >/< fails against a CAmountMap(), this means there | ||
// are all zeroes or one or more negative values. | ||
// | ||
// Examples: 1A + 2B <= 1A + 2B + 1C | ||
// and 1A + 2B < 1A + 2B + 1C | ||
// but | ||
// !(1A + 2B == 1A + 2B + 1C) | ||
//------------------------------------- | ||
// 1A + 2B == 1A + 2B | ||
// and 1A + 2B <= 1A + 2B | ||
// but | ||
// !(1A + 2B < 1A + 2B) | ||
//------------------------------------- | ||
// !(1A + 2B == 2B - 1C) | ||
// !(1A + 2B >= 2B - 1C) | ||
// ... | ||
// !(1A + 2B < 2B - 1C) | ||
// and 1A + 2B != 2B - 1C | ||
bool operator<(const CAmountMap& a, const CAmountMap& b); | ||
bool operator<=(const CAmountMap& a, const CAmountMap& b); | ||
bool operator>(const CAmountMap& a, const CAmountMap& b); | ||
bool operator>=(const CAmountMap& a, const CAmountMap& b); | ||
bool operator==(const CAmountMap& a, const CAmountMap& b); | ||
bool operator!=(const CAmountMap& a, const CAmountMap& b); | ||
|
||
inline bool MoneyRange(const CAmountMap& mapValue) { | ||
for(CAmountMap::const_iterator it = mapValue.begin(); it != mapValue.end(); it++) { | ||
if (it->second < 0 || it->second > MAX_MONEY) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
CAmount valueFor(const CAmountMap& mapValue, const CAsset& asset); | ||
|
||
#endif // BITCOIN_AMOUNT_H |