Add CAsset and CAmountMap

This commit is contained in:
Steven Roose 2019-03-19 18:12:49 +00:00
parent 14af0b6539
commit 10773c6c1a
No known key found for this signature in database
GPG key ID: 7FC91380BB4CE800
3 changed files with 265 additions and 0 deletions

View file

@ -92,6 +92,7 @@ endif
BITCOIN_CORE_H = \
addrdb.h \
addrman.h \
asset.h \
base58.h \
bech32.h \
blech32.h \
@ -359,6 +360,7 @@ libbitcoin_consensus_a_SOURCES = \
amount.h \
arith_uint256.cpp \
arith_uint256.h \
asset.cpp \
consensus/merkle.cpp \
consensus/merkle.h \
consensus/params.h \

153
src/asset.cpp Normal file
View file

@ -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);
}
}

110
src/asset.h Normal file
View file

@ -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 outputs coins are derived.
* Each output contains coins from a single asset/currency.
* For the host currency, the similarly-calculated hash of the chains 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