mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 10:15:52 +00:00
Eliminate the duplicated parentTransaction field from TransactionInput/Output.
This commit is contained in:
parent
20447bc340
commit
a30cdfed0c
@ -20,13 +20,11 @@ import javax.annotation.Nullable;
|
||||
/**
|
||||
* Represents a Message type that can be contained within another Message. ChildMessages that have a cached
|
||||
* backing byte array need to invalidate their parent's caches as well as their own if they are modified.
|
||||
*
|
||||
* @author git
|
||||
*/
|
||||
public abstract class ChildMessage extends Message {
|
||||
private static final long serialVersionUID = -7657113383624517931L;
|
||||
|
||||
@Nullable private Message parent;
|
||||
@Nullable protected Message parent;
|
||||
|
||||
protected ChildMessage() {
|
||||
}
|
||||
|
@ -58,13 +58,11 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
||||
@Nullable
|
||||
private final Coin value;
|
||||
// A pointer to the transaction that owns this input.
|
||||
private final Transaction parentTransaction;
|
||||
|
||||
/**
|
||||
* Creates an input that connects to nothing - used only in creation of coinbase transactions.
|
||||
*/
|
||||
public TransactionInput(NetworkParameters params, Transaction parentTransaction, byte[] scriptBytes) {
|
||||
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes) {
|
||||
this(params, parentTransaction, scriptBytes, new TransactionOutPoint(params, NO_SEQUENCE, (Transaction) null));
|
||||
}
|
||||
|
||||
@ -79,8 +77,8 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
this.scriptBytes = scriptBytes;
|
||||
this.outpoint = outpoint;
|
||||
this.sequence = NO_SEQUENCE;
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = value;
|
||||
setParent(parentTransaction);
|
||||
length = 40 + (scriptBytes == null ? 1 : VarInt.sizeOf(scriptBytes.length) + scriptBytes.length);
|
||||
}
|
||||
|
||||
@ -90,10 +88,10 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
TransactionInput(NetworkParameters params, Transaction parentTransaction, TransactionOutput output) {
|
||||
super(params);
|
||||
long outputIndex = output.getIndex();
|
||||
outpoint = new TransactionOutPoint(params, outputIndex, output.parentTransaction);
|
||||
outpoint = new TransactionOutPoint(params, outputIndex, output.getParentTransaction());
|
||||
scriptBytes = EMPTY_ARRAY;
|
||||
sequence = NO_SEQUENCE;
|
||||
this.parentTransaction = parentTransaction;
|
||||
setParent(parentTransaction);
|
||||
this.value = output.getValue();
|
||||
length = 41;
|
||||
}
|
||||
@ -104,7 +102,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
public TransactionInput(NetworkParameters params, Transaction parentTransaction,
|
||||
byte[] payload, int offset) throws ProtocolException {
|
||||
super(params, payload, offset);
|
||||
this.parentTransaction = parentTransaction;
|
||||
setParent(checkNotNull(parentTransaction));
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
@ -124,7 +122,6 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
boolean parseLazy, boolean parseRetain)
|
||||
throws ProtocolException {
|
||||
super(params, payload, offset, parentTransaction, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
||||
this.parentTransaction = parentTransaction;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
@ -261,7 +258,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
* @return The Transaction that owns this input.
|
||||
*/
|
||||
public Transaction getParentTransaction() {
|
||||
return parentTransaction;
|
||||
return (Transaction) parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -344,13 +341,13 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
checkElementIndex((int) outpoint.getIndex(), transaction.getOutputs().size(), "Corrupt transaction");
|
||||
TransactionOutput out = transaction.getOutput((int) outpoint.getIndex());
|
||||
if (!out.isAvailableForSpending()) {
|
||||
if (out.parentTransaction.equals(outpoint.fromTx)) {
|
||||
if (getParentTransaction().equals(outpoint.fromTx)) {
|
||||
// Already connected.
|
||||
return ConnectionResult.SUCCESS;
|
||||
} else if (mode == ConnectMode.DISCONNECT_ON_CONFLICT) {
|
||||
out.markAsUnspent();
|
||||
} else if (mode == ConnectMode.ABORT_ON_CONFLICT) {
|
||||
outpoint.fromTx = checkNotNull(out.parentTransaction);
|
||||
outpoint.fromTx = out.getParentTransaction();
|
||||
return TransactionInput.ConnectionResult.ALREADY_SPENT;
|
||||
}
|
||||
}
|
||||
@ -360,7 +357,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
|
||||
/** Internal use only: connects this TransactionInput to the given output (updates pointers and spent flags) */
|
||||
public void connect(TransactionOutput out) {
|
||||
outpoint.fromTx = checkNotNull(out.parentTransaction);
|
||||
outpoint.fromTx = out.getParentTransaction();
|
||||
out.markAsSpent(this);
|
||||
}
|
||||
|
||||
@ -421,15 +418,15 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
* @throws VerificationException If the outpoint doesn't match the given output.
|
||||
*/
|
||||
public void verify(TransactionOutput output) throws VerificationException {
|
||||
if (output.parentTransaction != null) {
|
||||
if (!getOutpoint().getHash().equals(output.parentTransaction.getHash()))
|
||||
if (output.parent != null) {
|
||||
if (!getOutpoint().getHash().equals(output.getParentTransaction().getHash()))
|
||||
throw new VerificationException("This input does not refer to the tx containing the output.");
|
||||
if (getOutpoint().getIndex() != output.getIndex())
|
||||
throw new VerificationException("This input refers to a different output on the given tx.");
|
||||
}
|
||||
Script pubKey = output.getScriptPubKey();
|
||||
int myIndex = parentTransaction.getInputs().indexOf(this);
|
||||
getScriptSig().correctlySpends(parentTransaction, myIndex, pubKey, true);
|
||||
int myIndex = getParentTransaction().getInputs().indexOf(this);
|
||||
getScriptSig().correctlySpends(getParentTransaction(), myIndex, pubKey, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -458,7 +455,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
if (!outpoint.equals(input.outpoint)) return false;
|
||||
if (!Arrays.equals(scriptBytes, input.scriptBytes)) return false;
|
||||
if (scriptSig != null ? !scriptSig.equals(input.scriptSig) : input.scriptSig != null) return false;
|
||||
if (parentTransaction != input.parentTransaction) return false;
|
||||
if (parent != input.parent) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -59,8 +59,6 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
private boolean availableForSpending;
|
||||
@Nullable private TransactionInput spentBy;
|
||||
|
||||
// A reference to the transaction which holds this output, if any.
|
||||
@Nullable Transaction parentTransaction;
|
||||
private transient int scriptLen;
|
||||
|
||||
/**
|
||||
@ -69,7 +67,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload,
|
||||
int offset) throws ProtocolException {
|
||||
super(params, payload, offset);
|
||||
parentTransaction = parent;
|
||||
setParent(parent);
|
||||
availableForSpending = true;
|
||||
}
|
||||
|
||||
@ -88,7 +86,6 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload, int offset,
|
||||
boolean parseLazy, boolean parseRetain) throws ProtocolException {
|
||||
super(params, payload, offset, parent, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
||||
parentTransaction = parent;
|
||||
availableForSpending = true;
|
||||
}
|
||||
|
||||
@ -118,7 +115,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
checkArgument(value.compareTo(NetworkParameters.MAX_MONEY) < 0, "Values larger than MAX_MONEY not allowed");
|
||||
this.value = value.value;
|
||||
this.scriptBytes = scriptBytes;
|
||||
parentTransaction = parent;
|
||||
setParent(parent);
|
||||
availableForSpending = true;
|
||||
length = 8 + VarInt.sizeOf(scriptBytes.length) + scriptBytes.length;
|
||||
}
|
||||
@ -218,14 +215,16 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
this.value = value.value;
|
||||
}
|
||||
|
||||
int getIndex() {
|
||||
checkNotNull(parentTransaction, "This output is not attached to a parent transaction.");
|
||||
for (int i = 0; i < parentTransaction.getOutputs().size(); i++) {
|
||||
if (parentTransaction.getOutputs().get(i) == this)
|
||||
/**
|
||||
* Gets the index of this output in the parent transaction, or throws if this output is free standing. Iterates
|
||||
* over the parents list to discover this.
|
||||
*/
|
||||
public int getIndex() {
|
||||
for (int i = 0; i < getParentTransaction().getOutputs().size(); i++) {
|
||||
if (getParentTransaction().getOutputs().get(i) == this)
|
||||
return i;
|
||||
}
|
||||
// Should never happen.
|
||||
throw new RuntimeException("Output linked to wrong parent transaction?");
|
||||
throw new IllegalStateException("Output linked to wrong parent transaction?");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -270,8 +269,8 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
checkState(availableForSpending);
|
||||
availableForSpending = false;
|
||||
spentBy = input;
|
||||
if (parentTransaction != null)
|
||||
log.info("Marked {}:{} as spent by {}", parentTransaction.getHash(), getIndex(), input);
|
||||
if (parent != null)
|
||||
log.info("Marked {}:{} as spent by {}", getParentTransaction().getHash(), getIndex(), input);
|
||||
else
|
||||
log.info("Marked floating output as spent by {}", input);
|
||||
}
|
||||
@ -280,8 +279,8 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
* Resets the spent pointer / availableForSpending flag to null.
|
||||
*/
|
||||
public void markAsUnspent() {
|
||||
if (parentTransaction != null)
|
||||
log.info("Un-marked {}:{} as spent by {}", parentTransaction.getHash(), getIndex(), spentBy);
|
||||
if (parent != null)
|
||||
log.info("Un-marked {}:{} as spent by {}", getParentTransaction().getHash(), getIndex(), spentBy);
|
||||
else
|
||||
log.info("Un-marked floating output as spent by {}", spentBy);
|
||||
availableForSpending = true;
|
||||
@ -388,7 +387,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
* Returns the transaction that owns this output, or throws NullPointerException if unowned.
|
||||
*/
|
||||
public Transaction getParentTransaction() {
|
||||
return checkNotNull(parentTransaction, "Free-standing TransactionOutput");
|
||||
return checkNotNull((Transaction) parent, "Free-standing TransactionOutput");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -423,14 +422,13 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
|
||||
if (!Arrays.equals(scriptBytes, other.scriptBytes)) return false;
|
||||
if (value != other.value) return false;
|
||||
if (parentTransaction != null && parentTransaction != other.parentTransaction) return false;
|
||||
if (parent != null && parent != other.parent) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 31 * (int) value + (scriptBytes != null ? Arrays.hashCode(scriptBytes) : 0);
|
||||
return result;
|
||||
return 31 * (int) value + (scriptBytes != null ? Arrays.hashCode(scriptBytes) : 0);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user