Unverified Commit bbd03e03 authored by TDevD's avatar TDevD Committed by GitHub
Browse files

Merge pull request #6 from Samourai-Wallet/develop

build 004
parents 33852ab5 2058bafb
[![Build Status](https://travis-ci.org/bitcoinj/bitcoinj.png?branch=master)](https://travis-ci.org/bitcoinj/bitcoinj) [![Coverage Status](https://coveralls.io/repos/bitcoinj/bitcoinj/badge.png?branch=master)](https://coveralls.io/r/bitcoinj/bitcoinj?branch=master) [![](https://jitpack.io/v/Samourai-Wallet/bitcoinj.svg)](https://jitpack.io/#Samourai-Wallet/bitcoinj)
[![Build Status](https://travis-ci.org/bitcoinj/bitcoinj.png?branch=master)](https://travis-ci.org/bitcoinj/bitcoinj) [![Coverage Status](https://coveralls.io/repos/bitcoinj/bitcoinj/badge.png?branch=master)](https://coveralls.io/r/bitcoinj/bitcoinj?branch=master)
[![Visit our IRC channel](https://kiwiirc.com/buttons/irc.freenode.net/bitcoinj.png)](https://kiwiirc.com/client/irc.freenode.net/bitcoinj) [![Visit our IRC channel](https://kiwiirc.com/buttons/irc.freenode.net/bitcoinj.png)](https://kiwiirc.com/client/irc.freenode.net/bitcoinj)
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
<parent> <parent>
<groupId>org.bitcoinj</groupId> <groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-parent</artifactId> <artifactId>bitcoinj-parent</artifactId>
<version>0.15-Segwit-Samourai-001</version> <version>0.15-Segwit-Samourai-004</version>
</parent> </parent>
<artifactId>bitcoinj-core</artifactId> <artifactId>bitcoinj-core</artifactId>
...@@ -183,15 +183,17 @@ ...@@ -183,15 +183,17 @@
<!-- classifier is "null" if not present --> <!-- classifier is "null" if not present -->
<urns> <urns>
<urn>cglib:cglib-nodep:2.2:jar:null:test:59afed7ab65e7ec6585d5bc60556c3cbd203532b</urn> <urn>cglib:cglib-nodep:2.2:jar:null:test:59afed7ab65e7ec6585d5bc60556c3cbd203532b</urn>
<!--
<urn>com.fasterxml.jackson.core:jackson-annotations:2.5.0:jar:null:test:a2a55a3375bc1cef830ca426d68d2ea22961190e</urn> <urn>com.fasterxml.jackson.core:jackson-annotations:2.5.0:jar:null:test:a2a55a3375bc1cef830ca426d68d2ea22961190e</urn>
<urn>com.fasterxml.jackson.core:jackson-core:2.5.1:jar:null:test:e2a00ad1d7e540ec395e9296a34da484c8888d4d</urn> <urn>com.fasterxml.jackson.core:jackson-core:2.5.1:jar:null:test:e2a00ad1d7e540ec395e9296a34da484c8888d4d</urn>
<urn>com.fasterxml.jackson.core:jackson-databind:2.5.2:jar:null:test:2b4dd13fbe6f8c6b146d4c3b7fd70862f136802d</urn> <urn>com.fasterxml.jackson.core:jackson-databind:2.5.2:jar:null:test:2b4dd13fbe6f8c6b146d4c3b7fd70862f136802d</urn>
-->
<urn>com.google.code.findbugs:jsr305:2.0.1:jar:null:compile:516c03b21d50a644d538de0f0369c620989cd8f0</urn> <urn>com.google.code.findbugs:jsr305:2.0.1:jar:null:compile:516c03b21d50a644d538de0f0369c620989cd8f0</urn>
<urn>com.google.guava:guava:18.0:jar:null:compile:cce0823396aa693798f8882e64213b1772032b09</urn> <urn>com.google.guava:guava:18.0:jar:null:compile:cce0823396aa693798f8882e64213b1772032b09</urn>
<urn>com.google.protobuf:protobuf-java:2.6.1:jar:null:compile:d9521f2aecb909835746b7a5facf612af5e890e8</urn> <urn>com.google.protobuf:protobuf-java:2.6.1:jar:null:compile:d9521f2aecb909835746b7a5facf612af5e890e8</urn>
<urn>com.h2database:h2:1.3.167:jar:null:compile:d3867d586f087e53eb12fc65e5693d8ee9a5da17</urn> <urn>com.h2database:h2:1.3.167:jar:null:compile:d3867d586f087e53eb12fc65e5693d8ee9a5da17</urn>
<urn>com.lambdaworks:scrypt:1.4.0:jar:null:compile:906506b74f30c8c20bccd9ed4a11112d8941fe87</urn> <urn>com.lambdaworks:scrypt:1.4.0:jar:null:compile:906506b74f30c8c20bccd9ed4a11112d8941fe87</urn>
<urn>org.bouncycastle:bcprov-jdk15on:1.55:jar:null:compile:6fc928491ada0974140257e85e2b016a2eee0e1d</urn> <urn>org.bouncycastle:bcprov-jdk15on:1.55:jar:null:compile:935f2e57a00ec2c489cbd2ad830d4a399708f979</urn>
<urn>junit:junit:4.12:jar:null:test:2973d150c0dc1fefe998f834810d68f278ea58ec</urn> <urn>junit:junit:4.12:jar:null:test:2973d150c0dc1fefe998f834810d68f278ea58ec</urn>
<urn>mysql:mysql-connector-java:5.1.33:jar:null:compile:8af455a9a3267e6664cafc87ace71a4e4ef02837</urn> <urn>mysql:mysql-connector-java:5.1.33:jar:null:compile:8af455a9a3267e6664cafc87ace71a4e4ef02837</urn>
<urn>net.jcip:jcip-annotations:1.0:jar:null:compile:afba4942caaeaf46aab0b976afd57cc7c181467e</urn> <urn>net.jcip:jcip-annotations:1.0:jar:null:compile:afba4942caaeaf46aab0b976afd57cc7c181467e</urn>
...@@ -365,7 +367,7 @@ ...@@ -365,7 +367,7 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.5.2</version> <version>2.8.11.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
...@@ -432,5 +434,4 @@ ...@@ -432,5 +434,4 @@
<version>2.7.5</version> <version>2.7.5</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -21,6 +21,7 @@ import com.google.common.base.*; ...@@ -21,6 +21,7 @@ import com.google.common.base.*;
import com.google.common.collect.*; import com.google.common.collect.*;
import com.google.common.util.concurrent.*; import com.google.common.util.concurrent.*;
import org.bitcoinj.core.listeners.*; import org.bitcoinj.core.listeners.*;
import org.bitcoinj.script.ScriptException;
import org.bitcoinj.store.*; import org.bitcoinj.store.*;
import org.bitcoinj.utils.*; import org.bitcoinj.utils.*;
import org.bitcoinj.wallet.Wallet; import org.bitcoinj.wallet.Wallet;
...@@ -281,14 +282,14 @@ public abstract class AbstractBlockChain { ...@@ -281,14 +282,14 @@ public abstract class AbstractBlockChain {
public void removeTransactionReceivedListener(TransactionReceivedInBlockListener listener) { public void removeTransactionReceivedListener(TransactionReceivedInBlockListener listener) {
ListenerRegistration.removeFromList(listener, transactionReceivedListeners); ListenerRegistration.removeFromList(listener, transactionReceivedListeners);
} }
/** /**
* Returns the {@link BlockStore} the chain was constructed with. You can use this to iterate over the chain. * Returns the {@link BlockStore} the chain was constructed with. You can use this to iterate over the chain.
*/ */
public BlockStore getBlockStore() { public BlockStore getBlockStore() {
return blockStore; return blockStore;
} }
/** /**
* Adds/updates the given {@link Block} with the block store. * Adds/updates the given {@link Block} with the block store.
* This version is used when the transactions have not been verified. * This version is used when the transactions have not been verified.
...@@ -298,7 +299,7 @@ public abstract class AbstractBlockChain { ...@@ -298,7 +299,7 @@ public abstract class AbstractBlockChain {
*/ */
protected abstract StoredBlock addToBlockStore(StoredBlock storedPrev, Block block) protected abstract StoredBlock addToBlockStore(StoredBlock storedPrev, Block block)
throws BlockStoreException, VerificationException; throws BlockStoreException, VerificationException;
/** /**
* Adds/updates the given {@link StoredBlock} with the block store. * Adds/updates the given {@link StoredBlock} with the block store.
* This version is used when the transactions have already been verified to properly spend txOutputChanges. * This version is used when the transactions have already been verified to properly spend txOutputChanges.
...@@ -314,7 +315,7 @@ public abstract class AbstractBlockChain { ...@@ -314,7 +315,7 @@ public abstract class AbstractBlockChain {
/** /**
* Rollback the block store to a given height. This is currently only supported by {@link BlockChain} instances. * Rollback the block store to a given height. This is currently only supported by {@link BlockChain} instances.
* *
* @throws BlockStoreException * @throws BlockStoreException
* if the operation fails or is unsupported. * if the operation fails or is unsupported.
*/ */
...@@ -326,7 +327,7 @@ public abstract class AbstractBlockChain { ...@@ -326,7 +327,7 @@ public abstract class AbstractBlockChain {
* that were started by disconnectTransactions/connectTransactions. * that were started by disconnectTransactions/connectTransactions.
*/ */
protected abstract void doSetChainHead(StoredBlock chainHead) throws BlockStoreException; protected abstract void doSetChainHead(StoredBlock chainHead) throws BlockStoreException;
/** /**
* Called if we (possibly) previously called disconnectTransaction/connectTransactions, * Called if we (possibly) previously called disconnectTransaction/connectTransactions,
* but will not be calling preSetChainHead as a block failed verification. * but will not be calling preSetChainHead as a block failed verification.
...@@ -334,7 +335,7 @@ public abstract class AbstractBlockChain { ...@@ -334,7 +335,7 @@ public abstract class AbstractBlockChain {
* disconnectTransactions/connectTransactions. * disconnectTransactions/connectTransactions.
*/ */
protected abstract void notSettingChainHead() throws BlockStoreException; protected abstract void notSettingChainHead() throws BlockStoreException;
/** /**
* For a standard BlockChain, this should return blockStore.get(hash), * For a standard BlockChain, this should return blockStore.get(hash),
* for a FullPrunedBlockChain blockStore.getOnceUndoableStoredBlock(hash) * for a FullPrunedBlockChain blockStore.getOnceUndoableStoredBlock(hash)
...@@ -363,7 +364,7 @@ public abstract class AbstractBlockChain { ...@@ -363,7 +364,7 @@ public abstract class AbstractBlockChain {
block.toString(), e); block.toString(), e);
} }
} }
/** /**
* Processes a received block and tries to add it to the chain. If there's something wrong with the block an * Processes a received block and tries to add it to the chain. If there's something wrong with the block an
* exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false. * exception is thrown. If the block is OK but cannot be connected to the chain at this time, returns false.
...@@ -392,13 +393,13 @@ public abstract class AbstractBlockChain { ...@@ -392,13 +393,13 @@ public abstract class AbstractBlockChain {
block.toString(), e); block.toString(), e);
} }
} }
/** /**
* Whether or not we are maintaining a set of unspent outputs and are verifying all transactions. * Whether or not we are maintaining a set of unspent outputs and are verifying all transactions.
* Also indicates that all calls to add() should provide a block containing transactions * Also indicates that all calls to add() should provide a block containing transactions
*/ */
protected abstract boolean shouldVerifyTransactions(); protected abstract boolean shouldVerifyTransactions();
/** /**
* Connect each transaction in block.transactions, verifying them as we go and removing spent outputs * Connect each transaction in block.transactions, verifying them as we go and removing spent outputs
* If an error is encountered in a transaction, no changes should be made to the underlying BlockStore. * If an error is encountered in a transaction, no changes should be made to the underlying BlockStore.
...@@ -419,8 +420,8 @@ public abstract class AbstractBlockChain { ...@@ -419,8 +420,8 @@ public abstract class AbstractBlockChain {
* @throws BlockStoreException if the block store had an underlying error or newBlock does not exist in the block store at all. * @throws BlockStoreException if the block store had an underlying error or newBlock does not exist in the block store at all.
* @return The full set of all changes made to the set of open transaction outputs. * @return The full set of all changes made to the set of open transaction outputs.
*/ */
protected abstract TransactionOutputChanges connectTransactions(StoredBlock newBlock) throws VerificationException, BlockStoreException, PrunedException; protected abstract TransactionOutputChanges connectTransactions(StoredBlock newBlock) throws VerificationException, BlockStoreException, PrunedException;
// filteredTxHashList contains all transactions, filteredTxn just a subset // filteredTxHashList contains all transactions, filteredTxn just a subset
private boolean add(Block block, boolean tryConnecting, private boolean add(Block block, boolean tryConnecting,
@Nullable List<Sha256Hash> filteredTxHashList, @Nullable Map<Sha256Hash, Transaction> filteredTxn) @Nullable List<Sha256Hash> filteredTxHashList, @Nullable Map<Sha256Hash, Transaction> filteredTxn)
...@@ -531,7 +532,7 @@ public abstract class AbstractBlockChain { ...@@ -531,7 +532,7 @@ public abstract class AbstractBlockChain {
if (!tx.isFinal(storedPrev.getHeight() + 1, block.getTimeSeconds())) if (!tx.isFinal(storedPrev.getHeight() + 1, block.getTimeSeconds()))
throw new VerificationException("Block contains non-final transaction"); throw new VerificationException("Block contains non-final transaction");
} }
StoredBlock head = getChainHead(); StoredBlock head = getChainHead();
if (storedPrev.equals(head)) { if (storedPrev.equals(head)) {
if (filtered && filteredTxn.size() > 0) { if (filtered && filteredTxn.size() > 0) {
...@@ -598,14 +599,14 @@ public abstract class AbstractBlockChain { ...@@ -598,14 +599,14 @@ public abstract class AbstractBlockChain {
splitPointHeight, splitPointHash, newBlock.getHeader().getHashAsString()); splitPointHeight, splitPointHash, newBlock.getHeader().getHashAsString());
} }
} }
// We may not have any transactions if we received only a header, which can happen during fast catchup. // We may not have any transactions if we received only a header, which can happen during fast catchup.
// If we do, send them to the wallet but state that they are on a side chain so it knows not to try and // If we do, send them to the wallet but state that they are on a side chain so it knows not to try and
// spend them until they become activated. // spend them until they become activated.
if (block.transactions != null || filtered) { if (block.transactions != null || filtered) {
informListenersForNewBlock(block, NewBlockType.SIDE_CHAIN, filteredTxHashList, filteredTxn, newBlock); informListenersForNewBlock(block, NewBlockType.SIDE_CHAIN, filteredTxHashList, filteredTxn, newBlock);
} }
if (haveNewBestChain) if (haveNewBestChain)
handleNewBestChain(storedPrev, newBlock, block, expensiveChecks); handleNewBestChain(storedPrev, newBlock, block, expensiveChecks);
} }
...@@ -721,11 +722,11 @@ public abstract class AbstractBlockChain { ...@@ -721,11 +722,11 @@ public abstract class AbstractBlockChain {
timestamps[10] = storedBlock.getHeader().getTimeSeconds(); timestamps[10] = storedBlock.getHeader().getTimeSeconds();
while (unused >= 0 && (storedBlock = storedBlock.getPrev(store)) != null) while (unused >= 0 && (storedBlock = storedBlock.getPrev(store)) != null)
timestamps[unused--] = storedBlock.getHeader().getTimeSeconds(); timestamps[unused--] = storedBlock.getHeader().getTimeSeconds();
Arrays.sort(timestamps, unused+1, 11); Arrays.sort(timestamps, unused+1, 11);
return timestamps[unused + (11-unused)/2]; return timestamps[unused + (11-unused)/2];
} }
/** /**
* Disconnect each transaction in the block (after reading it from the block store) * Disconnect each transaction in the block (after reading it from the block store)
* Only called if(shouldVerifyTransactions()) * Only called if(shouldVerifyTransactions())
...@@ -736,7 +737,7 @@ public abstract class AbstractBlockChain { ...@@ -736,7 +737,7 @@ public abstract class AbstractBlockChain {
/** /**
* Called as part of connecting a block when the new block results in a different chain having higher total work. * Called as part of connecting a block when the new block results in a different chain having higher total work.
* *
* if (shouldVerifyTransactions) * if (shouldVerifyTransactions)
* Either newChainHead needs to be in the block store as a FullStoredBlock, or (block != null && block.transactions != null) * Either newChainHead needs to be in the block store as a FullStoredBlock, or (block != null && block.transactions != null)
*/ */
......
...@@ -90,6 +90,10 @@ public abstract class NetworkParameters { ...@@ -90,6 +90,10 @@ public abstract class NetworkParameters {
protected byte[] alertSigningKey; protected byte[] alertSigningKey;
protected int bip32HeaderPub; protected int bip32HeaderPub;
protected int bip32HeaderPriv; protected int bip32HeaderPriv;
protected int bip49HeaderPub;
protected int bip49HeaderPriv;
protected int bip84HeaderPub;
protected int bip84HeaderPriv;
/** Used to check majorities for block version upgrade */ /** Used to check majorities for block version upgrade */
protected int majorityEnforceBlockUpgrade; protected int majorityEnforceBlockUpgrade;
...@@ -107,7 +111,7 @@ public abstract class NetworkParameters { ...@@ -107,7 +111,7 @@ public abstract class NetworkParameters {
*/ */
protected int spendableCoinbaseDepth; protected int spendableCoinbaseDepth;
protected int subsidyDecreaseBlockCount; protected int subsidyDecreaseBlockCount;
protected int[] acceptableAddressCodes; protected int[] acceptableAddressCodes;
protected String[] dnsSeeds; protected String[] dnsSeeds;
protected int[] addrSeeds; protected int[] addrSeeds;
...@@ -146,7 +150,7 @@ public abstract class NetworkParameters { ...@@ -146,7 +150,7 @@ public abstract class NetworkParameters {
public static final int TARGET_TIMESPAN = 14 * 24 * 60 * 60; // 2 weeks per difficulty cycle, on average. public static final int TARGET_TIMESPAN = 14 * 24 * 60 * 60; // 2 weeks per difficulty cycle, on average.
public static final int TARGET_SPACING = 10 * 60; // 10 minutes per block. public static final int TARGET_SPACING = 10 * 60; // 10 minutes per block.
public static final int INTERVAL = TARGET_TIMESPAN / TARGET_SPACING; public static final int INTERVAL = TARGET_TIMESPAN / TARGET_SPACING;
/** /**
* Blocks with a timestamp after this should enforce BIP 16, aka "Pay to script hash". This BIP changed the * Blocks with a timestamp after this should enforce BIP 16, aka "Pay to script hash". This BIP changed the
* network rules in a soft-forking manner, that is, blocks that don't follow the rules are accepted but not * network rules in a soft-forking manner, that is, blocks that don't follow the rules are accepted but not
...@@ -406,6 +410,26 @@ public abstract class NetworkParameters { ...@@ -406,6 +410,26 @@ public abstract class NetworkParameters {
return bip32HeaderPriv; return bip32HeaderPriv;
} }
/** Returns the 4 byte header for BIP49 (HD) wallet - public key part. */
public int getBip49HeaderPub() {
return bip49HeaderPub;
}
/** Returns the 4 byte header for BIP49 (HD) wallet - private key part. */
public int getBip49HeaderPriv() {
return bip49HeaderPriv;
}
/** Returns the 4 byte header for BIP84 (HD) wallet - public key part. */
public int getBip84HeaderPub() {
return bip84HeaderPub;
}
/** Returns the 4 byte header for BIP84 (HD) wallet - private key part. */
public int getBip84HeaderPriv() {
return bip84HeaderPriv;
}
/** /**
* Returns the number of coins that will be produced in total, on this * Returns the number of coins that will be produced in total, on this
* network. Where not applicable, a very large number of coins is returned * network. Where not applicable, a very large number of coins is returned
...@@ -438,7 +462,7 @@ public abstract class NetworkParameters { ...@@ -438,7 +462,7 @@ public abstract class NetworkParameters {
/** /**
* Return the default serializer for this network. This is a shared serializer. * Return the default serializer for this network. This is a shared serializer.
* @return * @return
*/ */
public final MessageSerializer getDefaultSerializer() { public final MessageSerializer getDefaultSerializer() {
// Construct a default serializer if we don't have one // Construct a default serializer if we don't have one
...@@ -493,7 +517,7 @@ public abstract class NetworkParameters { ...@@ -493,7 +517,7 @@ public abstract class NetworkParameters {
* The flags indicating which block validation tests should be applied to * The flags indicating which block validation tests should be applied to
* the given block. Enables support for alternative blockchains which enable * the given block. Enables support for alternative blockchains which enable
* tests based on different criteria. * tests based on different criteria.
* *
* @param block block to determine flags for. * @param block block to determine flags for.
* @param height height of the block, if known, null otherwise. Returned * @param height height of the block, if known, null otherwise. Returned
* tests should be a safe subset if block height is unknown. * tests should be a safe subset if block height is unknown.
......
...@@ -564,6 +564,15 @@ public class Peer extends PeerSocketHandler { ...@@ -564,6 +564,15 @@ public class Peer extends PeerSocketHandler {
close(); close();
return; return;
} }
if (((vPeerVersionMessage.localServices
& VersionMessage.NODE_BITCOIN_CASH) == VersionMessage.NODE_BITCOIN_CASH) ||
((vPeerVersionMessage.localServices
& VersionMessage.NODE_SEGWIT2X) == VersionMessage.NODE_SEGWIT2X)) {
log.info("{}: Peer follows an incompatible block chain.", this);
// Shut down the channel gracefully.
close();
return;
}
if (vPeerVersionMessage.bestHeight < 0) if (vPeerVersionMessage.bestHeight < 0)
// In this case, it's a protocol violation. // In this case, it's a protocol violation.
throw new ProtocolException("Peer reports invalid best height: " + vPeerVersionMessage.bestHeight); throw new ProtocolException("Peer reports invalid best height: " + vPeerVersionMessage.bestHeight);
......
...@@ -21,6 +21,7 @@ import org.bitcoinj.core.TransactionConfidence.ConfidenceType; ...@@ -21,6 +21,7 @@ import org.bitcoinj.core.TransactionConfidence.ConfidenceType;
import org.bitcoinj.crypto.TransactionSignature; import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.script.Script; import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptBuilder; import org.bitcoinj.script.ScriptBuilder;
import org.bitcoinj.script.ScriptException;
import org.bitcoinj.script.ScriptOpCodes; import org.bitcoinj.script.ScriptOpCodes;
import org.bitcoinj.signers.TransactionSigner; import org.bitcoinj.signers.TransactionSigner;
import org.bitcoinj.utils.ExchangeRate; import org.bitcoinj.utils.ExchangeRate;
...@@ -56,7 +57,7 @@ import java.math.BigInteger; ...@@ -56,7 +57,7 @@ import java.math.BigInteger;
* Whether to trust a transaction is something that needs to be decided on a case by case basis - a rule that makes * Whether to trust a transaction is something that needs to be decided on a case by case basis - a rule that makes
* sense for selling MP3s might not make sense for selling cars, or accepting payments from a family member. If you * sense for selling MP3s might not make sense for selling cars, or accepting payments from a family member. If you
* are building a wallet, how to present confidence to your users is something to consider carefully.</p> * are building a wallet, how to present confidence to your users is something to consider carefully.</p>
* *
* <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 Transaction extends ChildMessage { public class Transaction extends ChildMessage {
...@@ -188,6 +189,11 @@ public class Transaction extends ChildMessage { ...@@ -188,6 +189,11 @@ public class Transaction extends ChildMessage {
@Nullable @Nullable
private String memo; private String memo;
/**
* Segwit makes sigop limit four times higher and scales regular sigops by four.
*/
public static final int WITNESS_SCALE_FACTOR = 4;
public Transaction(NetworkParameters params) { public Transaction(NetworkParameters params) {
super(params); super(params);
version = 1; version = 1;
...@@ -1687,4 +1693,40 @@ public class Transaction extends ChildMessage { ...@@ -1687,4 +1693,40 @@ public class Transaction extends ChildMessage {
public void setMemo(String memo) { public void setMemo(String memo) {
this.memo = memo; this.memo = memo;
} }
/**
* Transaction weight is a segwit-related computation 3b+t where b is the size of a transaction serialized in the
* traditional manner without witness data, and t is the size of a transaction serialized in the segwit format
* with witness data.
*/
public int getWeight() {
final int baseLength;
{
final ByteArrayOutputStream base = new UnsafeByteArrayOutputStream(length < 32 ? 32 : length + 32);
try {
bitcoinSerializeToStream(base, TransactionOptions.NONE);
} catch (IOException e) {
; // Cannot happen, we are serializing to a memory stream
}
baseLength = base.size();
}
final int totalLength;
{
final ByteArrayOutputStream total = new UnsafeByteArrayOutputStream(length < 32 ? 32 : length + 32);
try {
bitcoinSerializeToStream(total, TransactionOptions.WITNESS);
} catch (IOException e) {
; // Cannot happen, we are serializing to a memory stream
}
totalLength = total.size();
}
return baseLength * (WITNESS_SCALE_FACTOR - 1) + totalLength;
}
public int getVirtualTransactionSize() {
return (getWeight() + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;
}
} }
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
package org.bitcoinj.core; package org.bitcoinj.core;
import org.bitcoinj.script.Script; import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptException;
import org.bitcoinj.wallet.DefaultRiskAnalysis; import org.bitcoinj.wallet.DefaultRiskAnalysis;
import org.bitcoinj.wallet.KeyBag; import org.bitcoinj.wallet.KeyBag;
import org.bitcoinj.wallet.RedeemData; import org.bitcoinj.wallet.RedeemData;
...@@ -40,7 +41,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -40,7 +41,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
* can be claimed by the recipient in the input of another transaction. You can imagine a * can be claimed by the recipient in the input of another transaction. You can imagine a
* transaction as being a module which is wired up to others, the inputs of one have to be wired * transaction as being a module which is wired up to others, the inputs of one have to be wired
* to the outputs of another. The exceptions are coinbase transactions, which create new coins.</p> * to the outputs of another. The exceptions are coinbase transactions, which create new coins.</p>
* *
* <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 ChildMessage {
...@@ -213,7 +214,7 @@ public class TransactionInput extends ChildMessage { ...@@ -213,7 +214,7 @@ public class TransactionInput extends ChildMessage {
} }
/** /**
* @return The previous output transaction reference, as an OutPoint structure. This contains the * @return The previous output transaction reference, as an OutPoint structure. This contains the
* 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.
*/ */
public TransactionOutPoint getOutpoint() { public TransactionOutPoint getOutpoint() {
...@@ -238,7 +239,7 @@ public class TransactionInput extends ChildMessage { ...@@ -238,7 +239,7 @@ public class TransactionInput extends ChildMessage {
/** /**
* @param scriptBytes the scriptBytes to set * @param scriptBytes the scriptBytes to set
*/ */
void setScriptBytes(byte[] scriptBytes) { public void setScriptBytes(byte[] scriptBytes) {
unCache(); unCache();
this.scriptSig = null; this.scriptSig = null;
int oldLength = length; int oldLength = length;
......
...@@ -29,13 +29,13 @@ import java.util.Locale; ...@@ -29,13 +29,13 @@ import java.util.Locale;
/** /**
* <p>A VersionMessage holds information exchanged during connection setup with another peer. Most of the fields are not * <p>A VersionMessage holds information exchanged during connection setup with another peer. Most of the fields are not
* particularly interesting. The subVer field, since BIP 14, acts as a User-Agent string would. You can and should * particularly interesting. The subVer field, since BIP 14, acts as a User-Agent string would. You can and should
* append to or change the subVer for your own software so other implementations can identify it, and you can look at * append to or change the subVer for your own software so other implementations can identify it, and you can look at
* the subVer field received from other nodes to see what they are running.</p> * the subVer field received from other nodes to see what they are running.</p>
* *
* <p>After creating yourself a VersionMessage, you can pass it to {@link PeerGroup#setVersionMessage(VersionMessage)} * <p>After creating yourself a VersionMessage, you can pass it to {@link PeerGroup#setVersionMessage(VersionMessage)}
* to ensure it will be used for each new connection.</p> * to ensure it will be used for each new connection.</p>
* *
* <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 VersionMessage extends Message { public class VersionMessage extends Message {
...@@ -49,6 +49,10 @@ public class VersionMessage extends Message { ...@@ -49,6 +49,10 @@ public class VersionMessage extends Message {
public static final int NODE_NETWORK = 1 << 0; public static final int NODE_NETWORK = 1 << 0;
/** A flag that denotes whether the peer supports the getutxos message or not. */ /** A flag that denotes whether the peer supports the getutxos message or not. */
public static final int NODE_GETUTXOS = 1 << 1; public static final int NODE_GETUTXOS = 1 << 1;
/** A service bit used by Bitcoin-ABC to announce Bitcoin Cash nodes. */
public static final int NODE_BITCOIN_CASH = 1 << 5;
/** A service bit used by BTC1 to announce Segwit2x nodes. */
public static final int NODE_SEGWIT2X = 1 << 7;
/** Indicates that a node can be asked for blocks and transactions including witness data. */ /** Indicates that a node can be asked for blocks and transactions including witness data. */
public static final int NODE_WITNESS = 1 << 3; public static final int NODE_WITNESS = 1 << 3;
...@@ -94,7 +98,7 @@ public class VersionMessage extends Message { ...@@ -94,7 +98,7 @@ public class VersionMessage extends Message {