From 6bf6d86cd9b34f0a5edbdd60ffce9141b095dded Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 10 Apr 2012 15:26:44 -0700 Subject: [PATCH] Offer logic seems to be working now. --- src/Amount.cpp | 73 ++++++++++++++++++++++++++++++++++++++----- src/SerializedTypes.h | 13 +++++--- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/Amount.cpp b/src/Amount.cpp index d514ab0eb4..90ec1fc731 100644 --- a/src/Amount.cpp +++ b/src/Amount.cpp @@ -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(*this); + str << std::setprecision(14) << static_cast(*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("ient, 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("ient)<=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; } diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index ceddccb173..9dad1cb6fe 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -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