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:
parent
1b5252fd61
commit
1a107952b9
@ -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));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user