mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 18:00:39 +01:00
Wallet: migrate lastBlockSeenTime
field to java.time
API
This commit is contained in:
parent
be0b2b46b8
commit
da8b9ce434
@ -31,7 +31,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
@ -91,21 +93,23 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
|
||||
if (wallet == null)
|
||||
return null;
|
||||
|
||||
|
||||
final int height = wallet.getLastBlockSeenHeight();
|
||||
final long time = wallet.getLastBlockSeenTimeSecs();
|
||||
if (time == 0)
|
||||
final Optional<Instant> time = wallet.getLastBlockSeenTimeInstant();
|
||||
if (!time.isPresent())
|
||||
return null;
|
||||
|
||||
// If the transaction has a lock time specified in blocks, we consider that if the tx would become final in the
|
||||
// next block it is not risky (as it would confirm normally).
|
||||
final int adjustedHeight = height + 1;
|
||||
final long timeSecs = time.get().getEpochSecond();
|
||||
|
||||
if (!tx.isFinal(adjustedHeight, time)) {
|
||||
if (!tx.isFinal(adjustedHeight, timeSecs)) {
|
||||
nonFinal = tx;
|
||||
return Result.NON_FINAL;
|
||||
}
|
||||
for (Transaction dep : dependencies) {
|
||||
if (!dep.isFinal(adjustedHeight, time)) {
|
||||
if (!dep.isFinal(adjustedHeight, timeSecs)) {
|
||||
nonFinal = dep;
|
||||
return Result.NON_FINAL;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ public class Wallet extends BaseTaggableObject
|
||||
|
||||
@Nullable private Sha256Hash lastBlockSeenHash;
|
||||
private int lastBlockSeenHeight;
|
||||
private long lastBlockSeenTimeSecs;
|
||||
@Nullable private Instant lastBlockSeenTime;
|
||||
|
||||
private final List<ListenerRegistration<WalletChangeEventListener>> changeListeners
|
||||
= new CopyOnWriteArrayList<>();
|
||||
@ -2447,7 +2447,7 @@ public class Wallet extends BaseTaggableObject
|
||||
// Store the new block hash.
|
||||
setLastBlockSeenHash(newBlockHash);
|
||||
setLastBlockSeenHeight(block.getHeight());
|
||||
setLastBlockSeenTimeSecs(block.getHeader().getTimeSeconds());
|
||||
setLastBlockSeenTime(block.getHeader().getTimeInstant());
|
||||
// Notify all the BUILDING transactions of the new block.
|
||||
// This is so that they can update their depth.
|
||||
Set<Transaction> transactions = getTransactions(true);
|
||||
@ -3292,7 +3292,7 @@ public class Wallet extends BaseTaggableObject
|
||||
clearTransactions();
|
||||
lastBlockSeenHash = null;
|
||||
lastBlockSeenHeight = -1; // Magic value for 'never'.
|
||||
lastBlockSeenTimeSecs = 0;
|
||||
lastBlockSeenTime = null;
|
||||
saveLater();
|
||||
maybeQueueOnWalletChanged();
|
||||
} finally {
|
||||
@ -3510,9 +3510,10 @@ public class Wallet extends BaseTaggableObject
|
||||
builder.append(" ").append(unspent.size()).append(" unspent\n");
|
||||
builder.append(" ").append(spent.size()).append(" spent\n");
|
||||
builder.append(" ").append(dead.size()).append(" dead\n");
|
||||
final Date lastBlockSeenTime = getLastBlockSeenTime();
|
||||
builder.append("Last seen best block: ").append(getLastBlockSeenHeight()).append(" (")
|
||||
.append(lastBlockSeenTime == null ? "time unknown" : TimeUtils.dateTimeFormat(lastBlockSeenTime))
|
||||
.append(getLastBlockSeenTimeInstant()
|
||||
.map(instant -> TimeUtils.dateTimeFormat(instant.toEpochMilli()))
|
||||
.orElse("time unknown"))
|
||||
.append("): ").append(getLastBlockSeenHash()).append('\n');
|
||||
final KeyCrypter crypter = keyChainGroup.getKeyCrypter();
|
||||
if (crypter != null)
|
||||
@ -3667,45 +3668,58 @@ public class Wallet extends BaseTaggableObject
|
||||
}
|
||||
}
|
||||
|
||||
public void setLastBlockSeenTimeSecs(long timeSecs) {
|
||||
public void setLastBlockSeenTime(Instant time) {
|
||||
lock.lock();
|
||||
try {
|
||||
lastBlockSeenTimeSecs = timeSecs;
|
||||
lastBlockSeenTime = checkNotNull(time);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearLastBlockSeenTime() {
|
||||
lock.lock();
|
||||
try {
|
||||
lastBlockSeenTime = null;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #setLastBlockSeenTime(Instant)} or {@link #clearLastBlockSeenTime()} */
|
||||
@Deprecated
|
||||
public void setLastBlockSeenTimeSecs(long timeSecs) {
|
||||
checkArgument(timeSecs > 0);
|
||||
setLastBlockSeenTime(Instant.ofEpochSecond(timeSecs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UNIX time in seconds since the epoch extracted from the last best seen block header. This timestamp
|
||||
* Returns time extracted from the last best seen block header, or empty. This timestamp
|
||||
* is <b>not</b> the local time at which the block was first observed by this application but rather what the block
|
||||
* (i.e. miner) self declares. It is allowed to have some significant drift from the real time at which the block
|
||||
* was found, although most miners do use accurate times. If this wallet is old and does not have a recorded
|
||||
* time then this method returns zero.
|
||||
*/
|
||||
public long getLastBlockSeenTimeSecs() {
|
||||
public Optional<Instant> getLastBlockSeenTimeInstant() {
|
||||
lock.lock();
|
||||
try {
|
||||
return lastBlockSeenTimeSecs;
|
||||
return Optional.ofNullable(lastBlockSeenTime);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Date} representing the time extracted from the last best seen block header. This timestamp
|
||||
* is <b>not</b> the local time at which the block was first observed by this application but rather what the block
|
||||
* (i.e. miner) self declares. It is allowed to have some significant drift from the real time at which the block
|
||||
* was found, although most miners do use accurate times. If this wallet is old and does not have a recorded
|
||||
* time then this method returns null.
|
||||
*/
|
||||
/** @deprecated use {@link #getLastBlockSeenTimeInstant()} */
|
||||
@Deprecated
|
||||
public long getLastBlockSeenTimeSecs() {
|
||||
return getLastBlockSeenTimeInstant().map(Instant::getEpochSecond).orElse((long) 0);
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #getLastBlockSeenTimeInstant()} */
|
||||
@Deprecated
|
||||
@Nullable
|
||||
public Date getLastBlockSeenTime() {
|
||||
final long secs = getLastBlockSeenTimeSecs();
|
||||
if (secs == 0)
|
||||
return null;
|
||||
else
|
||||
return new Date(secs * 1000);
|
||||
return getLastBlockSeenTimeInstant().map(Date::from).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,10 +94,11 @@ public class WalletFiles {
|
||||
// Some other scheduled request already beat us to it.
|
||||
return null;
|
||||
}
|
||||
Date lastBlockSeenTime = wallet.getLastBlockSeenTime();
|
||||
log.info("Background saving wallet; last seen block is height {}, date {}, hash {}",
|
||||
wallet.getLastBlockSeenHeight(),
|
||||
lastBlockSeenTime != null ? TimeUtils.dateTimeFormat(lastBlockSeenTime) : "unknown",
|
||||
wallet.getLastBlockSeenTimeInstant()
|
||||
.map(time -> TimeUtils.dateTimeFormat(time.toEpochMilli()))
|
||||
.orElse("unknown"),
|
||||
wallet.getLastBlockSeenHash());
|
||||
saveNowInternal();
|
||||
return null;
|
||||
@ -128,9 +129,10 @@ public class WalletFiles {
|
||||
// but they will serialize (using different temp files).
|
||||
if (executor.isShutdown())
|
||||
return;
|
||||
Date lastBlockSeenTime = wallet.getLastBlockSeenTime();
|
||||
log.info("Saving wallet; last seen block is height {}, date {}, hash {}", wallet.getLastBlockSeenHeight(),
|
||||
lastBlockSeenTime != null ? TimeUtils.dateTimeFormat(lastBlockSeenTime) : "unknown",
|
||||
wallet.getLastBlockSeenTimeInstant()
|
||||
.map(time -> TimeUtils.dateTimeFormat(time.toEpochMilli()))
|
||||
.orElse("unknown"),
|
||||
wallet.getLastBlockSeenHash());
|
||||
saveNowInternal();
|
||||
}
|
||||
|
@ -201,8 +201,8 @@ public class WalletProtobufSerializer {
|
||||
walletBuilder.setLastSeenBlockHash(hashToByteString(lastSeenBlockHash));
|
||||
walletBuilder.setLastSeenBlockHeight(wallet.getLastBlockSeenHeight());
|
||||
}
|
||||
if (wallet.getLastBlockSeenTimeSecs() > 0)
|
||||
walletBuilder.setLastSeenBlockTimeSecs(wallet.getLastBlockSeenTimeSecs());
|
||||
wallet.getLastBlockSeenTimeInstant().ifPresent(
|
||||
time -> walletBuilder.setLastSeenBlockTimeSecs(time.getEpochSecond()));
|
||||
|
||||
// Populate the scrypt parameters.
|
||||
KeyCrypter keyCrypter = wallet.getKeyCrypter();
|
||||
@ -525,7 +525,7 @@ public class WalletProtobufSerializer {
|
||||
// Should mirror Wallet.reset()
|
||||
wallet.setLastBlockSeenHash(null);
|
||||
wallet.setLastBlockSeenHeight(-1);
|
||||
wallet.setLastBlockSeenTimeSecs(0);
|
||||
wallet.clearLastBlockSeenTime();
|
||||
} else {
|
||||
// Read all transactions and insert into the txMap.
|
||||
for (Protos.Transaction txProto : walletProto.getTransactionList()) {
|
||||
@ -550,7 +550,7 @@ public class WalletProtobufSerializer {
|
||||
wallet.setLastBlockSeenHeight(walletProto.getLastSeenBlockHeight());
|
||||
}
|
||||
// Will default to zero if not present.
|
||||
wallet.setLastBlockSeenTimeSecs(walletProto.getLastSeenBlockTimeSecs());
|
||||
wallet.setLastBlockSeenTime(Instant.ofEpochSecond(walletProto.getLastSeenBlockTimeSecs()));
|
||||
|
||||
if (walletProto.hasKeyRotationTime()) {
|
||||
wallet.setKeyRotationTime(Instant.ofEpochSecond(walletProto.getKeyRotationTime()));
|
||||
|
@ -37,6 +37,7 @@ import org.bitcoinj.wallet.DefaultRiskAnalysis.RuleViolation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -61,7 +62,7 @@ public class DefaultRiskAnalysisTest {
|
||||
Context.propagate(new Context());
|
||||
wallet = Wallet.createDeterministic(MAINNET, ScriptType.P2PKH);
|
||||
wallet.setLastBlockSeenHeight(1000);
|
||||
wallet.setLastBlockSeenTimeSecs(TIMESTAMP);
|
||||
wallet.setLastBlockSeenTime(Instant.ofEpochSecond(TIMESTAMP));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
|
@ -1538,7 +1538,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Receive a block on the best chain - this should set the last block seen hash.
|
||||
chain.add(b10);
|
||||
assertEquals(b10.getHash(), wallet.getLastBlockSeenHash());
|
||||
assertEquals(b10.getTimeSeconds(), wallet.getLastBlockSeenTimeSecs());
|
||||
assertEquals(b10.getTimeInstant(), wallet.getLastBlockSeenTimeInstant().get());
|
||||
assertEquals(1, wallet.getLastBlockSeenHeight());
|
||||
// Receive a block on the side chain - this should not change the last block seen hash.
|
||||
chain.add(b11);
|
||||
|
Loading…
Reference in New Issue
Block a user