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
|
* 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.
|
* 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 {
|
public abstract class ChildMessage extends Message {
|
||||||
private static final long serialVersionUID = -7657113383624517931L;
|
private static final long serialVersionUID = -7657113383624517931L;
|
||||||
|
|
||||||
@Nullable private Message parent;
|
@Nullable protected Message parent;
|
||||||
|
|
||||||
protected ChildMessage() {
|
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(). */
|
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Coin value;
|
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.
|
* 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));
|
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.scriptBytes = scriptBytes;
|
||||||
this.outpoint = outpoint;
|
this.outpoint = outpoint;
|
||||||
this.sequence = NO_SEQUENCE;
|
this.sequence = NO_SEQUENCE;
|
||||||
this.parentTransaction = parentTransaction;
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
setParent(parentTransaction);
|
||||||
length = 40 + (scriptBytes == null ? 1 : VarInt.sizeOf(scriptBytes.length) + scriptBytes.length);
|
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) {
|
TransactionInput(NetworkParameters params, Transaction parentTransaction, TransactionOutput output) {
|
||||||
super(params);
|
super(params);
|
||||||
long outputIndex = output.getIndex();
|
long outputIndex = output.getIndex();
|
||||||
outpoint = new TransactionOutPoint(params, outputIndex, output.parentTransaction);
|
outpoint = new TransactionOutPoint(params, outputIndex, output.getParentTransaction());
|
||||||
scriptBytes = EMPTY_ARRAY;
|
scriptBytes = EMPTY_ARRAY;
|
||||||
sequence = NO_SEQUENCE;
|
sequence = NO_SEQUENCE;
|
||||||
this.parentTransaction = parentTransaction;
|
setParent(parentTransaction);
|
||||||
this.value = output.getValue();
|
this.value = output.getValue();
|
||||||
length = 41;
|
length = 41;
|
||||||
}
|
}
|
||||||
@ -104,7 +102,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
public TransactionInput(NetworkParameters params, Transaction parentTransaction,
|
public TransactionInput(NetworkParameters params, Transaction parentTransaction,
|
||||||
byte[] payload, int offset) throws ProtocolException {
|
byte[] payload, int offset) throws ProtocolException {
|
||||||
super(params, payload, offset);
|
super(params, payload, offset);
|
||||||
this.parentTransaction = parentTransaction;
|
setParent(checkNotNull(parentTransaction));
|
||||||
this.value = null;
|
this.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +122,6 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
boolean parseLazy, boolean parseRetain)
|
boolean parseLazy, boolean parseRetain)
|
||||||
throws ProtocolException {
|
throws ProtocolException {
|
||||||
super(params, payload, offset, parentTransaction, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
super(params, payload, offset, parentTransaction, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
||||||
this.parentTransaction = parentTransaction;
|
|
||||||
this.value = null;
|
this.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +258,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
* @return The Transaction that owns this input.
|
* @return The Transaction that owns this input.
|
||||||
*/
|
*/
|
||||||
public Transaction getParentTransaction() {
|
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");
|
checkElementIndex((int) outpoint.getIndex(), transaction.getOutputs().size(), "Corrupt transaction");
|
||||||
TransactionOutput out = transaction.getOutput((int) outpoint.getIndex());
|
TransactionOutput out = transaction.getOutput((int) outpoint.getIndex());
|
||||||
if (!out.isAvailableForSpending()) {
|
if (!out.isAvailableForSpending()) {
|
||||||
if (out.parentTransaction.equals(outpoint.fromTx)) {
|
if (getParentTransaction().equals(outpoint.fromTx)) {
|
||||||
// Already connected.
|
// Already connected.
|
||||||
return ConnectionResult.SUCCESS;
|
return ConnectionResult.SUCCESS;
|
||||||
} else if (mode == ConnectMode.DISCONNECT_ON_CONFLICT) {
|
} else if (mode == ConnectMode.DISCONNECT_ON_CONFLICT) {
|
||||||
out.markAsUnspent();
|
out.markAsUnspent();
|
||||||
} else if (mode == ConnectMode.ABORT_ON_CONFLICT) {
|
} else if (mode == ConnectMode.ABORT_ON_CONFLICT) {
|
||||||
outpoint.fromTx = checkNotNull(out.parentTransaction);
|
outpoint.fromTx = out.getParentTransaction();
|
||||||
return TransactionInput.ConnectionResult.ALREADY_SPENT;
|
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) */
|
/** Internal use only: connects this TransactionInput to the given output (updates pointers and spent flags) */
|
||||||
public void connect(TransactionOutput out) {
|
public void connect(TransactionOutput out) {
|
||||||
outpoint.fromTx = checkNotNull(out.parentTransaction);
|
outpoint.fromTx = out.getParentTransaction();
|
||||||
out.markAsSpent(this);
|
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.
|
* @throws VerificationException If the outpoint doesn't match the given output.
|
||||||
*/
|
*/
|
||||||
public void verify(TransactionOutput output) throws VerificationException {
|
public void verify(TransactionOutput output) throws VerificationException {
|
||||||
if (output.parentTransaction != null) {
|
if (output.parent != null) {
|
||||||
if (!getOutpoint().getHash().equals(output.parentTransaction.getHash()))
|
if (!getOutpoint().getHash().equals(output.getParentTransaction().getHash()))
|
||||||
throw new VerificationException("This input does not refer to the tx containing the output.");
|
throw new VerificationException("This input does not refer to the tx containing the output.");
|
||||||
if (getOutpoint().getIndex() != output.getIndex())
|
if (getOutpoint().getIndex() != output.getIndex())
|
||||||
throw new VerificationException("This input refers to a different output on the given tx.");
|
throw new VerificationException("This input refers to a different output on the given tx.");
|
||||||
}
|
}
|
||||||
Script pubKey = output.getScriptPubKey();
|
Script pubKey = output.getScriptPubKey();
|
||||||
int myIndex = parentTransaction.getInputs().indexOf(this);
|
int myIndex = getParentTransaction().getInputs().indexOf(this);
|
||||||
getScriptSig().correctlySpends(parentTransaction, myIndex, pubKey, true);
|
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 (!outpoint.equals(input.outpoint)) return false;
|
||||||
if (!Arrays.equals(scriptBytes, input.scriptBytes)) return false;
|
if (!Arrays.equals(scriptBytes, input.scriptBytes)) return false;
|
||||||
if (scriptSig != null ? !scriptSig.equals(input.scriptSig) : input.scriptSig != null) 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,6 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
private boolean availableForSpending;
|
private boolean availableForSpending;
|
||||||
@Nullable private TransactionInput spentBy;
|
@Nullable private TransactionInput spentBy;
|
||||||
|
|
||||||
// A reference to the transaction which holds this output, if any.
|
|
||||||
@Nullable Transaction parentTransaction;
|
|
||||||
private transient int scriptLen;
|
private transient int scriptLen;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +67,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload,
|
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload,
|
||||||
int offset) throws ProtocolException {
|
int offset) throws ProtocolException {
|
||||||
super(params, payload, offset);
|
super(params, payload, offset);
|
||||||
parentTransaction = parent;
|
setParent(parent);
|
||||||
availableForSpending = true;
|
availableForSpending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +86,6 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload, int offset,
|
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, byte[] payload, int offset,
|
||||||
boolean parseLazy, boolean parseRetain) throws ProtocolException {
|
boolean parseLazy, boolean parseRetain) throws ProtocolException {
|
||||||
super(params, payload, offset, parent, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
super(params, payload, offset, parent, parseLazy, parseRetain, UNKNOWN_LENGTH);
|
||||||
parentTransaction = parent;
|
|
||||||
availableForSpending = true;
|
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");
|
checkArgument(value.compareTo(NetworkParameters.MAX_MONEY) < 0, "Values larger than MAX_MONEY not allowed");
|
||||||
this.value = value.value;
|
this.value = value.value;
|
||||||
this.scriptBytes = scriptBytes;
|
this.scriptBytes = scriptBytes;
|
||||||
parentTransaction = parent;
|
setParent(parent);
|
||||||
availableForSpending = true;
|
availableForSpending = true;
|
||||||
length = 8 + VarInt.sizeOf(scriptBytes.length) + scriptBytes.length;
|
length = 8 + VarInt.sizeOf(scriptBytes.length) + scriptBytes.length;
|
||||||
}
|
}
|
||||||
@ -218,14 +215,16 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
this.value = value.value;
|
this.value = value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getIndex() {
|
/**
|
||||||
checkNotNull(parentTransaction, "This output is not attached to a parent transaction.");
|
* Gets the index of this output in the parent transaction, or throws if this output is free standing. Iterates
|
||||||
for (int i = 0; i < parentTransaction.getOutputs().size(); i++) {
|
* over the parents list to discover this.
|
||||||
if (parentTransaction.getOutputs().get(i) == this)
|
*/
|
||||||
|
public int getIndex() {
|
||||||
|
for (int i = 0; i < getParentTransaction().getOutputs().size(); i++) {
|
||||||
|
if (getParentTransaction().getOutputs().get(i) == this)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
// Should never happen.
|
throw new IllegalStateException("Output linked to wrong parent transaction?");
|
||||||
throw new RuntimeException("Output linked to wrong parent transaction?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -270,8 +269,8 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
checkState(availableForSpending);
|
checkState(availableForSpending);
|
||||||
availableForSpending = false;
|
availableForSpending = false;
|
||||||
spentBy = input;
|
spentBy = input;
|
||||||
if (parentTransaction != null)
|
if (parent != null)
|
||||||
log.info("Marked {}:{} as spent by {}", parentTransaction.getHash(), getIndex(), input);
|
log.info("Marked {}:{} as spent by {}", getParentTransaction().getHash(), getIndex(), input);
|
||||||
else
|
else
|
||||||
log.info("Marked floating output as spent by {}", input);
|
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.
|
* Resets the spent pointer / availableForSpending flag to null.
|
||||||
*/
|
*/
|
||||||
public void markAsUnspent() {
|
public void markAsUnspent() {
|
||||||
if (parentTransaction != null)
|
if (parent != null)
|
||||||
log.info("Un-marked {}:{} as spent by {}", parentTransaction.getHash(), getIndex(), spentBy);
|
log.info("Un-marked {}:{} as spent by {}", getParentTransaction().getHash(), getIndex(), spentBy);
|
||||||
else
|
else
|
||||||
log.info("Un-marked floating output as spent by {}", spentBy);
|
log.info("Un-marked floating output as spent by {}", spentBy);
|
||||||
availableForSpending = true;
|
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.
|
* Returns the transaction that owns this output, or throws NullPointerException if unowned.
|
||||||
*/
|
*/
|
||||||
public Transaction getParentTransaction() {
|
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 (!Arrays.equals(scriptBytes, other.scriptBytes)) return false;
|
||||||
if (value != other.value) 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int result = 31 * (int) value + (scriptBytes != null ? Arrays.hashCode(scriptBytes) : 0);
|
return 31 * (int) value + (scriptBytes != null ? Arrays.hashCode(scriptBytes) : 0);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user