mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-19 05:33:44 +01:00
Move Transaction.isConsistent() to Wallet.isTxConsistent(), as the wallet was the only consumer of that method.
This commit is contained in:
parent
8af0fa9884
commit
09a2ca64d2
@ -270,29 +270,6 @@ public class Transaction extends ChildMessage {
|
|||||||
return inputTotal;
|
return inputTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If isSpent - check that all my outputs spent, otherwise check that there at least
|
|
||||||
* one unspent.
|
|
||||||
*/
|
|
||||||
boolean isConsistent(TransactionBag transactionBag, boolean isSpent) {
|
|
||||||
boolean isActuallySpent = true;
|
|
||||||
for (TransactionOutput o : outputs) {
|
|
||||||
if (o.isAvailableForSpending()) {
|
|
||||||
if (o.isMineOrWatched(transactionBag)) isActuallySpent = false;
|
|
||||||
if (o.getSpentBy() != null) {
|
|
||||||
log.error("isAvailableForSpending != spentBy");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (o.getSpentBy() == null) {
|
|
||||||
log.error("isAvailableForSpending != spentBy");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return isActuallySpent == isSpent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
|
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
|
||||||
*/
|
*/
|
||||||
|
@ -1505,14 +1505,14 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Transaction tx : unspent.values()) {
|
for (Transaction tx : unspent.values()) {
|
||||||
if (!tx.isConsistent(this, false)) {
|
if (!isTxConsistent(tx, false)) {
|
||||||
success = false;
|
success = false;
|
||||||
log.error("Inconsistent unspent tx {}", tx.getHashAsString());
|
log.error("Inconsistent unspent tx {}", tx.getHashAsString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Transaction tx : spent.values()) {
|
for (Transaction tx : spent.values()) {
|
||||||
if (!tx.isConsistent(this, true)) {
|
if (!isTxConsistent(tx, true)) {
|
||||||
success = false;
|
success = false;
|
||||||
log.error("Inconsistent spent tx {}", tx.getHashAsString());
|
log.error("Inconsistent spent tx {}", tx.getHashAsString());
|
||||||
}
|
}
|
||||||
@ -1531,6 +1531,30 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If isSpent - check that all my outputs spent, otherwise check that there at least
|
||||||
|
* one unspent.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isTxConsistent(final Transaction tx, final boolean isSpent) {
|
||||||
|
boolean isActuallySpent = true;
|
||||||
|
for (TransactionOutput o : tx.getOutputs()) {
|
||||||
|
if (o.isAvailableForSpending()) {
|
||||||
|
if (o.isMineOrWatched(this)) isActuallySpent = false;
|
||||||
|
if (o.getSpentBy() != null) {
|
||||||
|
log.error("isAvailableForSpending != spentBy");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (o.getSpentBy() == null) {
|
||||||
|
log.error("isAvailableForSpending != spentBy");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isActuallySpent == isSpent;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a wallet deserialized from the given input stream and wallet extensions. */
|
/** Returns a wallet deserialized from the given input stream and wallet extensions. */
|
||||||
public static Wallet loadFromFileStream(InputStream stream, @Nullable WalletExtension... walletExtensions) throws UnreadableWalletException {
|
public static Wallet loadFromFileStream(InputStream stream, @Nullable WalletExtension... walletExtensions) throws UnreadableWalletException {
|
||||||
Wallet wallet = new WalletProtobufSerializer().readWallet(stream, walletExtensions);
|
Wallet wallet = new WalletProtobufSerializer().readWallet(stream, walletExtensions);
|
||||||
|
@ -111,39 +111,6 @@ public class TransactionTest {
|
|||||||
tx.verify();
|
tx.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isConsistentReturnsFalseAsExpected() {
|
|
||||||
TransactionBag mockTB = createMock(TransactionBag.class);
|
|
||||||
|
|
||||||
TransactionOutput to = createMock(TransactionOutput.class);
|
|
||||||
EasyMock.expect(to.isAvailableForSpending()).andReturn(true);
|
|
||||||
EasyMock.expect(to.isMineOrWatched(mockTB)).andReturn(true);
|
|
||||||
EasyMock.expect(to.getSpentBy()).andReturn(new TransactionInput(PARAMS, null, new byte[0]));
|
|
||||||
|
|
||||||
Transaction tx = FakeTxBuilder.createFakeTxWithoutChange(PARAMS, to);
|
|
||||||
|
|
||||||
replay(to);
|
|
||||||
|
|
||||||
boolean isConsistent = tx.isConsistent(mockTB, false);
|
|
||||||
|
|
||||||
assertEquals(isConsistent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void isConsistentReturnsFalseAsExpected_WhenAvailableForSpendingEqualsFalse() {
|
|
||||||
TransactionOutput to = createMock(TransactionOutput.class);
|
|
||||||
EasyMock.expect(to.isAvailableForSpending()).andReturn(false);
|
|
||||||
EasyMock.expect(to.getSpentBy()).andReturn(null);
|
|
||||||
|
|
||||||
Transaction tx = FakeTxBuilder.createFakeTxWithoutChange(PARAMS, to);
|
|
||||||
|
|
||||||
replay(to);
|
|
||||||
|
|
||||||
boolean isConsistent = tx.isConsistent(createMock(TransactionBag.class), false);
|
|
||||||
|
|
||||||
assertEquals(isConsistent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEstimatedLockTime_WhenParameterSignifiesBlockHeight() {
|
public void testEstimatedLockTime_WhenParameterSignifiesBlockHeight() {
|
||||||
int TEST_LOCK_TIME = 20;
|
int TEST_LOCK_TIME = 20;
|
||||||
|
@ -39,6 +39,8 @@ import org.bitcoinj.utils.Fiat;
|
|||||||
import org.bitcoinj.utils.Threading;
|
import org.bitcoinj.utils.Threading;
|
||||||
import org.bitcoinj.wallet.*;
|
import org.bitcoinj.wallet.*;
|
||||||
import org.bitcoinj.wallet.WalletTransaction.Pool;
|
import org.bitcoinj.wallet.WalletTransaction.Pool;
|
||||||
|
import org.easymock.EasyMock;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
@ -65,6 +67,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
import static org.bitcoinj.core.Coin.*;
|
import static org.bitcoinj.core.Coin.*;
|
||||||
import static org.bitcoinj.core.Utils.HEX;
|
import static org.bitcoinj.core.Utils.HEX;
|
||||||
import static org.bitcoinj.testing.FakeTxBuilder.*;
|
import static org.bitcoinj.testing.FakeTxBuilder.*;
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
@ -685,6 +689,37 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertFalse(wallet.isConsistent());
|
assertFalse(wallet.isConsistent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isTxConsistentReturnsFalseAsExpected() {
|
||||||
|
Wallet wallet = new Wallet(params);
|
||||||
|
TransactionOutput to = createMock(TransactionOutput.class);
|
||||||
|
EasyMock.expect(to.isAvailableForSpending()).andReturn(true);
|
||||||
|
EasyMock.expect(to.isMineOrWatched(wallet)).andReturn(true);
|
||||||
|
EasyMock.expect(to.getSpentBy()).andReturn(new TransactionInput(params, null, new byte[0]));
|
||||||
|
|
||||||
|
Transaction tx = FakeTxBuilder.createFakeTxWithoutChange(params, to);
|
||||||
|
|
||||||
|
replay(to);
|
||||||
|
|
||||||
|
boolean isConsistent = wallet.isTxConsistent(tx, false);
|
||||||
|
assertFalse(isConsistent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isTxConsistentReturnsFalseAsExpected_WhenAvailableForSpendingEqualsFalse() {
|
||||||
|
Wallet wallet = new Wallet(params);
|
||||||
|
TransactionOutput to = createMock(TransactionOutput.class);
|
||||||
|
EasyMock.expect(to.isAvailableForSpending()).andReturn(false);
|
||||||
|
EasyMock.expect(to.getSpentBy()).andReturn(null);
|
||||||
|
|
||||||
|
Transaction tx = FakeTxBuilder.createFakeTxWithoutChange(params, to);
|
||||||
|
|
||||||
|
replay(to);
|
||||||
|
|
||||||
|
boolean isConsistent = wallet.isTxConsistent(tx, false);
|
||||||
|
assertFalse(isConsistent);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void transactions() throws Exception {
|
public void transactions() throws Exception {
|
||||||
// This test covers a bug in which Transaction.getValueSentFromMe was calculating incorrectly.
|
// This test covers a bug in which Transaction.getValueSentFromMe was calculating incorrectly.
|
||||||
|
Loading…
Reference in New Issue
Block a user