mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-13 10:45:51 +00:00
Correct coinbase height script validation
Changes coinbase height validation to check for the bytes at the start of the coinbase script, and ignore everything after them. The validation then matches Bitcoin Core. Also update error messages to more closely match latest Bitcoin Core.
This commit is contained in:
parent
724cf7de36
commit
4a3d702397
@ -1177,25 +1177,17 @@ public class Transaction extends ChildMessage {
|
|||||||
|
|
||||||
// Check block height is in coinbase input script
|
// Check block height is in coinbase input script
|
||||||
final TransactionInput in = this.getInputs().get(0);
|
final TransactionInput in = this.getInputs().get(0);
|
||||||
final List<ScriptChunk> chunks;
|
final ScriptBuilder builder = new ScriptBuilder();
|
||||||
|
builder.data(ScriptBuilder.createHeightScriptData(height));
|
||||||
try {
|
final byte[] expected = builder.build().getProgram();
|
||||||
final Script scriptSig = in.getScriptSig();
|
final byte[] actual = in.getScriptBytes();
|
||||||
chunks = scriptSig.getChunks();
|
if (actual.length < expected.length) {
|
||||||
} catch(ScriptException e) {
|
throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase.");
|
||||||
throw new VerificationException("Coinbase input script signature is invalid.", e);
|
|
||||||
}
|
}
|
||||||
if (chunks.isEmpty()) {
|
for (int scriptIdx = 0; scriptIdx < expected.length; scriptIdx++) {
|
||||||
throw new VerificationException("Coinbase input script signature is empty.");
|
if (actual[scriptIdx] != expected[scriptIdx]) {
|
||||||
|
throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase.");
|
||||||
}
|
}
|
||||||
final ScriptChunk chunk = chunks.get(0);
|
|
||||||
if (!chunk.isPushData()) {
|
|
||||||
throw new VerificationException("First element of coinbase input script signature is not pushdata.");
|
|
||||||
}
|
|
||||||
final byte[] data = chunk.data;
|
|
||||||
final byte[] expected = ScriptBuilder.createHeightScriptData(height);
|
|
||||||
if (!Arrays.equals(data, expected)) {
|
|
||||||
throw new VerificationException.CoinbaseHeightMismatch("Coinbase height mismatch.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,10 +307,6 @@ public class TransactionTest {
|
|||||||
assertEquals(79, tx1.getMessageSizeForPriorityCalc());
|
assertEquals(79, tx1.getMessageSizeForPriorityCalc());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @throws VerificationException
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCoinbaseHeightCheck() throws VerificationException {
|
public void testCoinbaseHeightCheck() throws VerificationException {
|
||||||
// Coinbase transaction from block 300,000
|
// Coinbase transaction from block 300,000
|
||||||
@ -319,4 +315,22 @@ public class TransactionTest {
|
|||||||
final Transaction transaction = params.getDefaultSerializer().makeTransaction(transactionBytes);
|
final Transaction transaction = params.getDefaultSerializer().makeTransaction(transactionBytes);
|
||||||
transaction.checkCoinBaseHeight(height);
|
transaction.checkCoinBaseHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test a coinbase transaction whose script has nonsense after the block height.
|
||||||
|
* See https://github.com/bitcoinj/bitcoinj/issues/1097
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCoinbaseHeightCheckWithDamagedScript() throws VerificationException {
|
||||||
|
// Coinbase transaction from block 224,430
|
||||||
|
final byte[] transactionBytes = HEX.decode(
|
||||||
|
"010000000100000000000000000000000000000000000000000000000000000000"
|
||||||
|
+ "00000000ffffffff3b03ae6c0300044bd7031a0400000000522cfabe6d6d0000"
|
||||||
|
+ "0000000000b7b8bf0100000068692066726f6d20706f6f6c7365727665726aac"
|
||||||
|
+ "1eeeed88ffffffff01e0587597000000001976a91421c0d001728b3feaf11551"
|
||||||
|
+ "5b7c135e779e9f442f88ac00000000");
|
||||||
|
final int height = 224430;
|
||||||
|
final Transaction transaction = params.getDefaultSerializer().makeTransaction(transactionBytes);
|
||||||
|
transaction.checkCoinBaseHeight(height);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user