Offer logic seems to be working now.

This commit is contained in:
JoelKatz
2012-04-10 15:26:44 -07:00
parent 22d3354ccc
commit 6bf6d86cd9
2 changed files with 74 additions and 12 deletions

View File

@@ -59,7 +59,7 @@ STAmount* STAmount::construct(SerializerIterator& sit, const char *name)
std::string STAmount::getText() const
{ // This should be re-implemented to put a '.' in the string form of the integer value
std::ostringstream str;
str << std::setprecision(16) << static_cast<double>(*this);
str << std::setprecision(14) << static_cast<double>(*this);
return str.str();
}
@@ -192,17 +192,16 @@ STAmount operator-(STAmount v1, STAmount v2)
return STAmount(v1.name, v1.value - v2.value, v1.offset);
}
STAmount getRate(const STAmount& offerIn, const STAmount& offerOut)
STAmount operator/(const STAmount& num, const STAmount& den)
{
CBigNum numerator, denominator, quotient;
if(offerOut.value == 0) throw std::runtime_error("illegal offer");
if(offerIn.value == 0) return STAmount();
if(den.value == 0) throw std::runtime_error("illegal offer");
if(num.value == 0) return STAmount();
// Compute (numerator * 10^16) / denominator
if( (BN_zero(&numerator) != 1) || (BN_zero(&denominator) != 1) ||
(BN_add_word(&numerator, offerIn.value) != 1) ||
(BN_add_word(&denominator, offerOut.value) != 1) ||
if( (BN_add_word(&numerator, num.value) != 1) ||
(BN_add_word(&denominator, den.value) != 1) ||
(BN_mul_word(&numerator, 10000000000000000ull) != 1) ||
(BN_div(&quotient, NULL, &numerator, &denominator, CAutoBN_CTX()) != 1) )
{
@@ -212,5 +211,63 @@ STAmount getRate(const STAmount& offerIn, const STAmount& offerOut)
// 10^15 <= quotient <= 10^17
assert(BN_num_bytes(&quotient)<=60);
return STAmount(quotient.getulong(), offerIn.offset - offerOut.offset - 16);
return STAmount(quotient.getulong(), num.offset - den.offset - 16);
}
STAmount operator*(const STAmount &v1, const STAmount &v2)
{
if( (v1.value == 0) || (v2.value == 0) ) return STAmount();
// Compute (numerator * denominator) / 10^15
CBigNum v;
if( (BN_add_word(&v, v1.value) != 1) ||
(BN_mul_word(&v, v2.value) != 1) ||
(BN_div_word(&v, 1000000000000000ull) == ((BN_ULONG)-1)) )
{
throw std::runtime_error("internal bn error");
}
// 10^15 <= product <= 10^17
assert(BN_num_bytes(&v)<=60);
return STAmount(v.getulong(), v1.offset + v2.offset + 15);
}
STAmount getRate(const STAmount& offerOut, const STAmount& offerIn)
{
return offerOut / offerIn;
}
STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid)
{ // if someone is offering (offerOut) for (offerIn), and I pay (paid), how much do I get?
// If you pay nothing, you get nothing. Offer is untouched
if (paid.value == 0) return STAmount();
if( (offerIn.value == 0) || (offerOut.value == 0) )
{ // If the other is invalid or empty, you pay nothing and get nothing and the offer is dead
offerIn.zero();
offerOut.zero();
paid.zero();
return STAmount();
}
if(paid >= offerIn)
{ // If you pay equal to or more than the offer amount, you get the whole offer and pay its input
STAmount ret(offerOut);
paid = offerIn;
offerOut.zero();
offerIn.zero();
return ret;
}
// partial satisfaction of a normal offer
STAmount ret = (paid * offerOut ) / offerIn;
offerOut -= ret;
offerIn -= paid;
if( (offerOut.value == 0) || (offerIn.value == 0) )
{
offerIn.zero();
offerOut.zero();
}
return ret;
}

View File

@@ -195,6 +195,8 @@ public:
int getOffset() const { return offset; }
uint64 getValue() const { return value; }
void zero() { offset=0; value=0; }
bool isZero() const { return value==0; }
virtual bool isEquivalent(const SerializedType& t) const;
@@ -216,15 +218,18 @@ public:
friend STAmount operator+(STAmount v1, STAmount v2);
friend STAmount operator-(STAmount v1, STAmount v2);
friend STAmount operator/(const STAmount& v1, const STAmount& v2);
friend STAmount operator*(const STAmount& v1, const STAmount& v2);
// Someone is offering X for Y, what is the rate?
friend STAmount getRate(const STAmount& offerIn, const STAmount& offerOut);
friend STAmount getRate(const STAmount& offerOut, const STAmount& offerIn);
// Someone is offering X for Y, I pay Z, how much do I get?
friend STAmount getClaimed(const STAmount& offerIn, const STAmount& offerOut, const STAmount& paid);
// Someone is offering X for Y, I try to pay Z, how much do I get?
// And what's left of the offer? And how much do I actually pay?
friend STAmount getClaimed(STAmount& offerOut, STAmount& offerIn, STAmount& paid);
// Someone is offering X for Y, I need Z, how much do I pay
friend STAmount getNeeded(const STAmount& offerIn, const STAmount& offerOut, const STAmount& needed);
friend STAmount getNeeded(const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed);
};
class STHash128 : public SerializedType