3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 14:54:15 +00:00

FullPrunedBlockChain: add a runScripts property, defaulting to true. Resolves issue 463.

This commit is contained in:
Mike Hearn 2013-09-30 14:11:33 +02:00
parent e3bcb49c4c
commit ee206537d7
2 changed files with 50 additions and 1 deletions

View File

@ -45,6 +45,9 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
/** Keeps a map of block hashes to StoredBlocks. */
protected final FullPrunedBlockStore blockStore;
// Whether or not to execute scriptPubKeys before accepting a transaction (i.e. check signatures).
private boolean runScripts = true;
/**
* Constructs a BlockChain connected to the given wallet and store. To obtain a {@link Wallet} you can construct
* one from scratch, or you can deserialize a saved wallet from disk using {@link Wallet#loadFromFile(java.io.File)}
@ -94,6 +97,17 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
protected boolean shouldVerifyTransactions() {
return true;
}
/**
* Whether or not to run scripts whilst accepting blocks (i.e. checking signatures, for most transactions).
* If you're accepting data from an untrusted node, such as one found via the P2P network, this should be set
* to true (which is the default). If you're downloading a chain from a node you control, script execution
* is redundant because you know the connected node won't relay bad data to you. In that case it's safe to set
* this to false and obtain a significant speedup.
*/
public void setRunScripts(boolean value) {
this.runScripts = value;
}
//TODO: Remove lots of duplicated code in the two connectTransactions
@ -218,7 +232,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
totalFees = totalFees.add(valueIn.subtract(valueOut));
}
if (!isCoinBase) {
if (!isCoinBase && runScripts) {
// Because correctlySpends modifies transactions, this must come after we are done with tx
FutureTask<VerificationException> future = new FutureTask<VerificationException>(new Verifier(tx, prevOutScripts, enforcePayToScriptHash));
scriptVerificationExecutor.execute(future);

View File

@ -101,6 +101,41 @@ public class FullPrunedBlockChainTest {
}
}
@Test
public void skipScripts() throws Exception {
store = new MemoryFullPrunedBlockStore(params, 10);
chain = new FullPrunedBlockChain(params, store);
// Check that we aren't accidentally leaving any references
// to the full StoredUndoableBlock's lying around (ie memory leaks)
ECKey outKey = new ECKey();
// Build some blocks on genesis block to create a spendable output
Block rollingBlock = params.getGenesisBlock().createNextBlockWithCoinbase(outKey.getPubKey());
chain.add(rollingBlock);
TransactionOutput spendableOutput = rollingBlock.getTransactions().get(0).getOutput(0);
for (int i = 1; i < params.getSpendableCoinbaseDepth(); i++) {
rollingBlock = rollingBlock.createNextBlockWithCoinbase(outKey.getPubKey());
chain.add(rollingBlock);
}
rollingBlock = rollingBlock.createNextBlock(null);
Transaction t = new Transaction(params);
t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), new byte[] {}));
TransactionInput input = t.addInput(spendableOutput);
// Invalid script.
input.setScriptBytes(new byte[]{});
rollingBlock.addTransaction(t);
rollingBlock.solve();
chain.setRunScripts(false);
try {
chain.add(rollingBlock);
} catch (VerificationException e) {
fail();
}
}
@Test
public void testFinalizedBlocks() throws Exception {
final int UNDOABLE_BLOCKS_STORED = 10;