Skip to content

Commit

Permalink
Fast parsing for template
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasDorier committed Oct 24, 2014
1 parent f10d35a commit 8ba48fa
Showing 1 changed file with 64 additions and 6 deletions.
70 changes: 64 additions & 6 deletions NBitcoin/StandardScriptTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public enum TxOutType

public class TxNullDataTemplate : ScriptTemplate
{
protected override bool FastCheckScriptPubKey(Script scriptPubKey)
{
var bytes = scriptPubKey.ToRawScript(true);
return bytes.Length >= 1 && bytes[0] == (byte)OpcodeType.OP_RETURN;
}
protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps)
{
var ops = scriptPubKeyOps;
Expand All @@ -32,17 +37,19 @@ protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPu
if(ops.Length == 2)
{
return ops[1].PushData != null && ops[1].PushData.Length <= 40;
throw new NotSupportedException();
}
return true;
}

public byte[] ExtractScriptPubKeyParameters(Script scriptPubKey)
{
if(!FastCheckScriptPubKey(scriptPubKey))
return null;
var ops = scriptPubKey.ToOps().ToArray();
if(!CheckScriptPubKeyCore(scriptPubKey, ops))
if(ops.Length != 2)
return null;
if(ops[1].PushData == null || ops[1].PushData.Length > 40)
return null;
if(ops.Length == 1)
return new byte[0];
return ops[1].PushData;
}

Expand Down Expand Up @@ -156,6 +163,13 @@ public PayToMultiSigTemplateParameters ExtractScriptPubKeyParameters(Script scri
};
}

protected override bool FastCheckScriptSig(Script scriptSig, Script scriptPubKey)
{
var bytes = scriptSig.ToRawScript(true);
return bytes.Length >= 1 &&
bytes[0] == (byte)OpcodeType.OP_0;
}

protected override bool CheckScriptSigCore(Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps)
{
if(!scriptSig.IsPushOnly)
Expand All @@ -179,6 +193,8 @@ protected override bool CheckScriptSigCore(Script scriptSig, Op[] scriptSigOps,

public TransactionSignature[] ExtractScriptSigParameters(Script scriptSig)
{
if(!FastCheckScriptSig(scriptSig, null))
return null;
var ops = scriptSig.ToOps().ToArray();
if(!CheckScriptSigCore(scriptSig, ops, null, null))
return null;
Expand Down Expand Up @@ -249,6 +265,15 @@ public Script GenerateScriptPubKey(Script scriptPubKey)
return GenerateScriptPubKey(scriptPubKey.ID);
}

protected override bool FastCheckScriptPubKey(Script scriptPubKey)
{
var bytes = scriptPubKey.ToRawScript(true);
return
bytes.Length >= 2 &&
bytes[0] == (byte)OpcodeType.OP_HASH160 &&
bytes[1] == 0x14;
}

protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps)
{
var ops = scriptPubKeyOps;
Expand Down Expand Up @@ -332,6 +357,8 @@ public override TxOutType Type

public ScriptId ExtractScriptPubKeyParameters(Script scriptPubKey)
{
if(!FastCheckScriptPubKey(scriptPubKey))
return null;
var ops = scriptPubKey.ToOps().ToArray();
if(!this.CheckScriptPubKeyCore(scriptPubKey, ops))
return null;
Expand Down Expand Up @@ -392,7 +419,7 @@ protected override bool CheckScriptSigCore(Script scriptSig, Op[] scriptSigOps,
if(ops.Length != 1)
return false;

return ops[0].PushData != null;
return ops[0].PushData != null && PubKey.IsValidSize(ops[0].PushData.Length);
}

public override TxOutType Type
Expand All @@ -408,7 +435,14 @@ public PubKey ExtractScriptPubKeyParameters(Script script)
var ops = script.ToOps().ToArray();
if(!CheckScriptPubKeyCore(script, ops))
return null;
return new PubKey(ops[0].PushData);
try
{
return new PubKey(ops[0].PushData);
}
catch(FormatException)
{
return null;
}
}


Expand Down Expand Up @@ -464,6 +498,15 @@ public Script GenerateScriptSig(TransactionSignature signature, PubKey publicKey
);
}

protected override bool FastCheckScriptPubKey(Script scriptPubKey)
{
var bytes = scriptPubKey.ToRawScript(true);
return bytes.Length >= 3 &&
bytes[0] == (byte)OpcodeType.OP_DUP &&
bytes[1] == (byte)OpcodeType.OP_HASH160 &&
bytes[2] == 0x14;
}

protected override bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps)
{
var ops = scriptPubKeyOps;
Expand Down Expand Up @@ -534,17 +577,32 @@ public bool CheckScriptPubKey(Script scriptPubKey)
{
if(scriptPubKey == null)
throw new ArgumentNullException("scriptPubKey");
if(!FastCheckScriptPubKey(scriptPubKey))
return false;
return CheckScriptPubKeyCore(scriptPubKey, scriptPubKey.ToOps().ToArray());
}

protected virtual bool FastCheckScriptPubKey(Script scriptPubKey)
{
return true;
}

protected abstract bool CheckScriptPubKeyCore(Script scriptPubKey, Op[] scriptPubKeyOps);
public bool CheckScriptSig(Script scriptSig, Script scriptPubKey)
{
if(scriptSig == null)
throw new ArgumentNullException("scriptSig");

if(!FastCheckScriptSig(scriptSig, scriptPubKey))
return false;
return CheckScriptSigCore(scriptSig, scriptSig.ToOps().ToArray(), scriptPubKey, scriptPubKey == null ? null : scriptPubKey.ToOps().ToArray());
}

protected virtual bool FastCheckScriptSig(Script scriptSig, Script scriptPubKey)
{
return true;
}

protected abstract bool CheckScriptSigCore(Script scriptSig, Op[] scriptSigOps, Script scriptPubKey, Op[] scriptPubKeyOps);
public abstract TxOutType Type
{
Expand Down

0 comments on commit 8ba48fa

Please sign in to comment.