diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java index 82bc40a..5a14739 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java @@ -391,16 +391,24 @@ public class GenerateFragment extends Fragment { // is it a date? SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd"); parser.setLenient(false); - parser.parse(restoreHeight); - height = RestoreHeight.getInstance().getHeight(restoreHeight); - } catch (ParseException exPE) { + height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight)); + } catch (ParseException ex) { + } + if (height <= 0) + try { + // is it a date without dashes? + SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd"); + parser.setLenient(false); + height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight)); + } catch (ParseException ex) { + } + if (height <= 0) try { // or is it a height? height = Long.parseLong(restoreHeight); - } catch (NumberFormatException exNFE) { + } catch (NumberFormatException ex) { return -1; } - } Timber.d("Using Restore Height = %d", height); return height; } diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/RestoreHeight.java b/app/src/main/java/com/m2049r/xmrwallet/util/RestoreHeight.java index 6d8374a..43b7a3e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/RestoreHeight.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/RestoreHeight.java @@ -19,6 +19,7 @@ package com.m2049r.xmrwallet.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.TimeZone; @@ -89,6 +90,10 @@ public class RestoreHeight { blockheight.put("2018-02-01", 1499599L); blockheight.put("2018-03-01", 1519796L); blockheight.put("2018-04-01", 1542067L); + blockheight.put("2018-05-01", 1562861L); + blockheight.put("2018-06-01", 1585135L); + blockheight.put("2018-07-01", 1606715L); + blockheight.put("2018-08-01", 1629017L); } public long getHeight(String date) { @@ -96,59 +101,66 @@ public class RestoreHeight { parser.setTimeZone(TimeZone.getTimeZone("UTC")); parser.setLenient(false); try { - Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - cal.set(Calendar.DST_OFFSET, 0); - cal.setTime(parser.parse(date)); - cal.add(Calendar.DAY_OF_MONTH, -4); // give it some leeway - if (cal.get(Calendar.YEAR) < 2014) - return 1; - if ((cal.get(Calendar.YEAR) == 2014) && (cal.get(Calendar.MONTH) <= 3)) - // before May 2014 - return 1; - - Calendar query = (Calendar) cal.clone(); - - SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); - formatter.setTimeZone(TimeZone.getTimeZone("UTC")); - cal.set(Calendar.DAY_OF_MONTH, 1); - long prevTime = cal.getTimeInMillis(); - String prevDate = formatter.format(prevTime); - // lookup blockheight at first of the month - Long prevBc = blockheight.get(prevDate); - if (prevBc == null) { - // if too recent, go back in time and find latest one we have - while (prevBc == null) { - cal.add(Calendar.MONTH, -1); - if (cal.get(Calendar.YEAR) < 2014) { - throw new IllegalStateException("endless loop looking for blockheight"); - } - prevTime = cal.getTimeInMillis(); - prevDate = formatter.format(prevTime); - prevBc = blockheight.get(prevDate); - } - } - long height = prevBc; - // now we have a blockheight & a date ON or BEFORE the restore date requested - if (date.equals(prevDate)) return height; - // see if we have a blockheight after this date - cal.add(Calendar.MONTH, 1); - long nextTime = cal.getTimeInMillis(); - String nextDate = formatter.format(nextTime); - Long nextBc = blockheight.get(nextDate); - if (nextBc != null) { // we have a range - interpolate the blockheight we are looking for - long diff = nextBc - prevBc; - long diffDays = TimeUnit.DAYS.convert(nextTime - prevTime, TimeUnit.MILLISECONDS); - long days = TimeUnit.DAYS.convert(query.getTimeInMillis() - prevTime, - TimeUnit.MILLISECONDS); - height = Math.round(prevBc + diff * (1.0 * days / diffDays)); - } else { - long days = TimeUnit.DAYS.convert(query.getTimeInMillis() - prevTime, - TimeUnit.MILLISECONDS); - height = Math.round(prevBc + 1.0 * days * (24 * 60 / 2)); - } - return height; + return getHeight(parser.parse(date)); } catch (ParseException ex) { throw new IllegalArgumentException(ex); } } + + public long getHeight(final Date date) { + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.set(Calendar.DST_OFFSET, 0); + cal.setTime(date); + cal.add(Calendar.DAY_OF_MONTH, -4); // give it some leeway + if (cal.get(Calendar.YEAR) < 2014) + return 0; + if ((cal.get(Calendar.YEAR) == 2014) && (cal.get(Calendar.MONTH) <= 3)) + // before May 2014 + return 0; + + Calendar query = (Calendar) cal.clone(); + + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + formatter.setTimeZone(TimeZone.getTimeZone("UTC")); + + String queryDate = formatter.format(date); + + cal.set(Calendar.DAY_OF_MONTH, 1); + long prevTime = cal.getTimeInMillis(); + String prevDate = formatter.format(prevTime); + // lookup blockheight at first of the month + Long prevBc = blockheight.get(prevDate); + if (prevBc == null) { + // if too recent, go back in time and find latest one we have + while (prevBc == null) { + cal.add(Calendar.MONTH, -1); + if (cal.get(Calendar.YEAR) < 2014) { + throw new IllegalStateException("endless loop looking for blockheight"); + } + prevTime = cal.getTimeInMillis(); + prevDate = formatter.format(prevTime); + prevBc = blockheight.get(prevDate); + } + } + long height = prevBc; + // now we have a blockheight & a date ON or BEFORE the restore date requested + if (queryDate.equals(prevDate)) return height; + // see if we have a blockheight after this date + cal.add(Calendar.MONTH, 1); + long nextTime = cal.getTimeInMillis(); + String nextDate = formatter.format(nextTime); + Long nextBc = blockheight.get(nextDate); + if (nextBc != null) { // we have a range - interpolate the blockheight we are looking for + long diff = nextBc - prevBc; + long diffDays = TimeUnit.DAYS.convert(nextTime - prevTime, TimeUnit.MILLISECONDS); + long days = TimeUnit.DAYS.convert(query.getTimeInMillis() - prevTime, + TimeUnit.MILLISECONDS); + height = Math.round(prevBc + diff * (1.0 * days / diffDays)); + } else { + long days = TimeUnit.DAYS.convert(query.getTimeInMillis() - prevTime, + TimeUnit.MILLISECONDS); + height = Math.round(prevBc + 1.0 * days * (24 * 60 / 2)); + } + return height; + } } diff --git a/app/src/test/java/com/m2049r/xmrwallet/util/RestoreHeightTest.java b/app/src/test/java/com/m2049r/xmrwallet/util/RestoreHeightTest.java index 620b06e..51185d9 100644 --- a/app/src/test/java/com/m2049r/xmrwallet/util/RestoreHeightTest.java +++ b/app/src/test/java/com/m2049r/xmrwallet/util/RestoreHeightTest.java @@ -30,18 +30,18 @@ public class RestoreHeightTest { @Test public void pre2014() { - assertTrue(getHeight("2013-12-01") == 1); - assertTrue(getHeight("1958-12-01") == 1); + assertTrue(getHeight("2013-12-01") == 0); + assertTrue(getHeight("1958-12-01") == 0); } @Test public void zero() { - assertTrue(getHeight("2014-04-27") == 1); + assertTrue(getHeight("2014-04-27") == 0); } @Test public void notZero() { - assertTrue(getHeight("2014-05-07") > 1); + assertTrue(getHeight("2014-05-07") > 0); } @Test(expected = IllegalArgumentException.class) @@ -83,7 +83,7 @@ public class RestoreHeightTest { @Test public void test2014() { - assertTrue(isInRange(getHeight("2014-04-26"), 1, 8501)); + assertTrue(isInRange(getHeight("2014-04-26"), 0, 8501)); assertTrue(isInRange(getHeight("2014-05-09"), 20289, 28311)); assertTrue(isInRange(getHeight("2014-05-17"), 32608, 40075)); assertTrue(isInRange(getHeight("2014-05-30"), 52139, 59548)); @@ -116,9 +116,9 @@ public class RestoreHeightTest { @Test public void postFuture() { - long b_20180208 = 1504715; - long b_20180808 = b_20180208 + 720 * (28 + 31 + 30 + 31 + 30 + 31); - assertTrue(isInRange(getHeight("2018-08-08"), b_20180808 - 720 * 5, b_20180808)); + long b_20180701 = 1606715L; + long b_20190108 = b_20180701 + 720 * (31 + 31 + 30 + 31 + 30 + 31 + 7); + assertTrue(isInRange(getHeight("2019-01-08"), b_20190108 - 720 * 5, b_20190108)); }