mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 09:50:32 +01:00
CheckpointManager: migrate checkpoints
map to java.time
API
This commit is contained in:
parent
b1ede764a7
commit
838b12c046
@ -42,6 +42,8 @@ import java.nio.ByteOrder;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.DigestInputStream;
|
import java.security.DigestInputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
@ -82,7 +84,7 @@ public class CheckpointManager {
|
|||||||
private static final int MAX_SIGNATURES = 256;
|
private static final int MAX_SIGNATURES = 256;
|
||||||
|
|
||||||
// Map of block header time (in seconds) to data.
|
// Map of block header time (in seconds) to data.
|
||||||
protected final TreeMap<Long, StoredBlock> checkpoints = new TreeMap<>();
|
protected final TreeMap<Instant, StoredBlock> checkpoints = new TreeMap<>();
|
||||||
|
|
||||||
protected final NetworkParameters params;
|
protected final NetworkParameters params;
|
||||||
protected final Sha256Hash dataHash;
|
protected final Sha256Hash dataHash;
|
||||||
@ -144,11 +146,11 @@ public class CheckpointManager {
|
|||||||
throw new IOException("Incomplete read whilst loading checkpoints.");
|
throw new IOException("Incomplete read whilst loading checkpoints.");
|
||||||
StoredBlock block = StoredBlock.deserializeCompact(params, buffer);
|
StoredBlock block = StoredBlock.deserializeCompact(params, buffer);
|
||||||
((Buffer) buffer).position(0);
|
((Buffer) buffer).position(0);
|
||||||
checkpoints.put(block.getHeader().getTimeSeconds(), block);
|
checkpoints.put(block.getHeader().getTimeInstant(), block);
|
||||||
}
|
}
|
||||||
Sha256Hash dataHash = Sha256Hash.wrap(digest.digest());
|
Sha256Hash dataHash = Sha256Hash.wrap(digest.digest());
|
||||||
log.info("Read {} checkpoints up to time {}, hash is {}", checkpoints.size(),
|
log.info("Read {} checkpoints up to time {}, hash is {}", checkpoints.size(),
|
||||||
TimeUtils.dateTimeFormat(checkpoints.lastEntry().getKey() * 1000), dataHash);
|
TimeUtils.dateTimeFormat(checkpoints.lastEntry().getKey().toEpochMilli()), dataHash);
|
||||||
return dataHash;
|
return dataHash;
|
||||||
} catch (ProtocolException e) {
|
} catch (ProtocolException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
@ -181,11 +183,11 @@ public class CheckpointManager {
|
|||||||
buffer.put(bytes);
|
buffer.put(bytes);
|
||||||
((Buffer) buffer).position(0);
|
((Buffer) buffer).position(0);
|
||||||
StoredBlock block = StoredBlock.deserializeCompact(params, buffer);
|
StoredBlock block = StoredBlock.deserializeCompact(params, buffer);
|
||||||
checkpoints.put(block.getHeader().getTimeSeconds(), block);
|
checkpoints.put(block.getHeader().getTimeInstant(), block);
|
||||||
}
|
}
|
||||||
HashCode hash = hasher.hash();
|
HashCode hash = hasher.hash();
|
||||||
log.info("Read {} checkpoints up to time {}, hash is {}", checkpoints.size(),
|
log.info("Read {} checkpoints up to time {}, hash is {}", checkpoints.size(),
|
||||||
TimeUtils.dateTimeFormat(checkpoints.lastEntry().getKey() * 1000), hash);
|
TimeUtils.dateTimeFormat(checkpoints.lastEntry().getKey().toEpochMilli()), hash);
|
||||||
return Sha256Hash.wrap(hash.asBytes());
|
return Sha256Hash.wrap(hash.asBytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,11 +196,11 @@ public class CheckpointManager {
|
|||||||
* Returns a {@link StoredBlock} representing the last checkpoint before the given time, for example, normally
|
* Returns a {@link StoredBlock} representing the last checkpoint before the given time, for example, normally
|
||||||
* you would want to know the checkpoint before the earliest wallet birthday.
|
* you would want to know the checkpoint before the earliest wallet birthday.
|
||||||
*/
|
*/
|
||||||
public StoredBlock getCheckpointBefore(long timeSecs) {
|
public StoredBlock getCheckpointBefore(Instant time) {
|
||||||
try {
|
try {
|
||||||
checkArgument(timeSecs > params.getGenesisBlock().getTimeSeconds());
|
checkArgument(time.isAfter(params.getGenesisBlock().getTimeInstant()));
|
||||||
// This is thread safe because the map never changes after creation.
|
// This is thread safe because the map never changes after creation.
|
||||||
Map.Entry<Long, StoredBlock> entry = checkpoints.floorEntry(timeSecs);
|
Map.Entry<Instant, StoredBlock> entry = checkpoints.floorEntry(time);
|
||||||
if (entry != null) return entry.getValue();
|
if (entry != null) return entry.getValue();
|
||||||
Block genesis = params.getGenesisBlock().cloneAsHeader();
|
Block genesis = params.getGenesisBlock().cloneAsHeader();
|
||||||
return new StoredBlock(genesis, genesis.getWork(), 0);
|
return new StoredBlock(genesis, genesis.getWork(), 0);
|
||||||
@ -207,6 +209,12 @@ public class CheckpointManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #getCheckpointBefore(Instant)} */
|
||||||
|
@Deprecated
|
||||||
|
public StoredBlock getCheckpointBefore(long timeSecs) {
|
||||||
|
return getCheckpointBefore(Instant.ofEpochSecond(timeSecs));
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the number of checkpoints that were loaded. */
|
/** Returns the number of checkpoints that were loaded. */
|
||||||
public int numCheckpoints() {
|
public int numCheckpoints() {
|
||||||
return checkpoints.size();
|
return checkpoints.size();
|
||||||
@ -222,24 +230,30 @@ public class CheckpointManager {
|
|||||||
* time, then inserts it into the store and sets that to be the chain head. Useful when you have just created
|
* time, then inserts it into the store and sets that to be the chain head. Useful when you have just created
|
||||||
* a new store from scratch and want to use configure it all in one go.</p>
|
* a new store from scratch and want to use configure it all in one go.</p>
|
||||||
*
|
*
|
||||||
* <p>Note that timeSecs is adjusted backwards by a week to account for possible clock drift in the block headers.</p>
|
* <p>Note that time is adjusted backwards by a week to account for possible clock drift in the block headers.</p>
|
||||||
*/
|
*/
|
||||||
public static void checkpoint(NetworkParameters params, InputStream checkpoints, BlockStore store, long timeSecs)
|
public static void checkpoint(NetworkParameters params, InputStream checkpoints, BlockStore store, Instant time)
|
||||||
throws IOException, BlockStoreException {
|
throws IOException, BlockStoreException {
|
||||||
checkNotNull(params);
|
checkNotNull(params);
|
||||||
checkNotNull(store);
|
checkNotNull(store);
|
||||||
checkArgument(!(store instanceof FullPrunedBlockStore), "You cannot use checkpointing with a full store.");
|
checkArgument(!(store instanceof FullPrunedBlockStore), "You cannot use checkpointing with a full store.");
|
||||||
|
|
||||||
timeSecs -= 60 * 60 * 24 * 7; // one week in seconds
|
time = time.minus(7, ChronoUnit.WEEKS);
|
||||||
|
|
||||||
checkArgument(timeSecs > 0);
|
log.info("Attempting to initialize a new block store with a checkpoint for time {} ({})", time.getEpochSecond(),
|
||||||
log.info("Attempting to initialize a new block store with a checkpoint for time {} ({})", timeSecs,
|
TimeUtils.dateTimeFormat(time.toEpochMilli()));
|
||||||
TimeUtils.dateTimeFormat(timeSecs * 1000));
|
|
||||||
|
|
||||||
BufferedInputStream stream = new BufferedInputStream(checkpoints);
|
BufferedInputStream stream = new BufferedInputStream(checkpoints);
|
||||||
CheckpointManager manager = new CheckpointManager(params, stream);
|
CheckpointManager manager = new CheckpointManager(params, stream);
|
||||||
StoredBlock checkpoint = manager.getCheckpointBefore(timeSecs);
|
StoredBlock checkpoint = manager.getCheckpointBefore(time);
|
||||||
store.put(checkpoint);
|
store.put(checkpoint);
|
||||||
store.setChainHead(checkpoint);
|
store.setChainHead(checkpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated use {@link #checkpoint(NetworkParameters, InputStream, BlockStore, Instant)} */
|
||||||
|
@Deprecated
|
||||||
|
public static void checkpoint(NetworkParameters params, InputStream checkpoints, BlockStore store, long timeSecs)
|
||||||
|
throws IOException, BlockStoreException {
|
||||||
|
checkpoint(params, checkpoints, store, Instant.ofEpochSecond(timeSecs));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user