From a0d8018e1f58a6486416b0ec25619e116fed36d6 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Mon, 2 Sep 2024 23:59:33 +0200 Subject: [PATCH] Transaction: migrate isFinal() to Instant Keep the old method as deprecated. --- .../java/org/bitcoinj/core/AbstractBlockChain.java | 2 +- .../src/main/java/org/bitcoinj/core/Transaction.java | 12 +++++++++--- .../org/bitcoinj/wallet/DefaultRiskAnalysis.java | 5 ++--- .../org/bitcoinj/core/FullBlockTestGenerator.java | 4 ++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/AbstractBlockChain.java b/core/src/main/java/org/bitcoinj/core/AbstractBlockChain.java index ed1ace649..d22ad7b8b 100644 --- a/core/src/main/java/org/bitcoinj/core/AbstractBlockChain.java +++ b/core/src/main/java/org/bitcoinj/core/AbstractBlockChain.java @@ -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"); } diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java index 8f74e4438..3a479e621 100644 --- a/core/src/main/java/org/bitcoinj/core/Transaction.java +++ b/core/src/main/java/org/bitcoinj/core/Transaction.java @@ -1652,7 +1652,7 @@ public class Transaction extends BaseMessage { *

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.

* - *

To check if this transaction is final at a given height and time, see {@link Transaction#isFinal(int, long)} + *

To check if this transaction is final at a given height and time, see {@link Transaction#isFinal(int, Instant)} *

*/ public boolean isTimeLocked() { @@ -1698,12 +1698,18 @@ public class Transaction extends BaseMessage { *

Note that currently the replacement feature is disabled in Bitcoin Core and will need to be * re-activated before this functionality is useful.

*/ - 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. diff --git a/core/src/main/java/org/bitcoinj/wallet/DefaultRiskAnalysis.java b/core/src/main/java/org/bitcoinj/wallet/DefaultRiskAnalysis.java index 9799cb073..a5c45b15e 100644 --- a/core/src/main/java/org/bitcoinj/wallet/DefaultRiskAnalysis.java +++ b/core/src/main/java/org/bitcoinj/wallet/DefaultRiskAnalysis.java @@ -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; } diff --git a/core/src/test/java/org/bitcoinj/core/FullBlockTestGenerator.java b/core/src/test/java/org/bitcoinj/core/FullBlockTestGenerator.java index 0eef3871e..b6866ffad 100644 --- a/core/src/test/java/org/bitcoinj/core/FullBlockTestGenerator.java +++ b/core/src/test/java/org/bitcoinj/core/FullBlockTestGenerator.java @@ -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"));