HF Assets: primitives/transaction: post-CT: Explicit multi-asset fees

Fix CTransaction::GetFee() + Introduce CMutableTransaction::SetFeesFromTxRewardMap
This commit is contained in:
Jorge Timón 2016-03-22 00:34:18 +01:00
parent 354383491d
commit f406c03568
2 changed files with 56 additions and 11 deletions

View file

@ -158,8 +158,8 @@ std::string CTxOut::ToString() const
return strprintf("CTxOut(nValue=%s, assetID=%s, scriptPubKey=%s)", (nValue.IsAmount() ? strprintf("%d.%08d", nValue.GetAmount() / COIN, nValue.GetAmount() % COIN) : std::string("UNKNOWN")), assetID.ToString(), scriptPubKey.ToString().substr(0,30));
}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nTxFee(0), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), nTxFee(tx.nTxFee), vout(tx.vout), nLockTime(tx.nLockTime) {}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), vTxFees(std::vector<CAmount>()), nLockTime(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), vin(tx.vin), vTxFees(tx.vTxFees), vout(tx.vout), nLockTime(tx.nLockTime) {}
uint256 CMutableTransaction::GetHash() const
{
@ -192,15 +192,15 @@ void CTransaction::UpdateHash() const
hasher.Finalize((unsigned char*)&hashFull);
}
CTransaction::CTransaction() : hash(0), hashFull(0), nVersion(CTransaction::CURRENT_VERSION), vin(), nTxFee(0), vout(), nLockTime(0) { }
CTransaction::CTransaction() : hash(0), hashFull(0), nVersion(CTransaction::CURRENT_VERSION), vin(), vTxFees(std::vector<CAmount>()), vout(), nLockTime(0) { }
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), nTxFee(tx.nTxFee), vout(tx.vout), nLockTime(tx.nLockTime) {
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vTxFees(tx.vTxFees), vout(tx.vout), nLockTime(tx.nLockTime) {
UpdateHash();
}
CTransaction& CTransaction::operator=(const CTransaction &tx) {
*const_cast<int*>(&nVersion) = tx.nVersion;
*const_cast<CAmount*>(&nTxFee) = tx.nTxFee;
*const_cast<std::vector<CAmount>*>(&vTxFees) = tx.vTxFees;
*const_cast<std::vector<CTxIn>*>(&vin) = tx.vin;
*const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
*const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
@ -217,6 +217,42 @@ double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSiz
return dPriorityInputs / nTxSize;
}
CAmountMap CTransaction::GetTxRewardMap() const
{
assert(vTxFees.size() <= vout.size());
CAmountMap mTxReward;
for (unsigned i = 0; i < vTxFees.size(); ++i)
if (vout[i].assetID != 0)
mTxReward[vout[i].assetID] += vTxFees[i];
return mTxReward;
}
void CMutableTransaction::SetFeesFromTxRewardMap(const CAmountMap& mTxReward)
{
assert(mTxReward.size() <= vout.size());
vTxFees.resize(mTxReward.size());
for(CAmountMap::const_iterator it = mTxReward.begin(); it != mTxReward.end(); ++it) {
bool fFoundAsset = false;
for (unsigned i = 0; i < vout.size(); ++i) {
if (vout[i].assetID == it->first) {
vTxFees[i] = it->second;
fFoundAsset = true;
break;
}
}
if (!fFoundAsset)
assert(false && "CMutableTransaction::SetFeesFromTxRewardMap: Trying to pay fees without output.");
}
}
CAmount CTransaction::GetFee(const CAssetID& assetID) const
{
const CAmountMap mTxReward = GetTxRewardMap();
if (!mTxReward.count(assetID))
return 0;
return mTxReward.find(assetID)->second;
}
unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
{
// In order to avoid disincentivizing cleaning up the UTXO set we don't count
@ -238,12 +274,12 @@ unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const
std::string CTransaction::ToString() const
{
std::string str;
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u, fee=%u)\n",
str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u, vTxFees.size=%u)\n",
GetHash().ToString().substr(0,10),
nVersion,
vin.size(),
vout.size(),
nLockTime, nTxFee);
nLockTime, vTxFees.size());
for (unsigned int i = 0; i < vin.size(); i++)
str += " " + vin[i].ToString() + "\n";
for (unsigned int i = 0; i < vout.size(); i++)

View file

@ -267,7 +267,7 @@ public:
// structure, including the hash.
const int32_t nVersion;
const std::vector<CTxIn> vin;
const CAmount nTxFee;
const std::vector<CAmount> vTxFees;
const std::vector<CTxOut> vout;
const uint32_t nLockTime;
@ -290,7 +290,7 @@ public:
assert((nType != SER_GETHASH && !fOnlyWitness && fWitness) || nType == SER_GETHASH);
if (!fOnlyWitness) READWRITE(*const_cast<int32_t*>(&this->nVersion));
READWRITE(*const_cast<std::vector<CTxIn>*>(&vin));
if (!fBitcoinTx && !fOnlyWitness) READWRITE(*const_cast<CAmount*>(&nTxFee));
if (!fBitcoinTx && !fOnlyWitness) READWRITE(*const_cast<std::vector<CAmount>*>(&vTxFees));
if (!fOnlyWitness) READWRITE(*const_cast<std::vector<CTxOut>*>(&vout));
if (!fOnlyWitness) READWRITE(*const_cast<uint32_t*>(&nLockTime));
if (ser_action.ForRead())
@ -324,6 +324,11 @@ public:
// Compute priority, given priority of inputs and (optionally) tx size
double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const;
/**
* @return a CAmountMap with total fees per asset.
*/
CAmountMap GetTxRewardMap() const;
CAmount GetFee(const CAssetID& assetID) const;
// Compute modified tx size for priority calculation (optionally given tx size)
unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const;
@ -362,7 +367,7 @@ struct CMutableTransaction
{
int32_t nVersion;
std::vector<CTxIn> vin;
CAmount nTxFee;
std::vector<CAmount> vTxFees;
std::vector<CTxOut> vout;
uint32_t nLockTime;
@ -380,7 +385,7 @@ struct CMutableTransaction
assert((nType != SER_GETHASH && !fOnlyWitness && fWitness) || nType == SER_GETHASH);
if (!fOnlyWitness) READWRITE(this->nVersion);
READWRITE(vin);
if (!fOnlyWitness) READWRITE(nTxFee);
if (!fOnlyWitness) READWRITE(vTxFees);
if (!fOnlyWitness) READWRITE(vout);
if (!fOnlyWitness) READWRITE(nLockTime);
}
@ -394,6 +399,10 @@ struct CMutableTransaction
* fly, as opposed to GetHash() in CTransaction, which uses a cached result.
*/
uint256 GetHash() const;
/**
* Sets the vTxFees to the cannonical representation provided
*/
void SetFeesFromTxRewardMap(const CAmountMap& mTxReward);
};
#define FOREACH_TXIN(VAR, TX) \