TransactionInput, TransactionOutput: make direct subclass of Message

Since only these 2 classes need to support the concept of a "parent", it
will be simpler to just add the code to handle that to both of them and
remove the `ChildMessage` altogether.
This commit is contained in:
Sean Gilligan 2023-03-29 16:59:04 -07:00 committed by Andreas Schildbach
parent 368d2f2c63
commit 3bc82cd9f7
3 changed files with 52 additions and 80 deletions

View file

@ -1,74 +0,0 @@
/*
* Copyright 2011 Steve Coughlan.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bitcoinj.core;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;
/**
* <p>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.</p>
*
* <p>Instances of this class are not safe for use by multiple threads.</p>
*/
public abstract class ChildMessage extends Message {
@Nullable protected Message parent;
public ChildMessage(NetworkParameters params) {
super(params);
}
public ChildMessage(NetworkParameters params, MessageSerializer serializer) {
super(params, serializer);
}
public ChildMessage(NetworkParameters params, ByteBuffer payload) throws ProtocolException {
super(params, payload);
}
public ChildMessage(NetworkParameters params, ByteBuffer payload, @Nullable Message parent) throws ProtocolException {
super(params, payload);
this.parent = parent;
}
public ChildMessage(NetworkParameters params, ByteBuffer payload, @Nullable Message parent,
MessageSerializer serializer) throws ProtocolException {
super(params, payload, serializer);
this.parent = parent;
}
public final void setParent(@Nullable Message parent) {
if (this.parent != null && this.parent != parent && parent != null) {
// After old parent is unlinked it won't be able to receive notice if this ChildMessage
// changes internally. To be safe we invalidate the parent cache to ensure it rebuilds
// manually on serialization.
this.parent.unCache();
}
this.parent = parent;
}
/* (non-Javadoc)
* @see Message#unCache()
*/
@Override
protected void unCache() {
super.unCache();
if (parent != null)
parent.unCache();
}
}

View file

@ -49,7 +49,7 @@ import static org.bitcoinj.base.internal.Preconditions.checkArgument;
* *
* <p>Instances of this class are not safe for use by multiple threads.</p> * <p>Instances of this class are not safe for use by multiple threads.</p>
*/ */
public class TransactionInput extends ChildMessage { public class TransactionInput extends Message {
/** Magic sequence number that indicates there is no sequence number. */ /** Magic sequence number that indicates there is no sequence number. */
public static final long NO_SEQUENCE = 0xFFFFFFFFL; public static final long NO_SEQUENCE = 0xFFFFFFFFL;
/** /**
@ -71,6 +71,8 @@ public class TransactionInput extends ChildMessage {
// Magic outpoint index that indicates the input is in fact unconnected. // Magic outpoint index that indicates the input is in fact unconnected.
private static final long UNCONNECTED = 0xFFFFFFFFL; private static final long UNCONNECTED = 0xFFFFFFFFL;
@Nullable protected Transaction parent;
// Allows for altering transactions after they were broadcast. Values below NO_SEQUENCE-1 mean it can be altered. // Allows for altering transactions after they were broadcast. Values below NO_SEQUENCE-1 mean it can be altered.
private long sequence; private long sequence;
// Data needed to connect to the output of the transaction we're gathering coins from. // Data needed to connect to the output of the transaction we're gathering coins from.
@ -145,7 +147,8 @@ public class TransactionInput extends ChildMessage {
*/ */
public TransactionInput(NetworkParameters params, Transaction parentTransaction, ByteBuffer payload, MessageSerializer serializer) public TransactionInput(NetworkParameters params, Transaction parentTransaction, ByteBuffer payload, MessageSerializer serializer)
throws ProtocolException { throws ProtocolException {
super(params, payload, parentTransaction, serializer); super(params, payload, serializer);
setParent(parentTransaction);
this.value = null; this.value = null;
} }
@ -273,7 +276,7 @@ public class TransactionInput extends ChildMessage {
* @return The Transaction that owns this input. * @return The Transaction that owns this input.
*/ */
public Transaction getParentTransaction() { public Transaction getParentTransaction() {
return (Transaction) parent; return parent;
} }
/** /**
@ -522,6 +525,26 @@ public class TransactionInput extends ChildMessage {
return DefaultRiskAnalysis.isInputStandard(this); return DefaultRiskAnalysis.isInputStandard(this);
} }
public final void setParent(@Nullable Transaction parent) {
if (this.parent != null && this.parent != parent && parent != null) {
// After old parent is unlinked it won't be able to receive notice if this child
// changes internally. To be safe we invalidate the parent cache to ensure it rebuilds
// manually on serialization.
this.parent.unCache();
}
this.parent = parent;
}
/* (non-Javadoc)
* @see Message#unCache()
*/
@Override
protected void unCache() {
super.unCache();
if (parent != null)
parent.unCache();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;

View file

@ -52,9 +52,11 @@ import static org.bitcoinj.base.internal.Preconditions.checkState;
* *
* <p>Instances of this class are not safe for use by multiple threads.</p> * <p>Instances of this class are not safe for use by multiple threads.</p>
*/ */
public class TransactionOutput extends ChildMessage { public class TransactionOutput extends Message {
private static final Logger log = LoggerFactory.getLogger(TransactionOutput.class); private static final Logger log = LoggerFactory.getLogger(TransactionOutput.class);
@Nullable protected Transaction parent;
// The output's value is kept as a native type in order to save class instances. // The output's value is kept as a native type in order to save class instances.
private long value; private long value;
@ -90,7 +92,8 @@ public class TransactionOutput extends ChildMessage {
* @throws ProtocolException * @throws ProtocolException
*/ */
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, ByteBuffer payload, MessageSerializer serializer) throws ProtocolException { public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, ByteBuffer payload, MessageSerializer serializer) throws ProtocolException {
super(params, payload, parent, serializer); super(params, payload, serializer);
setParent(parent);
availableForSpending = true; availableForSpending = true;
} }
@ -376,7 +379,7 @@ public class TransactionOutput extends ChildMessage {
*/ */
@Nullable @Nullable
public Transaction getParentTransaction() { public Transaction getParentTransaction() {
return (Transaction)parent; return parent;
} }
/** /**
@ -417,6 +420,26 @@ public class TransactionOutput extends ChildMessage {
return new TransactionOutput(params, null, Coin.valueOf(value), Arrays.copyOf(scriptBytes, scriptBytes.length)); return new TransactionOutput(params, null, Coin.valueOf(value), Arrays.copyOf(scriptBytes, scriptBytes.length));
} }
public final void setParent(@Nullable Transaction parent) {
if (this.parent != null && this.parent != parent && parent != null) {
// After old parent is unlinked it won't be able to receive notice if this child
// changes internally. To be safe we invalidate the parent cache to ensure it rebuilds
// manually on serialization.
this.parent.unCache();
}
this.parent = parent;
}
/* (non-Javadoc)
* @see Message#unCache()
*/
@Override
protected void unCache() {
super.unCache();
if (parent != null)
parent.unCache();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;