| 71 | } |
| 72 | |
| 73 | const char *currencyrate_str(const tal_t *ctx, |
| 74 | const struct bkpr *bkpr, |
| 75 | u64 timestamp, |
| 76 | const struct amount_msat *msat) |
| 77 | { |
| 78 | const struct currencyrate *crate; |
| 79 | u64 mul, intpart, fracpart, raw_rate; |
| 80 | |
| 81 | crate = covering_currencyrate(bkpr, timestamp); |
| 82 | if (!crate) |
| 83 | return NULL; |
| 84 | mul = ratefactor(bkpr->currency); |
| 85 | |
| 86 | if (msat) { |
| 87 | struct amount_msat res; |
| 88 | |
| 89 | /* If multiply overflows, use floating point */ |
| 90 | if (amount_msat_mul(&res, *msat, crate->raw_rate)) { |
| 91 | raw_rate = res.millisatoshis / MSAT_PER_BTC; /* Raw: divide */ |
| 92 | } else { |
| 93 | raw_rate = (double)msat->millisatoshis * crate->raw_rate / MSAT_PER_BTC; /* Raw: double */ |
| 94 | } |
| 95 | } else { |
| 96 | raw_rate = crate->raw_rate; |
| 97 | } |
| 98 | |
| 99 | intpart = raw_rate / mul; |
| 100 | fracpart = raw_rate % mul; |
| 101 | |
| 102 | if (bkpr->currency->minor_unit == 0) |
| 103 | return tal_fmt(ctx, "%"PRIu64, intpart); |
| 104 | |
| 105 | return tal_fmt(ctx, "%"PRIu64".%0*"PRIu64, |
| 106 | intpart, |
| 107 | (int)bkpr->currency->minor_unit, |
| 108 | fracpart); |
| 109 | } |
| 110 | |
| 111 | void json_add_currencyrate(struct json_stream *result, |
| 112 | const char *fieldname, |
no test coverage detected