Skip to content

Commit

Permalink
Merge pull request #133 from muun/51.2-release-branch
Browse files Browse the repository at this point in the history
Apollo: Release source code for 51.2
  • Loading branch information
acrespo authored Oct 27, 2023
2 parents f497acd + 4e4616d commit a98e5f2
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 10 deletions.
10 changes: 9 additions & 1 deletion android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ follow [https://changelog.md/](https://changelog.md/) guidelines.

## [Unreleased]

### FIXED

## [51.2] - 2023-10-24

### FIXED

- NPE when trying to recycling a QR bitmap before is was fully loaded.

## [51.1] - 2023-10-17

### ADDED
Expand Down Expand Up @@ -36,7 +44,7 @@ request.
- Satoshis copy in Select Bitcoin Unit screen. Now explicitly naming the option Satoshi (SAT),
instead of Bitcoin (SAT).
- Silence noisy DRM errors.
- Huge revamp to UI test suite. Enhancing reliability o coverage.
- Huge revamp to UI test suite. Enhancing reliability and coverage.

## [51] - 2023-07-28

Expand Down
4 changes: 2 additions & 2 deletions android/apolloui/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ android {
applicationId "io.muun.apollo"
minSdkVersion 19
targetSdkVersion 33
versionCode 1101
versionName "51.1"
versionCode 1102
versionName "51.2"

// Needed to make sure these classes are available in the main DEX file for API 19
// See: https://spin.atomicobject.com/2018/07/16/support-kitkat-multidex/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ abstract class QrFragment<PresenterT : QrPresenter<*>> : SingleFragment<Presente
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
bitmap.setPixels(pixels, 0, width, 0, 0, width, height)

// Since we just created a bitmap with default (aka bilinear) filtering, that smoothes the
// Since we just created a bitmap with default (aka bilinear) filtering, that smooths the
// contrast between adjacent pixels, which is normally GREAT for images, but no so much for
// our current case: QRs. So we create another bitmap, using "nearest-neighbor scaling".
// See: https://www.geeksforgeeks.org/css-image-rendering-property/
Expand All @@ -114,8 +114,10 @@ abstract class QrFragment<PresenterT : QrPresenter<*>> : SingleFragment<Presente
}

override fun onDestroyView() {
Timber.d("Recycling QR image Bitmap")
(qrImage.drawable as BitmapDrawable).bitmap.recycle()
if (qrImage.drawable != null) {
Timber.d("Recycling QR image Bitmap")
(qrImage.drawable as BitmapDrawable).bitmap.recycle()
}
super.onDestroyView()
}
}
11 changes: 7 additions & 4 deletions common/src/main/java/io/muun/common/model/BtcAmount.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.muun.common.model;

import com.google.common.annotations.VisibleForTesting;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
Expand All @@ -14,7 +16,8 @@ public class BtcAmount {

private static final long MSATS_PER_SAT = 1_000L;

private static final long MSATS_PER_BTC = 100_000_000_000L;
@VisibleForTesting
static final long MSATS_PER_BTC = 100_000_000_000L;

private final long milliSats;

Expand All @@ -33,7 +36,7 @@ public static BtcAmount fromSats(long satoshis) {
* Build an amount from BTC.
*/
public static BtcAmount fromBtc(double btc) {
return new BtcAmount((long)(btc * MSATS_PER_BTC));
return new BtcAmount(Math.round(btc * MSATS_PER_BTC));
}

/**
Expand Down Expand Up @@ -70,7 +73,7 @@ public long toSats(final RoundingMode roundingMode) {
}

/**
* Conver to BTC.
* Converts to BTC. Amounts greater than 10,000 BTC will lose the milliSat resolution
*/
public double toBtc() {
return ((double) milliSats) / MSATS_PER_BTC;
Expand Down Expand Up @@ -137,7 +140,7 @@ public BtcAmount max(@NotNull BtcAmount other) {
}

/**
* Return the smaller of this amount and the other.
* Return the smallest of this amount and the other.
*/
public BtcAmount min(@NotNull BtcAmount other) {
return BtcAmount.fromMilliSats(Math.min(milliSats, other.milliSats));
Expand Down
75 changes: 75 additions & 0 deletions common/src/test/java/io/muun/common/model/BtcAmountTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package io.muun.common.model;

import org.assertj.core.util.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import java.util.List;

import static io.muun.common.model.BtcAmount.MSATS_PER_BTC;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.withPrecision;

/**
* Checks that no unnecessary precision is lost when converting BTC amounts to {@link BtcAmount}.
*/
@RunWith(Parameterized.class)
public class BtcAmountTest {

/** Number of decimal digits that can be represented in a double precision IEEE floating point
* number without losing any precision.
* @see jdk.internal.math.FloatingDecimal#MAX_DECIMAL_DIGITS
*/
private static final int DECIMAL_DIGITS_REPRESENTABLE_IN_DOUBLE = 15;
private static final int DECIMAL_DIGITS = 10;
private static final double ONE_MILLI_SATOSHI_IN_BTC = 1.0d / MSATS_PER_BTC;
private final double btc;

public BtcAmountTest(double btc) {
this.btc = btc;
}

@Test
public void fromAmountToBtcMinimumResolution() {
assertThat(BtcAmount.fromBtc(btc).toBtc())
.isEqualTo(
btc,
withPrecision(ONE_MILLI_SATOSHI_IN_BTC / 2)
);
}

/**
* Generates BTC amounts for all the possible quantities of <b>milliSatoshi</b>s of the form
* d * 10^x + 1, i.e. a single decimal digit d followed of x zeros. Those amounts are then
* perturbed by adding a single milliSatoshi. The exponent goes up to 15, which is the maximum
* amount of decimal digits representable by a double precision IEEE number
*/
@Parameters(name = "{index}: Amount {0,number,0.00000000000} btc")
public static Iterable<Object> allOrdersOfMagnitude() {
final List<Object> values = Lists.newArrayList();

for (int i = 1; i < DECIMAL_DIGITS; i++) {
values.add(multipleOfOneMilliSatoshi(0, i));
}
for (int position = 1; position < DECIMAL_DIGITS_REPRESENTABLE_IN_DOUBLE; position++) {
for (int digit = 1; digit < DECIMAL_DIGITS; digit++) {
values.add(multipleOfOneMilliSatoshi(position, digit) + ONE_MILLI_SATOSHI_IN_BTC);
}
}
return values;
}

/**
* Generates a BTC amount based on a quantity of <b>milliSatoshi</b>s of the form
* <code>digitValue</code> * 10^<code>digitPosition</code> where <code>digitValue</code>
* is a number in [0, 9].
* @param digitPosition the position of the digit
* @param digitValue the digit of the amount
* @return The BTC amount built as specified
*/
private static double multipleOfOneMilliSatoshi(int digitPosition, int digitValue) {
return ONE_MILLI_SATOSHI_IN_BTC * Math.pow(DECIMAL_DIGITS, digitPosition) * digitValue;
}
}

0 comments on commit a98e5f2

Please sign in to comment.