Transaction: migrate isFinal() to Instant

Keep the old method as deprecated.
This commit is contained in:
Andreas Schildbach 2024-09-02 23:59:33 +02:00
parent 8d1a2cc966
commit a0d8018e1f
4 changed files with 14 additions and 9 deletions

View File

@ -589,7 +589,7 @@ public abstract class AbstractBlockChain {
throw new VerificationException("Block failed checkpoint lockin at " + (storedPrev.getHeight() + 1));
if (shouldVerifyTransactions()) {
for (Transaction tx : block.getTransactions())
if (!tx.isFinal(storedPrev.getHeight() + 1, block.getTimeSeconds()))
if (!tx.isFinal(storedPrev.getHeight() + 1, block.time()))
throw new VerificationException("Block contains non-final transaction");
}

View File

@ -1652,7 +1652,7 @@ public class Transaction extends BaseMessage {
* <p>A transaction is time-locked if at least one of its inputs is non-final and it has a lock time. A transaction can
* also have a relative lock time which this method doesn't tell. Use {@link #hasRelativeLockTime()} to find out.</p>
*
* <p>To check if this transaction is final at a given height and time, see {@link Transaction#isFinal(int, long)}
* <p>To check if this transaction is final at a given height and time, see {@link Transaction#isFinal(int, Instant)}
* </p>
*/
public boolean isTimeLocked() {
@ -1698,12 +1698,18 @@ public class Transaction extends BaseMessage {
* <p>Note that currently the replacement feature is disabled in Bitcoin Core and will need to be
* re-activated before this functionality is useful.</p>
*/
public boolean isFinal(int height, long blockTimeSeconds) {
public boolean isFinal(int height, Instant blockTime) {
LockTime locktime = lockTime();
return locktime.rawValue() < (locktime instanceof HeightLock ? height : blockTimeSeconds) ||
return locktime.rawValue() < (locktime instanceof HeightLock ? height : blockTime.getEpochSecond()) ||
!isTimeLocked();
}
/** @deprecated use {@link #isFinal(int, Instant)} */
@Deprecated
public boolean isFinal(int height, long blockTimeSeconds) {
return isFinal(height, Instant.ofEpochSecond(blockTimeSeconds));
}
/**
* Returns either the lock time, if it was specified as a timestamp, or an estimate based on the time in
* the current head block if it was specified as a block height.

View File

@ -102,14 +102,13 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
// 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, timeSecs)) {
if (!tx.isFinal(adjustedHeight, time.get())) {
nonFinal = tx;
return Result.NON_FINAL;
}
for (Transaction dep : dependencies) {
if (!dep.isFinal(adjustedHeight, timeSecs)) {
if (!dep.isFinal(adjustedHeight, time.get())) {
nonFinal = dep;
return Result.NON_FINAL;
}

View File

@ -1181,7 +1181,7 @@ public class FullBlockTestGenerator {
tx.addOutput(ZERO, OP_TRUE_SCRIPT);
addOnlyInputToTransaction(tx, out18, 0);
b62.addTransaction(tx);
checkState(!tx.isFinal(chainHeadHeight + 17, b62.block.getTimeSeconds()));
checkState(!tx.isFinal(chainHeadHeight + 17, b62.block.time()));
}
b62.solve();
blocks.add(new BlockAndValidity(b62, false, true, b60.getHash(), chainHeadHeight + 18, "b62"));
@ -1194,7 +1194,7 @@ public class FullBlockTestGenerator {
{
b63.block.getTransactions().get(0).setLockTime(0xffffffffL);
b63.block.getTransactions().get(0).getInput(0).setSequenceNumber(0xdeadbeefL);
checkState(!b63.block.getTransactions().get(0).isFinal(chainHeadHeight + 17, b63.block.getTimeSeconds()));
checkState(!b63.block.getTransactions().get(0).isFinal(chainHeadHeight + 17, b63.block.time()));
}
b63.solve();
blocks.add(new BlockAndValidity(b63, false, true, b60.getHash(), chainHeadHeight + 18, "b63"));