3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-12 02:05:53 +00:00

Reformatting of comments to 120 cols.

This commit is contained in:
Mike Hearn 2011-12-29 13:32:54 +00:00
parent 1b5252fd61
commit 1a107952b9

View File

@ -33,16 +33,12 @@ import static com.google.bitcoin.core.Utils.doubleDigest;
import static com.google.bitcoin.core.Utils.doubleDigestTwoBuffers; import static com.google.bitcoin.core.Utils.doubleDigestTwoBuffers;
/** /**
* A block is the foundation of the BitCoin system. It records a set of * A block is the foundation of the BitCoin system. It records a set of {@link Transaction}s together with some data
* {@link Transaction}s together with some data that links it into a place in * that links it into a place in the global block chain, and proves that a difficult calculation was done over its
* the global block chain, and proves that a difficult calculation was done over * contents. See the BitCoin technical paper for more detail on blocks. <p/>
* its contents. See the BitCoin technical paper for more detail on blocks. *
* <p/> * To get a block, you can either build one from the raw bytes you can get from another implementation, or request one
* <p/> * specifically using {@link Peer#getBlock(Sha256Hash)}, or grab one from a downloaded {@link BlockChain}.
* To get a block, you can either build one from the raw bytes you can get from
* another implementation, or request one specifically using
* {@link Peer#getBlock(Sha256Hash)}, or grab one from a downloaded
* {@link BlockChain}.
*/ */
public class Block extends Message { public class Block extends Message {
private static final Logger log = LoggerFactory.getLogger(Block.class); private static final Logger log = LoggerFactory.getLogger(Block.class);
@ -53,10 +49,7 @@ public class Block extends Message {
static final long ALLOWED_TIME_DRIFT = 2 * 60 * 60; // Same value as official client. static final long ALLOWED_TIME_DRIFT = 2 * 60 * 60; // Same value as official client.
/** /** A value for difficultyTarget (nBits) that allows half of all possible hash solutions. Used in unit testing. */
* A value for difficultyTarget (nBits) that allows half of all possible
* hash solutions. Used in unit testing.
*/
static final long EASIEST_DIFFICULTY_TARGET = 0x207fFFFFL; static final long EASIEST_DIFFICULTY_TARGET = 0x207fFFFFL;
// For unit testing. If not zero, use this instead of the current time. // For unit testing. If not zero, use this instead of the current time.
@ -82,10 +75,7 @@ public class Block extends Message {
private transient boolean headerBytesValid; private transient boolean headerBytesValid;
private transient boolean transactionBytesValid; private transient boolean transactionBytesValid;
/** /** Special case constructor, used for the genesis node, cloneAsHeader and unit tests. */
* Special case constructor, used for the genesis node, cloneAsHeader and
* unit tests.
*/
Block(NetworkParameters params) { Block(NetworkParameters params) {
super(params); super(params);
// Set up a few basic things. We are not complete after this though. // Set up a few basic things. We are not complete after this though.
@ -122,10 +112,8 @@ public class Block extends Message {
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
ois.defaultReadObject(); ois.defaultReadObject();
// This code is not actually necessary, as transient fields are // This code is not actually necessary, as transient fields are initialized to the default value which is in
// initialized to the default value which is in // this case null. However it clears out a FindBugs warning and makes it explicit what we're doing.
// this case null. However it clears out a FindBugs warning and makes it
// explicit what we're doing.
hash = null; hash = null;
} }
@ -168,11 +156,8 @@ public class Block extends Message {
transactions.add(tx); transactions.add(tx);
cursor += tx.getMessageSize(); cursor += tx.getMessageSize();
} }
// no need to set length here. If length was not provided then it should // No need to set length here. If length was not provided then it should be set at the end of parseLight().
// be set at the end // If this is a genuine lazy parse then length must have been provided to the constructor.
// of parseLight(). If this is a genuine lazy parse then length must
// have been provided to
// the constructor.
transactionsParsed = true; transactionsParsed = true;
transactionBytesValid = parseRetain; transactionBytesValid = parseRetain;
} }
@ -184,11 +169,11 @@ public class Block extends Message {
} }
protected void parseLite() throws ProtocolException { protected void parseLite() throws ProtocolException {
// ignore the header since it has fixed length. If length is not // Ignore the header since it has fixed length. If length is not provided we will have to
// provided we will have to
// invoke a light parse of transactions to calculate the length. // invoke a light parse of transactions to calculate the length.
if (length == UNKNOWN_LENGTH) { if (length == UNKNOWN_LENGTH) {
assert !parseLazy : "Performing lite parse of block transaction as block was initialised from byte array without providing length. This should never need to happen." + " parseLazy: " + parseLazy; assert !parseLazy : "Performing lite parse of block transaction as block was initialised from byte array " +
"without providing length. This should never need to happen. parseLazy: " + parseLazy;
parseTransactions(); parseTransactions();
length = cursor - offset; length = cursor - offset;
} else { } else {
@ -198,19 +183,16 @@ public class Block extends Message {
} }
/* /*
* Block uses some special handling for lazy parsing and retention of cached * Block uses some special handling for lazy parsing and retention of cached bytes. Parsing and serializing the
* bytes. Parsing and serializing the block header and the transaction list * block header and the transaction list are both non-trivial so there are good efficiency gains to be had by
* are both non-trivial so there are good efficiency gains to be had by * separating them. There are many cases where a user may need access to access or change one or the other but not both.
* separating them. There are many cases where a user may need access to
* access or change one or the other but not both.
* *
* With this in mind we ignore the inherited checkParse() and unCache() * With this in mind we ignore the inherited checkParse() and unCache() methods and implement a separate version
* methods and implement a separate version of them for both header and transactions. * of them for both header and transactions.
* *
* Serializing methods are also handled in their own way. Whilst they deal * Serializing methods are also handled in their own way. Whilst they deal with separate parts of the block structure
* with separate parts of the block structure there are some * there are some interdependencies. For example altering a tx requires invalidating the Merkle root and therefore
* interdependencies. For example altering a tx requires invalidating the * the cached header bytes.
* Merkle root and therefore the cached header bytes.
*/ */
private synchronized void maybeParseHeader() { private synchronized void maybeParseHeader() {
if (headerParsed || bytes == null) if (headerParsed || bytes == null)
@ -238,9 +220,8 @@ public class Block extends Message {
} }
/** /**
* Ensure the object is parsed if needed. This should be called in every * Ensure the object is parsed if needed. This should be called in every getter before returning a value. If the
* getter before returning a value. If the lazy parse flag is not set this * lazy parse flag is not set this is a method returns immediately.
* is a method returns immediately.
*/ */
protected synchronized void maybeParse() { protected synchronized void maybeParse() {
throw new LazyParseException( throw new LazyParseException(
@ -248,9 +229,10 @@ public class Block extends Message {
} }
/** /**
* In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed safe access is required * In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed
* this method will force parsing to occur immediately thus ensuring LazyParseExeption will never be thrown from this Message. * safe access is required this method will force parsing to occur immediately thus ensuring LazyParseExeption will
* If the Message contains child messages (e.g. a Block containing Transaction messages) this will not force child messages to parse. * never be thrown from this Message. If the Message contains child messages (e.g. a Block containing Transaction
* messages) this will not force child messages to parse.
* *
* This method ensures parsing of both headers and transactions. * This method ensures parsing of both headers and transactions.
* *
@ -268,9 +250,10 @@ public class Block extends Message {
} }
/** /**
* In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed safe access is required * In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed
* this method will force parsing to occur immediately thus ensuring LazyParseExeption will never be thrown from this Message. * safe access is required this method will force parsing to occur immediately thus ensuring LazyParseExeption
* If the Message contains child messages (e.g. a Block containing Transaction messages) this will not force child messages to parse. * will never be thrown from this Message. If the Message contains child messages (e.g. a Block containing
* Transaction messages) this will not force child messages to parse.
* *
* This method ensures parsing of headers only. * This method ensures parsing of headers only.
* *
@ -287,9 +270,10 @@ public class Block extends Message {
} }
/** /**
* In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed safe access is required * In lazy parsing mode access to getters and setters may throw an unchecked LazyParseException. If guaranteed
* this method will force parsing to occur immediately thus ensuring LazyParseExeption will never be thrown from this Message. * safe access is required this method will force parsing to occur immediately thus ensuring LazyParseExeption will
* If the Message contains child messages (e.g. a Block containing Transaction messages) this will not force child messages to parse. * never be thrown from this Message. If the Message contains child messages (e.g. a Block containing Transaction
* messages) this will not force child messages to parse.
* *
* This method ensures parsing of transactions only. * This method ensures parsing of transactions only.
* *
@ -384,11 +368,11 @@ public class Block extends Message {
/** /**
* Provides a reasonable guess at the byte length of the transactions part of the block. * Provides a reasonable guess at the byte length of the transactions part of the block.
* The returned value will be accurate in 99% of cases and in those cases where not will probably * The returned value will be accurate in 99% of cases and in those cases where not will probably slightly
* slightly oversize. * oversize.
* *
* This is used to preallocate the underlying byte array for a ByteArrayOutputStream. If the size * This is used to preallocate the underlying byte array for a ByteArrayOutputStream. If the size is under the
* is under the real value the only penalty is resizing of the underlying byte array. * real value the only penalty is resizing of the underlying byte array.
*/ */
private int guessTransactionsLength() { private int guessTransactionsLength() {
if (transactionBytesValid) if (transactionBytesValid)
@ -404,10 +388,8 @@ public class Block extends Message {
} }
protected void unCache() { protected void unCache() {
// Since we have alternate uncache methods to use internally this will // Since we have alternate uncache methods to use internally this will only ever be called by a child
// only ever be called // transaction so we only need to invalidate that part of the cache.
// by a child transaction so we only need to invalidate that part of the
// cache.
unCacheTransactions(); unCacheTransactions();
} }
@ -425,14 +407,11 @@ public class Block extends Message {
transactionBytesValid = false; transactionBytesValid = false;
if (!headerBytesValid) if (!headerBytesValid)
bytes = null; bytes = null;
// current implementation has to uncache headers as well as any change // Current implementation has to uncache headers as well as any change to a tx will alter the merkle root. In
// to a tx // future we can go more granular and cache merkle root separately so rest of the header does not need to be
// will alter the merkle root. In future we can go more granular and // rewritten.
// cache merkle root
// Separately so rest of the header does not need to be rewritten
unCacheHeader(); unCacheHeader();
// clear merkleRoot last as it may end up being parsed during // Clear merkleRoot last as it may end up being parsed during unCacheHeader().
// unCacheHeader().
merkleRoot = null; merkleRoot = null;
} }
@ -451,10 +430,9 @@ public class Block extends Message {
} }
/** /**
* Returns the hash of the block (which for a valid, solved block should be * Returns the hash of the block (which for a valid, solved block should be below the target) in the form seen on
* below the target) in the form seen on the block explorer. If you call * the block explorer. If you call this on block 1 in the production chain
* this on block 1 in the production chain, you will get * you will get "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048".
* "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048".
*/ */
public String getHashAsString() { public String getHashAsString() {
return getHash().toString(); return getHash().toString();
@ -524,13 +502,11 @@ public class Block extends Message {
} }
/** /**
* Finds a value of nonce that makes the blocks hash lower than the * Finds a value of nonce that makes the blocks hash lower than the difficulty target. This is called mining, but
* difficulty target. This is called mining, but solve() is far too slow to * solve() is far too slow to do real mining with. It exists only for unit testing purposes and is not a part of
* do real mining with. It exists only for unit testing purposes and is not * the public API.
* a part of the public API.
* *
* This can loop forever if a solution cannot be found solely by * This can loop forever if a solution cannot be found solely by incrementing nonce. It doesn't change extraNonce.
* incrementing nonce. It doesn't change extraNonce.
*/ */
void solve() { void solve() {
maybeParseHeader(); maybeParseHeader();
@ -548,9 +524,8 @@ public class Block extends Message {
} }
/** /**
* Returns the difficulty target as a 256 bit value that can be compared to * Returns the difficulty target as a 256 bit value that can be compared to a SHA-256 hash. Inside a block the
* a SHA-256 hash. Inside a block the target is represented using a compact * target is represented using a compact form. If this form decodes to a value that is out of bounds, an exception
* form. If this form decodes to a value that is out of bounds, an exception
* is thrown. * is thrown.
*/ */
public BigInteger getDifficultyTargetAsInteger() throws VerificationException { public BigInteger getDifficultyTargetAsInteger() throws VerificationException {
@ -561,25 +536,16 @@ public class Block extends Message {
return target; return target;
} }
/** /** Returns true if the hash of the block is OK (lower than difficulty target). */
* Returns true if the hash of the block is OK (lower than difficulty
* target).
*/
private boolean checkProofOfWork(boolean throwException) throws VerificationException { private boolean checkProofOfWork(boolean throwException) throws VerificationException {
// This part is key - it is what proves the block was as difficult to // This part is key - it is what proves the block was as difficult to make as it claims
// make as it claims // to be. Note however that in the context of this function, the block can claim to be
// to be. Note however that in the context of this function, the block // as difficult as it wants to be .... if somebody was able to take control of our network
// can claim to be // connection and fork us onto a different chain, they could send us valid blocks with
// as difficult as it wants to be .... if somebody was able to take
// control of our network
// connection and fork us onto a different chain, they could send us
// valid blocks with
// ridiculously easy difficulty and this function would accept them. // ridiculously easy difficulty and this function would accept them.
// //
// To prevent this attack from being possible, elsewhere we check that // To prevent this attack from being possible, elsewhere we check that the difficultyTarget
// the difficultyTarget // field is of the right value. This requires us to have the preceeding blocks.
// field is of the right value. This requires us to have the preceeding
// blocks.
BigInteger target = getDifficultyTargetAsInteger(); BigInteger target = getDifficultyTargetAsInteger();
BigInteger h = getHash().toBigInteger(); BigInteger h = getHash().toBigInteger();
@ -616,8 +582,7 @@ public class Block extends Message {
} }
private List<byte[]> buildMerkleTree() { private List<byte[]> buildMerkleTree() {
// The Merkle root is based on a tree of hashes calculated from the // The Merkle root is based on a tree of hashes calculated from the transactions:
// transactions:
// //
// root // root
// / \ // / \
@ -628,24 +593,16 @@ public class Block extends Message {
// The tree is represented as a list: t1,t2,t3,t4,A,B,root where each // The tree is represented as a list: t1,t2,t3,t4,A,B,root where each
// entry is a hash. // entry is a hash.
// //
// The hashing algorithm is double SHA-256. The leaves are a hash of the // The hashing algorithm is double SHA-256. The leaves are a hash of the serialized contents of the transaction.
// serialized contents of the // The interior nodes are hashes of the concenation of the two child hashes.
// transaction. The interior nodes are hashes of the concenation of the
// two child hashes.
// //
// This structure allows the creation of proof that a transaction was // This structure allows the creation of proof that a transaction was included into a block without having to
// included into a block without having to // provide the full block contents. Instead, you can provide only a Merkle branch. For example to prove tx2 was
// provide the full block contents. Instead, you can provide only a // in a block you can just provide tx2, the hash(tx1) and B. Now the other party has everything they need to
// Merkle branch. For example to prove tx2 was // derive the root, which can be checked against the block header. These proofs aren't used right now but
// in a block you can just provide tx2, the hash(tx1) and B. Now the // will be helpful later when we want to download partial block contents.
// other party has everything they need to
// derive the root, which can be checked against the block header. These
// proofs aren't used right now but
// will be helpful later when we want to download partial block
// contents.
// //
// Note that if the number of transactions is not even the last tx is // Note that if the number of transactions is not even the last tx is repeated to make it so (see
// repeated to make it so (see
// tx3 above). A tree with 5 transactions would look like this: // tx3 above). A tree with 5 transactions would look like this:
// //
// root // root
@ -657,20 +614,16 @@ public class Block extends Message {
// t1 t2 t3 t4 t5 t5 // t1 t2 t3 t4 t5 t5
maybeParseTransactions(); maybeParseTransactions();
ArrayList<byte[]> tree = new ArrayList<byte[]>(); ArrayList<byte[]> tree = new ArrayList<byte[]>();
// Start by adding all the hashes of the transactions as leaves of the // Start by adding all the hashes of the transactions as leaves of the tree.
// tree.
for (Transaction t : transactions) { for (Transaction t : transactions) {
tree.add(t.getHash().getBytes()); tree.add(t.getHash().getBytes());
} }
int levelOffset = 0; // Offset in the list where the currently processed int levelOffset = 0; // Offset in the list where the currently processed level starts.
// level starts. // Step through each level, stopping when we reach the root (levelSize == 1).
// Step through each level, stopping when we reach the root (levelSize
// == 1).
for (int levelSize = transactions.size(); levelSize > 1; levelSize = (levelSize + 1) / 2) { for (int levelSize = transactions.size(); levelSize > 1; levelSize = (levelSize + 1) / 2) {
// For each pair of nodes on that level: // For each pair of nodes on that level:
for (int left = 0; left < levelSize; left += 2) { for (int left = 0; left < levelSize; left += 2) {
// The right hand node can be the same as the left hand, in the // The right hand node can be the same as the left hand, in the case where we don't have enough
// case where we don't have enough
// transactions. // transactions.
int right = Math.min(left + 1, levelSize - 1); int right = Math.min(left + 1, levelSize - 1);
byte[] leftBytes = Utils.reverseBytes(tree.get(levelOffset + left)); byte[] leftBytes = Utils.reverseBytes(tree.get(levelOffset + left));
@ -684,8 +637,7 @@ public class Block extends Message {
} }
private void checkTransactions() throws VerificationException { private void checkTransactions() throws VerificationException {
// The first transaction in a block must always be a coinbase // The first transaction in a block must always be a coinbase transaction.
// transaction.
if (!transactions.get(0).isCoinBase()) if (!transactions.get(0).isCoinBase())
throw new VerificationException("First tx is not coinbase"); throw new VerificationException("First tx is not coinbase");
// The rest must not be. // The rest must not be.
@ -696,23 +648,18 @@ public class Block extends Message {
} }
/** /**
* Checks the block data to ensure it follows the rules laid out in the * Checks the block data to ensure it follows the rules laid out in the network parameters. Specifically,
* network parameters. Specifically, throws an exception if the proof of * throws an exception if the proof of work is invalid, or if the timestamp is too far from what it should be.
* work is invalid, or if the timestamp is too far from what it should be. * This is <b>not</b> everything that is required for a block to be valid, only what is checkable independent
* This is <b>not</b> everything that is required for a block to be valid, * of the chain and without a transaction index.
* only what is checkable independent of the chain and without a transaction
* index.
* *
* @throws VerificationException * @throws VerificationException
*/ */
public void verifyHeader() throws VerificationException { public void verifyHeader() throws VerificationException {
// Prove that this block is OK. It might seem that we can just ignore // Prove that this block is OK. It might seem that we can just ignore most of these checks given that the
// most of these checks given that the // network is also verifying the blocks, but we cannot as it'd open us to a variety of obscure attacks.
// network is also verifying the blocks, but we cannot as it'd open us
// to a variety of obscure attacks.
// //
// Firstly we need to ensure this block does in fact represent real work // Firstly we need to ensure this block does in fact represent real work done. If the difficulty is high
// done. If the difficulty is high
// enough, it's probably been done by the network. // enough, it's probably been done by the network.
maybeParseHeader(); maybeParseHeader();
checkProofOfWork(true); checkProofOfWork(true);
@ -725,12 +672,9 @@ public class Block extends Message {
* @throws VerificationException * @throws VerificationException
*/ */
public void verifyTransactions() throws VerificationException { public void verifyTransactions() throws VerificationException {
// Now we need to check that the body of the block actually matches the // Now we need to check that the body of the block actually matches the headers. The network won't generate
// headers. The network won't generate // an invalid block, but if we didn't validate this then an untrusted man-in-the-middle could obtain the next
// an invalid block, but if we didn't validate this then an untrusted // valid block from the network and simply replace the transactions in it with their own fictional
// man-in-the-middle could obtain the next
// valid block from the network and simply replace the transactions in
// it with their own fictional
// transactions that reference spent or non-existant inputs. // transactions that reference spent or non-existant inputs.
assert transactions.size() > 0; assert transactions.size() > 0;
maybeParseTransactions(); maybeParseTransactions();
@ -739,8 +683,7 @@ public class Block extends Message {
} }
/** /**
* Verifies both the header and that the transactions hash to the merkle * Verifies both the header and that the transactions hash to the merkle root.
* root.
*/ */
public void verify() throws VerificationException { public void verify() throws VerificationException {
verifyHeader(); verifyHeader();
@ -761,8 +704,7 @@ public class Block extends Message {
} }
/** /**
* Returns the merkle root in big endian form, calculating it from * Returns the merkle root in big endian form, calculating it from transactions if necessary.
* transactions if necessary.
*/ */
public Sha256Hash getMerkleRoot() { public Sha256Hash getMerkleRoot() {
maybeParseHeader(); maybeParseHeader();
@ -797,18 +739,14 @@ public class Block extends Message {
hash = null; hash = null;
} }
/** /** Returns the version of the block data structure as defined by the BitCoin protocol. */
* Returns the version of the block data structure as defined by the BitCoin
* protocol.
*/
public long getVersion() { public long getVersion() {
maybeParseHeader(); maybeParseHeader();
return version; return version;
} }
/** /**
* Returns the hash of the previous block in the chain, as defined by the * Returns the hash of the previous block in the chain, as defined by the block header.
* block header.
*/ */
public Sha256Hash getPrevBlockHash() { public Sha256Hash getPrevBlockHash() {
maybeParseHeader(); maybeParseHeader();
@ -822,9 +760,8 @@ public class Block extends Message {
} }
/** /**
* Returns the time at which the block was solved and broadcast, according * Returns the time at which the block was solved and broadcast, according to the clock of the solving node. This
* to the clock of the solving node. This is measured in seconds since the * is measured in seconds since the UNIX epoch (midnight Jan 1st 1970).
* UNIX epoch (midnight Jan 1st 1970).
*/ */
public long getTimeSeconds() { public long getTimeSeconds() {
maybeParseHeader(); maybeParseHeader();
@ -838,11 +775,9 @@ public class Block extends Message {
} }
/** /**
* Returns the difficulty of the proof of work that this block should meet * Returns the difficulty of the proof of work that this block should meet encoded in compact form. The {@link
* encoded in compact form. The {@link BlockChain} verifies that this is not * BlockChain} verifies that this is not too easy by looking at the length of the chain when the block is added.
* too easy by looking at the length of the chain when the block is added. * To find the actual value the hash should be compared against, use getDifficultyTargetBI.
* To find the actual value the hash should be compared against, use
* getDifficultyTargetBI.
*/ */
public long getDifficultyTarget() { public long getDifficultyTarget() {
maybeParseHeader(); maybeParseHeader();
@ -856,8 +791,8 @@ public class Block extends Message {
} }
/** /**
* Returns the nonce, an arbitrary value that exists only to make the hash * Returns the nonce, an arbitrary value that exists only to make the hash of the block header fall below the
* of the block header fall below the difficulty target. * difficulty target.
*/ */
public long getNonce() { public long getNonce() {
maybeParseHeader(); maybeParseHeader();
@ -886,13 +821,10 @@ public class Block extends Message {
unCacheTransactions(); unCacheTransactions();
transactions = new ArrayList<Transaction>(); transactions = new ArrayList<Transaction>();
Transaction coinbase = new Transaction(params); Transaction coinbase = new Transaction(params);
// A real coinbase transaction has some stuff in the scriptSig like the // A real coinbase transaction has some stuff in the scriptSig like the extraNonce and difficulty. The
// extraNonce and difficulty. The // transactions are distinguished by every TX output going to a different key.
// transactions are distinguished by every TX output going to a
// different key.
// //
// Here we will do things a bit differently so a new address isn't // Here we will do things a bit differently so a new address isn't needed every time. We'll put a simple
// needed every time. We'll put a simple
// counter in the scriptSig so every transaction has a different hash. // counter in the scriptSig so every transaction has a different hash.
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) txCounter++})); coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) txCounter++}));
coinbase.addOutput(new TransactionOutput(params, coinbase, Script.createOutputScript(pubKeyTo))); coinbase.addOutput(new TransactionOutput(params, coinbase, Script.createOutputScript(pubKeyTo)));
@ -902,8 +834,7 @@ public class Block extends Message {
static final byte[] EMPTY_BYTES = new byte[32]; static final byte[] EMPTY_BYTES = new byte[32];
/** /**
* Returns a solved block that builds on top of this one. This exists for * Returns a solved block that builds on top of this one. This exists for unit tests.
* unit tests.
*/ */
Block createNextBlock(Address to, long time) { Block createNextBlock(Address to, long time) {
Block b = new Block(params); Block b = new Block(params);
@ -913,13 +844,10 @@ public class Block extends Message {
// Add a transaction paying 50 coins to the "to" address. // Add a transaction paying 50 coins to the "to" address.
Transaction t = new Transaction(params); Transaction t = new Transaction(params);
t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), to)); t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), to));
// The input does not really need to be a valid signature, as long as it // The input does not really need to be a valid signature, as long as it has the right general form.
// has the right general form.
TransactionInput input = new TransactionInput(params, t, Script.createInputScript(EMPTY_BYTES, EMPTY_BYTES)); TransactionInput input = new TransactionInput(params, t, Script.createInputScript(EMPTY_BYTES, EMPTY_BYTES));
// Importantly the outpoint hash cannot be zero as that's how we detect // Importantly the outpoint hash cannot be zero as that's how we detect a coinbase transaction in isolation
// a coinbase transaction in isolation // but it must be unique to avoid 'different' transactions looking the same.
// but it must be unique to avoid 'different' transactions looking the
// same.
byte[] counter = new byte[32]; byte[] counter = new byte[32];
counter[0] = (byte) txCounter++; counter[0] = (byte) txCounter++;
input.getOutpoint().setHash(new Sha256Hash(counter)); input.getOutpoint().setHash(new Sha256Hash(counter));