3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 02:35:52 +00:00

Block: Add checkWitnessRoot() to verify the witness root.

This commit is contained in:
Andreas Schildbach 2019-02-22 10:45:40 +01:00
parent b2fed78c09
commit 19e083c017
2 changed files with 31 additions and 0 deletions

View File

@ -28,6 +28,7 @@ import java.io.*;
import java.math.*;
import java.util.*;
import static com.google.common.base.Preconditions.checkState;
import static org.bitcoinj.core.Coin.*;
import static org.bitcoinj.core.Sha256Hash.*;
@ -582,6 +583,32 @@ public class Block extends Message {
}
}
@VisibleForTesting
void checkWitnessRoot() throws VerificationException {
Transaction coinbase = transactions.get(0);
checkState(coinbase.isCoinBase());
Sha256Hash witnessCommitment = coinbase.findWitnessCommitment();
if (witnessCommitment != null) {
byte[] witnessReserved = null;
TransactionWitness witness = coinbase.getInput(0).getWitness();
if (witness.getPushCount() != 1)
throw new VerificationException("Coinbase witness reserved invalid: push count");
witnessReserved = witness.getPush(0);
if (witnessReserved.length != 32)
throw new VerificationException("Coinbase witness reserved invalid: length");
Sha256Hash witnessRootHash = Sha256Hash.twiceOf(getWitnessRoot().getReversedBytes(), witnessReserved);
if (!witnessRootHash.equals(witnessCommitment))
throw new VerificationException("Witness merkle root invalid. Expected " + witnessCommitment.toString()
+ " but got " + witnessRootHash.toString());
} else {
for (Transaction tx : transactions) {
if (tx.hasWitnesses())
throw new VerificationException("Transaction witness found but no witness commitment present");
}
}
}
private Sha256Hash calculateMerkleRoot() {
List<byte[]> tree = buildMerkleTree(false);
return Sha256Hash.wrap(tree.get(tree.size() - 1));

View File

@ -39,6 +39,7 @@ import java.util.EnumSet;
import java.util.List;
import static org.junit.Assert.*;
import static org.bitcoinj.core.Utils.HEX;
public class BlockTest {
private static final NetworkParameters TESTNET = TestNet3Params.get();
@ -272,6 +273,9 @@ public class BlockTest {
coinbase.getWTxId().toString());
Sha256Hash witnessCommitment = coinbase.findWitnessCommitment();
assertEquals("c3c1145d8070a57e433238e42e4c022c1e51ca2a958094af243ae1ee252ca106", witnessCommitment.toString());
byte[] witnessReserved = coinbase.getInput(0).getWitness().getPush(0);
assertEquals("0000000000000000000000000000000000000000000000000000000000000000", HEX.encode(witnessReserved));
block481829.checkWitnessRoot();
}
@Test