mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-13 02:35:52 +00:00
Block: Add getWitnessRoot() to calculate the witness root hash, similar to the merkle root hash.
This commit is contained in:
parent
11e4cb956e
commit
b2fed78c09
@ -92,7 +92,7 @@ public class Block extends Message {
|
||||
// Fields defined as part of the protocol format.
|
||||
private long version;
|
||||
private Sha256Hash prevBlockHash;
|
||||
private Sha256Hash merkleRoot;
|
||||
private Sha256Hash merkleRoot, witnessRoot;
|
||||
private long time;
|
||||
private long difficultyTarget; // "nBits"
|
||||
private long nonce;
|
||||
@ -484,11 +484,12 @@ public class Block extends Message {
|
||||
s.append(" (").append(bips).append(')');
|
||||
s.append('\n');
|
||||
s.append(" previous block: ").append(getPrevBlockHash()).append("\n");
|
||||
s.append(" merkle root: ").append(getMerkleRoot()).append("\n");
|
||||
s.append(" time: ").append(time).append(" (").append(Utils.dateTimeFormat(time * 1000)).append(")\n");
|
||||
s.append(" difficulty target (nBits): ").append(difficultyTarget).append("\n");
|
||||
s.append(" nonce: ").append(nonce).append("\n");
|
||||
if (transactions != null && transactions.size() > 0) {
|
||||
s.append(" merkle root: ").append(getMerkleRoot()).append("\n");
|
||||
s.append(" witness root: ").append(getWitnessRoot()).append("\n");
|
||||
s.append(" with ").append(transactions.size()).append(" transaction(s):\n");
|
||||
for (Transaction tx : transactions) {
|
||||
s.append(tx).append('\n');
|
||||
@ -582,11 +583,16 @@ public class Block extends Message {
|
||||
}
|
||||
|
||||
private Sha256Hash calculateMerkleRoot() {
|
||||
List<byte[]> tree = buildMerkleTree();
|
||||
List<byte[]> tree = buildMerkleTree(false);
|
||||
return Sha256Hash.wrap(tree.get(tree.size() - 1));
|
||||
}
|
||||
|
||||
private List<byte[]> buildMerkleTree() {
|
||||
private Sha256Hash calculateWitnessRoot() {
|
||||
List<byte[]> tree = buildMerkleTree(true);
|
||||
return Sha256Hash.wrap(tree.get(tree.size() - 1));
|
||||
}
|
||||
|
||||
private List<byte[]> buildMerkleTree(boolean useWTxId) {
|
||||
// The Merkle root is based on a tree of hashes calculated from the transactions:
|
||||
//
|
||||
// root
|
||||
@ -617,10 +623,15 @@ public class Block extends Message {
|
||||
// 2 3 4 4
|
||||
// / \ / \ / \
|
||||
// t1 t2 t3 t4 t5 t5
|
||||
ArrayList<byte[]> tree = new ArrayList<>();
|
||||
ArrayList<byte[]> tree = new ArrayList<>(transactions.size());
|
||||
// Start by adding all the hashes of the transactions as leaves of the tree.
|
||||
for (Transaction t : transactions) {
|
||||
tree.add(t.getTxId().getBytes());
|
||||
for (Transaction tx : transactions) {
|
||||
final Sha256Hash id;
|
||||
if (useWTxId && tx.isCoinBase())
|
||||
id = Sha256Hash.ZERO_HASH;
|
||||
else
|
||||
id = useWTxId ? tx.getWTxId() : tx.getTxId();
|
||||
tree.add(id.getBytes());
|
||||
}
|
||||
int levelOffset = 0; // Offset in the list where the currently processed level starts.
|
||||
// Step through each level, stopping when we reach the root (levelSize == 1).
|
||||
@ -749,6 +760,15 @@ public class Block extends Message {
|
||||
hash = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the witness root in big endian form, calculating it from transactions if necessary.
|
||||
*/
|
||||
public Sha256Hash getWitnessRoot() {
|
||||
if (witnessRoot == null)
|
||||
witnessRoot = calculateWitnessRoot();
|
||||
return witnessRoot;
|
||||
}
|
||||
|
||||
/** Adds a transaction to this block. The nonce and merkle root are invalid after this. */
|
||||
public void addTransaction(Transaction t) {
|
||||
addTransaction(t, true);
|
||||
|
@ -240,6 +240,14 @@ public class BlockTest {
|
||||
Block block481815 = MAINNET.getDefaultSerializer()
|
||||
.makeBlock(ByteStreams.toByteArray(getClass().getResourceAsStream("block481815.dat")));
|
||||
assertEquals(2097, block481815.getTransactions().size());
|
||||
assertEquals("f115afa8134171a0a686bfbe9667b60ae6fb5f6a439e0265789babc315333262",
|
||||
block481815.getMerkleRoot().toString());
|
||||
|
||||
// This block has no witnesses.
|
||||
for (Transaction tx : block481815.getTransactions())
|
||||
assertFalse(tx.hasWitnesses());
|
||||
|
||||
// Nevertheless, there is a witness commitment (but no witness reserved).
|
||||
Transaction coinbase = block481815.getTransactions().get(0);
|
||||
assertEquals("919a0df2253172a55bebcb9002dbe775b8511f84955b282ca6dae826fdd94f90", coinbase.getTxId().toString());
|
||||
assertEquals("919a0df2253172a55bebcb9002dbe775b8511f84955b282ca6dae826fdd94f90",
|
||||
@ -253,6 +261,11 @@ public class BlockTest {
|
||||
Block block481829 = MAINNET.getDefaultSerializer()
|
||||
.makeBlock(ByteStreams.toByteArray(getClass().getResourceAsStream("block481829.dat")));
|
||||
assertEquals(2020, block481829.getTransactions().size());
|
||||
assertEquals("f06f697be2cac7af7ed8cd0b0b81eaa1a39e444c6ebd3697e35ab34461b6c58d",
|
||||
block481829.getMerkleRoot().toString());
|
||||
assertEquals("0a02ddb2f86a14051294f8d98dd6959dd12bf3d016ca816c3db9b32d3e24fc2d",
|
||||
block481829.getWitnessRoot().toString());
|
||||
|
||||
Transaction coinbase = block481829.getTransactions().get(0);
|
||||
assertEquals("9c1ab453283035800c43eb6461eb46682b81be110a0cb89ee923882a5fd9daa4", coinbase.getTxId().toString());
|
||||
assertEquals("2bbda73aa4e561e7f849703994cc5e563e4bcf103fb0f6fef5ae44c95c7b83a6",
|
||||
|
Loading…
x
Reference in New Issue
Block a user