update restoreheightdate handling (#370)

* restore date without dashes

* heights upated to august 2018
This commit is contained in:
m2049r 2018-08-01 08:25:25 +02:00 committed by GitHub
parent 0bf3c6f099
commit 403dbdf14f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 64 deletions

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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));
}