3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 11:15:51 +00:00

Transaction: Add getTxId() and getWTxId(); deprecate getHash() and getHashAsString().

This commit is contained in:
Andreas Schildbach 2019-02-05 16:44:39 +01:00
parent 2d943838dd
commit 53a63c43bb
23 changed files with 145 additions and 113 deletions

View File

@ -306,12 +306,9 @@ public class BitcoinSerializer extends MessageSerializer {
* serialization format support.
*/
@Override
public Transaction makeTransaction(byte[] payloadBytes, int offset,
int length, byte[] hash) throws ProtocolException {
Transaction tx = new Transaction(params, payloadBytes, offset, null, this, length);
if (hash != null)
tx.setHash(Sha256Hash.wrapReversed(hash));
return tx;
public Transaction makeTransaction(byte[] payloadBytes, int offset, int length, byte[] hashFromHeader)
throws ProtocolException {
return new Transaction(params, payloadBytes, offset, null, this, length, hashFromHeader);
}
@Override

View File

@ -239,7 +239,7 @@ public class Block extends Message {
optimalEncodingMessageSize += VarInt.sizeOf(numTransactions);
transactions = new ArrayList<>(Math.min(numTransactions, Utils.MAX_INITIAL_ARRAY_LENGTH));
for (int i = 0; i < numTransactions; i++) {
Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH);
Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH, null);
// Label the transaction as coming from the P2P network, so code that cares where we first saw it knows.
tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK);
transactions.add(tx);

View File

@ -780,7 +780,7 @@ public class Peer extends PeerSocketHandler {
tx.verify();
lock.lock();
try {
log.debug("{}: Received tx {}", getAddress(), tx.getHashAsString());
log.debug("{}: Received tx {}", getAddress(), tx.getTxId());
// Label the transaction as coming in from the P2P network (as opposed to being created by us, direct import,
// etc). This helps the wallet decide how to risk analyze it later.
//
@ -839,7 +839,7 @@ public class Peer extends PeerSocketHandler {
@Override
public void onFailure(Throwable throwable) {
log.error("Could not download dependencies of tx {}", tx.getHashAsString());
log.error("Could not download dependencies of tx {}", tx.getTxId());
log.error("Error was: ", throwable);
// Not much more we can do at this point.
}
@ -887,7 +887,7 @@ public class Peer extends PeerSocketHandler {
public ListenableFuture<List<Transaction>> downloadDependencies(Transaction tx) {
TransactionConfidence.ConfidenceType txConfidence = tx.getConfidence().getConfidenceType();
Preconditions.checkArgument(txConfidence != TransactionConfidence.ConfidenceType.BUILDING);
log.info("{}: Downloading dependencies of {}", getAddress(), tx.getHashAsString());
log.info("{}: Downloading dependencies of {}", getAddress(), tx.getTxId());
final LinkedList<Transaction> results = new LinkedList<>();
// future will be invoked when the entire dependency tree has been walked and the results compiled.
final ListenableFuture<Object> future = downloadDependenciesInternal(vDownloadTxDependencyDepth, 0, tx,
@ -945,7 +945,7 @@ public class Peer extends PeerSocketHandler {
List<ListenableFuture<Object>> childFutures = Lists.newLinkedList();
for (Transaction tx : transactions) {
if (tx == null) continue;
log.info("{}: Downloaded dependency of {}: {}", getAddress(), rootTxHash, tx.getHashAsString());
log.info("{}: Downloaded dependency of {}: {}", getAddress(), rootTxHash, tx.getTxId());
results.add(tx);
// Now recurse into the dependencies of this transaction too.
if (depth + 1 < maxDepth)

View File

@ -2062,7 +2062,7 @@ public class PeerGroup implements TransactionBroadcaster {
// If we don't have a record of where this tx came from already, set it to be ourselves so Peer doesn't end up
// redownloading it from the network redundantly.
if (tx.getConfidence().getSource().equals(TransactionConfidence.Source.UNKNOWN)) {
log.info("Transaction source unknown, setting to SELF: {}", tx.getHashAsString());
log.info("Transaction source unknown, setting to SELF: {}", tx.getTxId());
tx.getConfidence().setSource(TransactionConfidence.Source.SELF);
}
final TransactionBroadcast broadcast = new TransactionBroadcast(this, tx);

View File

@ -135,9 +135,9 @@ public class Transaction extends ChildMessage {
// list of transactions from a wallet, which is helpful for presenting to users.
private Date updatedAt;
// This is an in memory helper only. It contains the transaction hash (aka txid), used as a reference by transaction
// inputs via outpoints.
private Sha256Hash hash;
// These are in memory helpers only. They contain the transaction hashes without and with witness.
private Sha256Hash cachedTxId;
private Sha256Hash cachedWTxId;
// Data about how confirmed this tx is. Serialized, may be null.
@Nullable private TransactionConfidence confidence;
@ -230,11 +230,19 @@ public class Transaction extends ChildMessage {
* @param setSerializer The serializer to use for this transaction.
* @param length The length of message if known. Usually this is provided when deserializing of the wire
* as the length will be provided as part of the header. If unknown then set to Message.UNKNOWN_LENGTH
* @param hashFromHeader Used by BitcoinSerializer. The serializer has to calculate a hash for checksumming so to
* avoid wasting the considerable effort a set method is provided so the serializer can set it. No verification
* is performed on this hash.
* @throws ProtocolException
*/
public Transaction(NetworkParameters params, byte[] payload, int offset, @Nullable Message parent, MessageSerializer setSerializer, int length)
throws ProtocolException {
public Transaction(NetworkParameters params, byte[] payload, int offset, @Nullable Message parent,
MessageSerializer setSerializer, int length, @Nullable byte[] hashFromHeader) throws ProtocolException {
super(params, payload, offset, parent, setSerializer, length);
if (hashFromHeader != null) {
cachedWTxId = Sha256Hash.wrapReversed(hashFromHeader);
if (!hasWitnesses())
cachedTxId = cachedWTxId;
}
}
/**
@ -245,39 +253,59 @@ public class Transaction extends ChildMessage {
super(params, payload, 0, parent, setSerializer, length);
}
/**
* Returns the transaction hash (aka txid) as you see them in block explorers. It is used as a reference by
* transaction inputs via outpoints.
*/
/** @deprecated use {@link #getTxId()} */
@Override
@Deprecated
public Sha256Hash getHash() {
if (hash == null) {
ByteArrayOutputStream stream = new UnsafeByteArrayOutputStream(length < 32 ? 32 : length + 32);
try {
bitcoinSerializeToStream(stream, false);
} catch (IOException e) {
// Cannot happen, we are serializing to a memory stream.
}
hash = Sha256Hash.wrapReversed(Sha256Hash.hashTwice(stream.toByteArray()));
}
return hash;
return getTxId();
}
/**
* Used by BitcoinSerializer. The serializer has to calculate a hash for checksumming so to
* avoid wasting the considerable effort a set method is provided so the serializer can set it.
*
* No verification is performed on this hash.
*/
void setHash(Sha256Hash hash) {
this.hash = hash;
}
/**
* Returns the transaction hash (aka txid) as you see them in block explorers, as a hex string.
*/
/** @deprecated use {@link #getTxId()}.toString() */
@Deprecated
public String getHashAsString() {
return getHash().toString();
return getTxId().toString();
}
/**
* Returns the transaction id as you see them in block explorers. It is used as a reference by transaction inputs
* via outpoints.
*/
public Sha256Hash getTxId() {
if (cachedTxId == null) {
if (!hasWitnesses() && cachedWTxId != null) {
cachedTxId = cachedWTxId;
} else {
ByteArrayOutputStream stream = new UnsafeByteArrayOutputStream(length < 32 ? 32 : length + 32);
try {
bitcoinSerializeToStream(stream, false);
} catch (IOException e) {
throw new RuntimeException(e); // cannot happen
}
cachedTxId = Sha256Hash.wrapReversed(Sha256Hash.hashTwice(stream.toByteArray()));
}
}
return cachedTxId;
}
/**
* Returns the witness transaction id (aka witness id) as per BIP144. For transactions without witness, this is the
* same as {@link #getTxId()}.
*/
public Sha256Hash getWTxId() {
if (cachedWTxId == null) {
if (!hasWitnesses() && cachedTxId != null) {
cachedWTxId = cachedTxId;
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
bitcoinSerializeToStream(baos, hasWitnesses());
} catch (IOException e) {
throw new RuntimeException(e); // cannot happen
}
cachedWTxId = Sha256Hash.wrapReversed(Sha256Hash.hashTwice(baos.toByteArray()));
}
}
return cachedWTxId;
}
/**
@ -525,7 +553,8 @@ public class Transaction extends ChildMessage {
@Override
protected void unCache() {
super.unCache();
hash = null;
cachedTxId = null;
cachedWTxId = null;
}
protected static int calcLength(byte[] buf, int offset) {
@ -710,7 +739,11 @@ public class Transaction extends ChildMessage {
if (indent == null)
indent = "";
StringBuilder s = new StringBuilder();
s.append(indent).append(getHashAsString()).append('\n');
Sha256Hash txId = getTxId(), wTxId = getWTxId();
s.append(indent).append(txId);
if (!wTxId.equals(txId))
s.append(", wtxid ").append(wTxId);
s.append('\n');
if (updatedAt != null)
s.append(indent).append("updated: ").append(Utils.dateTimeFormat(updatedAt)).append('\n');
if (version != 1)
@ -810,7 +843,7 @@ public class Transaction extends ChildMessage {
final TransactionInput spentBy = out.getSpentBy();
if (spentBy != null) {
s.append(" by:");
s.append(spentBy.getParentTransaction().getHashAsString()).append(':')
s.append(spentBy.getParentTransaction().getTxId()).append(':')
.append(spentBy.getIndex());
}
}

View File

@ -152,7 +152,7 @@ public class TransactionBroadcast {
numWaitingFor = (int) Math.ceil((peers.size() - numToBroadcastTo) / 2.0);
Collections.shuffle(peers, random);
peers = peers.subList(0, numToBroadcastTo);
log.info("broadcastTransaction: We have {} peers, adding {} to the memory pool", numConnected, tx.getHashAsString());
log.info("broadcastTransaction: We have {} peers, adding {} to the memory pool", numConnected, tx.getTxId());
log.info("Sending to {} peers, will wait for {}, sending to: {}", numToBroadcastTo, numWaitingFor, Joiner.on(",").join(peers));
for (Peer peer : peers) {
try {
@ -183,7 +183,7 @@ public class TransactionBroadcast {
// The number of peers that announced this tx has gone up.
int numSeenPeers = conf.numBroadcastPeers() + rejects.size();
boolean mined = tx.getAppearsInHashes() != null;
log.info("broadcastTransaction: {}: TX {} seen by {} peers{}", reason, tx.getHashAsString(),
log.info("broadcastTransaction: {}: TX {} seen by {} peers{}", reason, tx.getTxId(),
numSeenPeers, mined ? " and mined" : "");
// Progress callback on the requested thread.

View File

@ -194,7 +194,7 @@ public abstract class PaymentChannelServerState {
final SettableFuture<PaymentChannelServerState> future = SettableFuture.create();
Futures.addCallback(broadcaster.broadcastTransaction(contract).future(), new FutureCallback<Transaction>() {
@Override public void onSuccess(Transaction transaction) {
log.info("Successfully broadcast multisig contract {}. Channel now open.", transaction.getHashAsString());
log.info("Successfully broadcast multisig contract {}. Channel now open.", transaction.getTxId());
try {
// Manually add the contract to the wallet, overriding the isRelevant checks so we can track
// it and check for double-spends later

View File

@ -170,8 +170,8 @@ public class PaymentChannelV1ClientState extends PaymentChannelClientState {
refundFees = multisigFee;
}
refundTx.getConfidence().setSource(TransactionConfidence.Source.SELF);
log.info("initiated channel with multi-sig contract {}, refund {}", multisigContract.getHashAsString(),
refundTx.getHashAsString());
log.info("initiated channel with multi-sig contract {}, refund {}", multisigContract.getTxId(),
refundTx.getTxId());
stateMachine.transition(State.INITIATED);
// Client should now call getIncompleteRefundTransaction() and send it to the server.
}

View File

@ -147,7 +147,7 @@ public class PaymentChannelV2ClientState extends PaymentChannelClientState {
refundTx.getInput(0).setScriptSig(ScriptBuilder.createCLTVPaymentChannelP2SHRefund(refundSignature, redeemScript));
refundTx.getConfidence().setSource(TransactionConfidence.Source.SELF);
log.info("initiated channel with contract {}", contract.getHashAsString());
log.info("initiated channel with contract {}", contract.getTxId());
stateMachine.transition(State.SAVE_STATE_IN_WALLET);
// Client should now call getIncompleteRefundTransaction() and send it to the server.
}

View File

@ -244,11 +244,11 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
@Override
public String toString() {
if (!analyzed)
return "Pending risk analysis for " + tx.getHashAsString();
return "Pending risk analysis for " + tx.getTxId();
else if (nonFinal != null)
return "Risky due to non-finality of " + nonFinal.getHashAsString();
return "Risky due to non-finality of " + nonFinal.getTxId();
else if (nonStandard != null)
return "Risky due to non-standard tx " + nonStandard.getHashAsString();
return "Risky due to non-standard tx " + nonStandard.getTxId();
else
return "Non-risky";
}

View File

@ -1601,13 +1601,13 @@ public class Wallet extends BaseTaggableObject
for (Transaction tx : unspent.values()) {
if (!isTxConsistent(tx, false)) {
throw new IllegalStateException("Inconsistent unspent tx: " + tx.getHashAsString());
throw new IllegalStateException("Inconsistent unspent tx: " + tx.getTxId());
}
}
for (Transaction tx : spent.values()) {
if (!isTxConsistent(tx, true)) {
throw new IllegalStateException("Inconsistent spent tx: " + tx.getHashAsString());
throw new IllegalStateException("Inconsistent spent tx: " + tx.getTxId());
}
}
} finally {
@ -1720,7 +1720,7 @@ public class Wallet extends BaseTaggableObject
// between pools.
EnumSet<Pool> containingPools = getContainingPools(tx);
if (!containingPools.equals(EnumSet.noneOf(Pool.class))) {
log.debug("Received tx we already saw in a block or created ourselves: " + tx.getHashAsString());
log.debug("Received tx we already saw in a block or created ourselves: " + tx.getTxId());
return;
}
// Repeat the check of relevancy here, even though the caller may have already done so - this is to avoid
@ -1736,8 +1736,8 @@ public class Wallet extends BaseTaggableObject
Coin valueSentToMe = tx.getValueSentToMe(this);
Coin valueSentFromMe = tx.getValueSentFromMe(this);
if (log.isInfoEnabled()) {
log.info(String.format(Locale.US, "Received a pending transaction %s that spends %s from our own wallet," +
" and sends us %s", tx.getHashAsString(), valueSentFromMe.toFriendlyString(),
log.info(String.format(Locale.US, "Received a pending transaction {} that spends {} from our own wallet," +
" and sends us {}", tx.getTxId(), valueSentFromMe.toFriendlyString(),
valueSentToMe.toFriendlyString()));
}
if (tx.getConfidence().getSource().equals(TransactionConfidence.Source.UNKNOWN)) {
@ -1806,7 +1806,7 @@ public class Wallet extends BaseTaggableObject
// between pools.
EnumSet<Pool> containingPools = getContainingPools(tx);
if (!containingPools.equals(EnumSet.noneOf(Pool.class))) {
log.debug("Received tx we already saw in a block or created ourselves: " + tx.getHashAsString());
log.debug("Received tx we already saw in a block or created ourselves: " + tx.getTxId());
return false;
}
// We only care about transactions that:
@ -1948,7 +1948,7 @@ public class Wallet extends BaseTaggableObject
Coin valueDifference = valueSentToMe.subtract(valueSentFromMe);
log.info("Received tx{} for {}: {} [{}] in block {}", sideChain ? " on a side chain" : "",
valueDifference.toFriendlyString(), tx.getHashAsString(), relativityOffset,
valueDifference.toFriendlyString(), tx.getTxId(), relativityOffset,
block != null ? block.getHeader().getHash() : "(unit test)");
// Inform the key chains that the issued keys were observed in a transaction, so they know to
@ -2212,7 +2212,7 @@ public class Wallet extends BaseTaggableObject
// entirely by this point. We could and maybe should rebroadcast them so the network remembers and tries
// to confirm them again. But this is a deeply unusual edge case that due to the maturity rule should never
// happen in practice, thus for simplicities sake we ignore it here.
log.info(" coinbase tx <-dead: confidence {}", tx.getHashAsString(),
log.info(" coinbase tx <-dead: confidence {}", tx.getTxId(),
tx.getConfidence().getConfidenceType().name());
dead.remove(tx.getHash());
}
@ -2228,20 +2228,20 @@ public class Wallet extends BaseTaggableObject
if (hasOutputsToMe) {
// Needs to go into either unspent or spent (if the outputs were already spent by a pending tx).
if (tx.isEveryOwnedOutputSpent(this)) {
log.info(" tx {} ->spent (by pending)", tx.getHashAsString());
log.info(" tx {} ->spent (by pending)", tx.getTxId());
addWalletTransaction(Pool.SPENT, tx);
} else {
log.info(" tx {} ->unspent", tx.getHashAsString());
log.info(" tx {} ->unspent", tx.getTxId());
addWalletTransaction(Pool.UNSPENT, tx);
}
} else if (tx.getValueSentFromMe(this).signum() > 0) {
hasOutputsFromMe = true;
// Didn't send us any money, but did spend some. Keep it around for record keeping purposes.
log.info(" tx {} ->spent", tx.getHashAsString());
log.info(" tx {} ->spent", tx.getTxId());
addWalletTransaction(Pool.SPENT, tx);
} else if (forceAddToPool) {
// Was manually added to pending, so we should keep it to notify the user of confidence information
log.info(" tx {} ->spent (manually added)", tx.getHashAsString());
log.info(" tx {} ->spent (manually added)", tx.getTxId());
addWalletTransaction(Pool.SPENT, tx);
}
@ -2327,7 +2327,7 @@ public class Wallet extends BaseTaggableObject
// The outputs are already marked as spent by the connect call above, so check if there are any more for
// us to use. Move if not.
Transaction connected = checkNotNull(input.getConnectedTransaction());
log.info(" marked {} as spent by {}", input.getOutpoint(), tx.getHashAsString());
log.info(" marked {} as spent by {}", input.getOutpoint(), tx.getTxId());
maybeMovePool(connected, "prevtx");
// Just because it's connected doesn't mean it's actually ours: sometimes we have total visibility.
if (output.isMineOrWatched(this)) {
@ -2351,7 +2351,7 @@ public class Wallet extends BaseTaggableObject
}
if (result == TransactionInput.ConnectionResult.SUCCESS) {
log.info("Connected pending tx input {}:{}",
pendingTx.getHashAsString(), pendingTx.getInputs().indexOf(input));
pendingTx.getTxId(), pendingTx.getInputs().indexOf(input));
// The unspents map might not have it if we never saw this tx until it was included in the chain
// and thus becomes spent the moment we become aware of it.
if (myUnspents.remove(input.getConnectedOutput()))
@ -2372,8 +2372,8 @@ public class Wallet extends BaseTaggableObject
LinkedList<Transaction> work = new LinkedList<>(txnsToKill);
while (!work.isEmpty()) {
final Transaction tx = work.poll();
log.warn("TX {} killed{}", tx.getHashAsString(),
overridingTx != null ? " by " + overridingTx.getHashAsString() : "");
log.warn("TX {} killed{}", tx.getTxId(),
overridingTx != null ? " by " + overridingTx.getTxId() : "");
log.warn("Disconnecting each input and moving connected transactions.");
// TX could be pending (finney attack), or in unspent/spent (coinbase killed by reorg).
pending.remove(tx.getHash());
@ -2433,14 +2433,14 @@ public class Wallet extends BaseTaggableObject
// There's nothing left I can spend in this transaction.
if (unspent.remove(tx.getHash()) != null) {
if (log.isInfoEnabled()) {
log.info(" {} {} <-unspent ->spent", tx.getHashAsString(), context);
log.info(" {} {} <-unspent ->spent", tx.getTxId(), context);
}
spent.put(tx.getHash(), tx);
}
} else {
if (spent.remove(tx.getHash()) != null) {
if (log.isInfoEnabled()) {
log.info(" {} {} <-spent ->unspent", tx.getHashAsString(), context);
log.info(" {} {} <-spent ->unspent", tx.getTxId(), context);
}
unspent.put(tx.getHash(), tx);
}
@ -2458,7 +2458,7 @@ public class Wallet extends BaseTaggableObject
try {
if (pending.containsKey(tx.getHash()))
return false;
log.info("commitTx of {}", tx.getHashAsString());
log.info("commitTx of {}", tx.getTxId());
Coin balance = getBalance();
tx.setUpdateTime(Utils.now());
// Put any outputs that are sending money back to us into the unspents map, and calculate their total value.
@ -2481,7 +2481,7 @@ public class Wallet extends BaseTaggableObject
!isNotSpendingTxnsInConfidenceType(tx, ConfidenceType.DEAD)) {
// tx is a double spend against a tx already in the best chain or spends outputs of a DEAD tx.
// Add tx to the dead pool and schedule confidence listener notifications.
log.info("->dead: {}", tx.getHashAsString());
log.info("->dead: {}", tx.getTxId());
tx.getConfidence().setConfidenceType(ConfidenceType.DEAD);
confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.TYPE);
addWalletTransaction(Pool.DEAD, tx);
@ -2490,7 +2490,7 @@ public class Wallet extends BaseTaggableObject
// tx is a double spend against a pending tx or spends outputs of a tx already IN_CONFLICT.
// Add tx to the pending pool. Update the confidence type of tx, the txns in conflict with tx and all
// their dependencies to IN_CONFLICT and schedule confidence listener notifications.
log.info("->pending (IN_CONFLICT): {}", tx.getHashAsString());
log.info("->pending (IN_CONFLICT): {}", tx.getTxId());
addWalletTransaction(Pool.PENDING, tx);
doubleSpendPendingTxns.add(tx);
addTransactionsDependingOn(doubleSpendPendingTxns, getTransactions(true));
@ -2501,7 +2501,7 @@ public class Wallet extends BaseTaggableObject
} else {
// No conflict detected.
// Add to the pending pool and schedule confidence listener notifications.
log.info("->pending: {}", tx.getHashAsString());
log.info("->pending: {}", tx.getTxId());
tx.getConfidence().setConfidenceType(ConfidenceType.PENDING);
confidenceChanged.put(tx, TransactionConfidence.Listener.ChangeReason.TYPE);
addWalletTransaction(Pool.PENDING, tx);
@ -3067,7 +3067,7 @@ public class Wallet extends BaseTaggableObject
for (Iterator<Transaction> i = pending.values().iterator(); i.hasNext();) {
Transaction tx = i.next();
if (isTransactionRisky(tx, null) && !acceptRiskyTransactions) {
log.debug("Found risky transaction {} in wallet during cleanup.", tx.getHashAsString());
log.debug("Found risky transaction {} in wallet during cleanup.", tx.getTxId());
if (!tx.isAnyOutputSpent()) {
// Sync myUnspents with the change.
for (TransactionInput input : tx.getInputs()) {
@ -3083,11 +3083,11 @@ public class Wallet extends BaseTaggableObject
i.remove();
transactions.remove(tx.getHash());
dirty = true;
log.info("Removed transaction {} from pending pool during cleanup.", tx.getHashAsString());
log.info("Removed transaction {} from pending pool during cleanup.", tx.getTxId());
} else {
log.info(
"Cannot remove transaction {} from pending pool during cleanup, as it's already spent partially.",
tx.getHashAsString());
tx.getTxId());
}
}
}
@ -4453,7 +4453,7 @@ public class Wallet extends BaseTaggableObject
// graph we can never reliably kill all transactions we might have that were rooted in
// this coinbase tx. Some can just go pending forever, like the Bitcoin Core. However we
// can do our best.
log.warn("Coinbase killed by re-org: {}", tx.getHashAsString());
log.warn("Coinbase killed by re-org: {}", tx.getTxId());
killTxns(ImmutableSet.of(tx), null);
} else {
for (TransactionOutput output : tx.getOutputs()) {

View File

@ -734,7 +734,7 @@ public class WalletProtobufSerializer {
Transaction spendingTx = txMap.get(spentByTransactionHash);
if (spendingTx == null) {
throw new UnreadableWalletException(String.format(Locale.US, "Could not connect %s to %s",
tx.getHashAsString(), byteStringToHash(spentByTransactionHash)));
tx.getTxId(), byteStringToHash(spentByTransactionHash)));
}
final int spendingIndex = transactionOutput.getSpentByTransactionIndex();
TransactionInput input = checkNotNull(spendingTx.getInput(spendingIndex));
@ -757,7 +757,7 @@ public class WalletProtobufSerializer {
// We are lenient here because tx confidence is not an essential part of the wallet.
// If the tx has an unknown type of confidence, ignore.
if (!confidenceProto.hasType()) {
log.warn("Unknown confidence type for tx {}", tx.getHashAsString());
log.warn("Unknown confidence type for tx {}", tx.getTxId());
return;
}
ConfidenceType confidenceType;
@ -776,27 +776,27 @@ public class WalletProtobufSerializer {
confidence.setConfidenceType(confidenceType);
if (confidenceProto.hasAppearedAtHeight()) {
if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getHashAsString());
log.warn("Have appearedAtHeight but not BUILDING for tx {}", tx.getTxId());
return;
}
confidence.setAppearedAtChainHeight(confidenceProto.getAppearedAtHeight());
}
if (confidenceProto.hasDepth()) {
if (confidence.getConfidenceType() != ConfidenceType.BUILDING) {
log.warn("Have depth but not BUILDING for tx {}", tx.getHashAsString());
log.warn("Have depth but not BUILDING for tx {}", tx.getTxId());
return;
}
confidence.setDepthInBlocks(confidenceProto.getDepth());
}
if (confidenceProto.hasOverridingTransaction()) {
if (confidence.getConfidenceType() != ConfidenceType.DEAD) {
log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getHashAsString());
log.warn("Have overridingTransaction but not OVERRIDDEN for tx {}", tx.getTxId());
return;
}
Transaction overridingTransaction =
txMap.get(confidenceProto.getOverridingTransaction());
if (overridingTransaction == null) {
log.warn("Have overridingTransaction that is not in wallet for tx {}", tx.getHashAsString());
log.warn("Have overridingTransaction that is not in wallet for tx {}", tx.getTxId());
return;
}
confidence.setOverridingTransaction(overridingTransaction);

View File

@ -290,7 +290,8 @@ public class TransactionTest {
hex2 = HEX.encode(tx.bitcoinSerialize());
assertEquals(hex, hex2);
assertEquals("Uncorrect hash", "38d4cfeb57d6685753b7a3b3534c3cb576c34ca7344cd4582f9613ebf0c2b02a",
tx.getHash().toString());
tx.getTxId().toString());
assertEquals(tx.getWTxId(), tx.getTxId());
// Roundtrip with witness
hex = "0100000000010213206299feb17742091c3cb2ab45faa3aa87922d3c030cafb3f798850a2722bf0000000000feffffffa12f2424b9599898a1d30f06e1ce55eba7fabfeee82ae9356f07375806632ff3010000006b483045022100fcc8cf3014248e1a0d6dcddf03e80f7e591605ad0dbace27d2c0d87274f8cd66022053fcfff64f35f22a14deb657ac57f110084fb07bb917c3b42e7d033c54c7717b012102b9e4dcc33c9cc9cb5f42b96dddb3b475b067f3e21125f79e10c853e5ca8fba31feffffff02206f9800000000001976a9144841b9874d913c430048c78a7b18baebdbea440588ac8096980000000000160014e4873ef43eac347471dd94bc899c51b395a509a502483045022100dd8250f8b5c2035d8feefae530b10862a63030590a851183cb61b3672eb4f26e022057fe7bc8593f05416c185d829b574290fb8706423451ebd0a0ae50c276b87b43012102179862f40b85fa43487500f1d6b13c864b5eb0a83999738db0f7a6b91b2ec64f00db080000";
@ -303,7 +304,8 @@ public class TransactionTest {
hex2 = HEX.encode(tx.bitcoinSerialize());
assertEquals(hex, hex2);
assertEquals("Uncorrect hash", "99e7484eafb6e01622c395c8cae7cb9f8822aab6ba993696b39df8b60b0f4b11",
tx.getHash().toString());
tx.getTxId().toString());
assertNotEquals(tx.getWTxId(), tx.getTxId());
}
@Test
@ -597,7 +599,7 @@ public class TransactionTest {
genesis.getTransactions().get(0).getOutput(0).getOutPointFor());
final Transaction tx = block1.getTransactions().get(1);
final String txHash = tx.getHashAsString();
final Sha256Hash txHash = tx.getTxId();
final String txNormalizedHash = tx.hashForSignature(
0,
new byte[0],
@ -606,7 +608,7 @@ public class TransactionTest {
for (int i = 0; i < 100; i++) {
// ensure the transaction object itself was not modified; if it was, the hash will change
assertEquals(txHash, tx.getHashAsString());
assertEquals(txHash, tx.getTxId());
new Thread(){
public void run() {
assertEquals(

View File

@ -384,7 +384,7 @@ public class WalletProtobufSerializerTest {
Transaction tx = new Transaction(UNITTEST, Utils.HEX.decode(
"0200000001d7902864af9310420c6e606b814c8f89f7902d40c130594e85df2e757a7cc301070000006b483045022100ca1757afa1af85c2bb014382d9ce411e1628d2b3d478df9d5d3e9e93cb25dcdd02206c5d272b31a23baf64e82793ee5c816e2bbef251e733a638b630ff2331fc83ba0121026ac2316508287761befbd0f7495ea794b396dbc5b556bf276639f56c0bd08911feffffff0274730700000000001976a91456da2d038a098c42390c77ef163e1cc23aedf24088ac91062300000000001976a9148ebf3467b9a8d7ae7b290da719e61142793392c188ac22e00600"));
assertEquals(tx.getVersion(), 2);
assertEquals(tx.getHashAsString(), "0321b1413ed9048199815bd6bc2650cab1a9e8d543f109a42c769b1f18df4174");
assertEquals(tx.getTxId().toString(), "0321b1413ed9048199815bd6bc2650cab1a9e8d543f109a42c769b1f18df4174");
myWallet.addWalletTransaction(new WalletTransaction(Pool.UNSPENT, tx));
Wallet wallet1 = roundTrip(myWallet);
Transaction tx2 = wallet1.getTransaction(tx.getHash());
@ -481,7 +481,7 @@ public class WalletProtobufSerializerTest {
Transaction tx = new Transaction(UNITTEST, Utils.HEX.decode(
"02000000000103fc8a5bea59392369e8a1b635395e507a5cbaeffd926e6967a00d17c669aef1d3010000001716001403c80a334ed6a92cf400d8c708522ea0d6fa5593ffffffffc0166d2218a2613b5384fc2c31238b1b6fa337080a1384220734e1bfd3629d3f0100000000ffffffffc0166d2218a2613b5384fc2c31238b1b6fa337080a1384220734e1bfd3629d3f0200000000ffffffff01a086010000000000220020eb72e573a9513d982a01f0e6a6b53e92764db81a0c26d2be94c5fc5b69a0db7d02473044022048e895b7af715303ce273a2be03d6110ed69b5700679f4f036000f8ba6eddd2802205f780423fcce9b3632ed41681b0a86f5d123766b71f303558c39c1be5fe43e2601210259eb16169df80dbe5856d082a226d84a97d191c895f8046c3544df525028a874000220c0166d2218a2613b5384fc2c31238b1b6fa337080a1384220734e1bfd3629d3f20c0166d2218a2613b5384fc2c31238b1b6fa337080a1384220734e1bfd3629d3f00000000"));
assertTrue(tx.hasWitnesses());
assertEquals(tx.getHashAsString(), "1c687396f4710f26206dbdd8bf07a28c76398be6750226ddfaf05a1a80d30034");
assertEquals(tx.getTxId().toString(), "1c687396f4710f26206dbdd8bf07a28c76398be6750226ddfaf05a1a80d30034");
myWallet.addWalletTransaction(new WalletTransaction(Pool.UNSPENT, tx));
Wallet wallet1 = roundTrip(myWallet);
Transaction tx2 = wallet1.getTransaction(tx.getHash());

View File

@ -187,7 +187,7 @@ public class DefaultRiskAnalysisTest {
// This is a real transaction. Its signatures S component is "low".
Transaction tx1 = new Transaction(MAINNET, Utils.HEX.decode(
"010000000200a2be4376b7f47250ad9ad3a83b6aa5eb6a6d139a1f50771704d77aeb8ce76c010000006a4730440220055723d363cd2d4fe4e887270ebdf5c4b99eaf233a5c09f9404f888ec8b839350220763c3794d310b384ce86decfb05787e5bfa5d31983db612a2dde5ffec7f396ae012102ef47e27e0c4bdd6dc83915f185d972d5eb8515c34d17bad584a9312e59f4e0bcffffffff52239451d37757eeacb86d32864ec1ee6b6e131d1e3fee6f1cff512703b71014030000006b483045022100ea266ac4f893d98a623a6fc0e6a961cd5a3f32696721e87e7570a68851917e75022056d75c3b767419f6f6cb8189a0ad78d45971523908dc4892f7594b75fd43a8d00121038bb455ca101ebbb0ecf7f5c01fa1dcb7d14fbf6b7d7ea52ee56f0148e72a736cffffffff0630b15a00000000001976a9146ae477b690cf85f21c2c01e2c8639a5c18dc884e88ac4f260d00000000001976a91498d08c02ab92a671590adb726dddb719695ee12e88ac65753b00000000001976a9140b2eb4ba6d364c82092f25775f56bc10cd92c8f188ac65753b00000000001976a914d1cb414e22081c6ba3a935635c0f1d837d3c5d9188ac65753b00000000001976a914df9d137a0d279471a2796291874c29759071340b88ac3d753b00000000001976a91459f5aa4815e3aa8e1720e8b82f4ac8e6e904e47d88ac00000000"));
assertEquals("2a1c8569b2b01ebac647fb94444d1118d4d00e327456a3c518e40d47d72cd5fe", tx1.getHashAsString());
assertEquals("2a1c8569b2b01ebac647fb94444d1118d4d00e327456a3c518e40d47d72cd5fe", tx1.getTxId().toString());
assertEquals(RuleViolation.NONE, DefaultRiskAnalysis.isStandard(tx1));
@ -195,7 +195,7 @@ public class DefaultRiskAnalysisTest {
// It was part of the Oct 2015 malleability attack.
Transaction tx2 = new Transaction(MAINNET, Utils.HEX.decode(
"010000000200a2be4376b7f47250ad9ad3a83b6aa5eb6a6d139a1f50771704d77aeb8ce76c010000006a4730440220055723d363cd2d4fe4e887270ebdf5c4b99eaf233a5c09f9404f888ec8b839350220763c3794d310b384ce86decfb05787e5bfa5d31983db612a2dde5ffec7f396ae012102ef47e27e0c4bdd6dc83915f185d972d5eb8515c34d17bad584a9312e59f4e0bcffffffff52239451d37757eeacb86d32864ec1ee6b6e131d1e3fee6f1cff512703b71014030000006c493046022100ea266ac4f893d98a623a6fc0e6a961cd5a3f32696721e87e7570a68851917e75022100a928a3c4898be60909347e765f52872a613d8aada66c57a8c8791316d2f298710121038bb455ca101ebbb0ecf7f5c01fa1dcb7d14fbf6b7d7ea52ee56f0148e72a736cffffffff0630b15a00000000001976a9146ae477b690cf85f21c2c01e2c8639a5c18dc884e88ac4f260d00000000001976a91498d08c02ab92a671590adb726dddb719695ee12e88ac65753b00000000001976a9140b2eb4ba6d364c82092f25775f56bc10cd92c8f188ac65753b00000000001976a914d1cb414e22081c6ba3a935635c0f1d837d3c5d9188ac65753b00000000001976a914df9d137a0d279471a2796291874c29759071340b88ac3d753b00000000001976a91459f5aa4815e3aa8e1720e8b82f4ac8e6e904e47d88ac00000000"));
assertEquals("dbe4147cf89b89fd9fa6c8ce6a3e2adecb234db094ec88301ae09073ca17d61d", tx2.getHashAsString());
assertEquals("dbe4147cf89b89fd9fa6c8ce6a3e2adecb234db094ec88301ae09073ca17d61d", tx2.getTxId().toString());
assertFalse(ECKey.ECDSASignature
.decodeFromDER(new Script(tx2.getInputs().get(1).getScriptBytes()).getChunks().get(0).data)
.isCanonical());

View File

@ -53,7 +53,7 @@ public class FetchTransactions {
System.out.println("Waiting for node to send us the dependencies ...");
List<Transaction> deps = peer.downloadDependencies(tx).get();
for (Transaction dep : deps) {
System.out.println("Got dependency " + dep.getHashAsString());
System.out.println("Got dependency " + dep.getTxId());
}
System.out.println("Done.");

View File

@ -145,7 +145,7 @@ public class ForwardingService {
@Override
public void run() {
// The wallet has changed now, it'll get auto saved shortly or when the app shuts down.
System.out.println("Sent coins onwards! Transaction hash is " + sendResult.tx.getHashAsString());
System.out.println("Sent coins onwards! Transaction hash is " + sendResult.tx.getTxId());
}
}, MoreExecutors.directExecutor());
} catch (KeyCrypterException | InsufficientMoneyException e) {

View File

@ -108,7 +108,7 @@ public class GenerateLowSTests {
// First output a conventional low-S transaction with the LOW_S flag, for the tx_valid.json set
System.out.println("[\"A transaction with a low-S signature.\"],");
System.out.println("[[[\""
+ inputTransaction.getHashAsString() + "\", "
+ inputTransaction.getTxId() + "\", "
+ output.getIndex() + ", \""
+ scriptToString(output.getScriptPubKey()) + "\"]],\n"
+ "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""
@ -123,7 +123,7 @@ public class GenerateLowSTests {
// A high-S transaction without the LOW_S flag, for the tx_valid.json set
System.out.println("[\"A transaction with a high-S signature.\"],");
System.out.println("[[[\""
+ inputTransaction.getHashAsString() + "\", "
+ inputTransaction.getTxId() + "\", "
+ output.getIndex() + ", \""
+ scriptToString(output.getScriptPubKey()) + "\"]],\n"
+ "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""
@ -132,7 +132,7 @@ public class GenerateLowSTests {
// Lastly a conventional high-S transaction with the LOW_S flag, for the tx_invalid.json set
System.out.println("[\"A transaction with a high-S signature.\"],");
System.out.println("[[[\""
+ inputTransaction.getHashAsString() + "\", "
+ inputTransaction.getTxId() + "\", "
+ output.getIndex() + ", \""
+ scriptToString(output.getScriptPubKey()) + "\"]],\n"
+ "\"" + Utils.HEX.encode(proposedTransaction.partialTx.unsafeBitcoinSerialize()) + "\", \""

View File

@ -68,7 +68,7 @@ public class Kit {
kit.wallet().addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
System.out.println("-----> coins resceived: " + tx.getHashAsString());
System.out.println("-----> coins resceived: " + tx.getTxId());
System.out.println("received: " + tx.getValue(wallet));
}
});
@ -97,7 +97,7 @@ public class Kit {
kit.wallet().addTransactionConfidenceEventListener(new TransactionConfidenceEventListener() {
@Override
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
System.out.println("-----> confidence changed: " + tx.getHashAsString());
System.out.println("-----> confidence changed: " + tx.getTxId());
TransactionConfidence confidence = tx.getConfidence();
System.out.println("new block depth: " + confidence.getDepthInBlocks());
}

View File

@ -47,7 +47,7 @@ public class RefreshWallet {
wallet.addCoinsReceivedEventListener(new WalletCoinsReceivedEventListener() {
@Override
public synchronized void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
System.out.println("\nReceived tx " + tx.getHashAsString());
System.out.println("\nReceived tx " + tx.getTxId());
System.out.println(tx.toString());
}
});

View File

@ -59,7 +59,7 @@ public class SendRequest {
// In this example we catch the InsufficientMoneyException and register a BalanceFuture callback that runs once the wallet has enough balance.
try {
Wallet.SendResult result = kit.wallet().sendCoins(kit.peerGroup(), to, value);
System.out.println("coins sent. transaction hash: " + result.tx.getHashAsString());
System.out.println("coins sent. transaction hash: " + result.tx.getTxId());
// you can use a block explorer like https://www.biteasy.com/ to inspect the transaction with the printed transaction hash.
} catch (InsufficientMoneyException e) {
System.out.println("Not enough coins in your wallet. Missing " + e.missing.getValue() + " satoshis are missing (including fees)");

View File

@ -675,7 +675,7 @@ public class WalletTool {
throw new RuntimeException(e);
}
t = req.tx; // Not strictly required today.
System.out.println(t.getHashAsString());
System.out.println(t.getTxId());
if (options.has("offline")) {
wallet.commitTx(t);
return;
@ -792,7 +792,7 @@ public class WalletTool {
}
wallet.completeTx(req);
System.out.println(req.tx.getHashAsString());
System.out.println(req.tx.getTxId());
if (options.has("offline")) {
wallet.commitTx(req.tx);
return;
@ -898,7 +898,7 @@ public class WalletTool {
req.tx.calculateSignature(0, key2, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
input.setScriptSig(ScriptBuilder.createCLTVPaymentChannelInput(sig1, sig2));
System.out.println(req.tx.getHashAsString());
System.out.println(req.tx.getTxId());
if (options.has("offline")) {
wallet.commitTx(req.tx);
return;
@ -1001,7 +1001,7 @@ public class WalletTool {
req.tx.calculateSignature(0, key, lockTimeVerifyOutput.getScriptPubKey(), Transaction.SigHash.SINGLE, false);
input.setScriptSig(ScriptBuilder.createCLTVPaymentChannelRefund(sig));
System.out.println(req.tx.getHashAsString());
System.out.println(req.tx.getTxId());
if (options.has("offline")) {
wallet.commitTx(req.tx);
return;
@ -1162,7 +1162,7 @@ public class WalletTool {
@Override
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
// Runs in a peer thread.
System.out.println(tx.getHashAsString());
System.out.println(tx.getTxId());
latch.countDown(); // Wake up main thread.
}
});
@ -1170,7 +1170,7 @@ public class WalletTool {
@Override
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
// Runs in a peer thread.
System.out.println(tx.getHashAsString());
System.out.println(tx.getTxId());
latch.countDown(); // Wake up main thread.
}
});

View File

@ -54,7 +54,7 @@ public class WatchMempool {
public void onTransaction(Peer peer, Transaction tx) {
Result result = DefaultRiskAnalysis.FACTORY.create(null, tx, NO_DEPS).analyze();
incrementCounter(TOTAL_KEY);
log.info("tx {} result {}", tx.getHash(), result);
log.info("tx {} result {}", tx.getTxId(), result);
incrementCounter(result.name());
if (result == Result.NON_STANDARD)
incrementCounter(Result.NON_STANDARD + "-" + DefaultRiskAnalysis.isStandard(tx));