Skip to content

Commit a45758e

Browse files
authored
Fix GetSigOpCount and revert earlier workaround (#493)
* Fix GetSigOpCount and revert earlier workaround * Add network argument * Add network argument
1 parent 55c4986 commit a45758e

File tree

4 files changed

+30
-11
lines changed

4 files changed

+30
-11
lines changed

src/NBitcoin.Tests/sigopcount_tests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using Moq;
23
using Stratis.Bitcoin.Tests.Common;
34
using Xunit;
45

@@ -39,5 +40,24 @@ public void GetSigOpCount()
3940
scriptSig2 = scriptSig2 + OpcodeType.OP_1 + dummy.ToBytes() + dummy.ToBytes() + s2.ToBytes();
4041
Assert.Equal(3U, p2sh.GetSigOpCount(KnownNetworks.Main, scriptSig2));
4142
}
43+
44+
[Fact]
45+
[Trait("Core", "Core")]
46+
public void GetSigOpCountForFederation()
47+
{
48+
PubKey[] keys = Enumerable.Range(0, 3).Select(_ => new Key(true).PubKey).ToArray();
49+
var federations = new Federations();
50+
federations.RegisterFederation(new Federation(keys.Take(2), 1));
51+
var network = KnownNetworks.StraxRegTest;
52+
network.SetPrivatePropertyValue("Federations", federations);
53+
54+
// Test CScript::GetSigOpCount()
55+
var s1 = new Script();
56+
s1 = s1 + OpcodeType.OP_1 + OpcodeType.OP_FEDERATION + OpcodeType.OP_CHECKMULTISIG;
57+
Assert.Equal(2U, s1.GetSigOpCount(true, network));
58+
s1 = s1 + OpcodeType.OP_IF + OpcodeType.OP_CHECKSIG + OpcodeType.OP_ENDIF;
59+
Assert.Equal(3U, s1.GetSigOpCount(true, network));
60+
Assert.Equal(21U, s1.GetSigOpCount(false, network));
61+
}
4262
}
4363
}

src/NBitcoin/Script.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ public IList<Op> ToOps()
854854
}
855855
}
856856

857-
public uint GetSigOpCount(bool fAccurate)
857+
public uint GetSigOpCount(bool fAccurate, Network network = null)
858858
{
859859
uint n = 0;
860860
Op lastOpcode = null;
@@ -864,7 +864,9 @@ public uint GetSigOpCount(bool fAccurate)
864864
n++;
865865
else if (op.Code == OpcodeType.OP_CHECKMULTISIG || op.Code == OpcodeType.OP_CHECKMULTISIGVERIFY)
866866
{
867-
if (fAccurate && lastOpcode != null && lastOpcode.Code >= OpcodeType.OP_1 && lastOpcode.Code <= OpcodeType.OP_16)
867+
if (fAccurate && network?.Federations != null && lastOpcode.Code == OpcodeType.OP_FEDERATION)
868+
n += (uint)network.Federations.GetOnlyFederation().GetFederationDetails().transactionSigningKeys.Length;
869+
else if (fAccurate && lastOpcode != null && lastOpcode.Code >= OpcodeType.OP_1 && lastOpcode.Code <= OpcodeType.OP_16)
868870
n += (lastOpcode.PushData == null || lastOpcode.PushData.Length == 0) ? 0U : (uint)lastOpcode.PushData[0];
869871
else
870872
n += 20;
@@ -913,12 +915,12 @@ public uint GetSigOpCount(Network network, Script scriptSig)
913915
{
914916
// TODO: Is the network needed?
915917
if (!IsPayToScriptHash(network))
916-
return GetSigOpCount(true);
918+
return GetSigOpCount(true, network);
917919
// This is a pay-to-script-hash scriptPubKey;
918920
// get the last item that the scriptSig
919921
// pushes onto the stack:
920922
bool validSig = new PayToScriptHashTemplate().CheckScriptSig(network, scriptSig, this);
921-
return !validSig ? 0 : new Script(scriptSig.ToOps().Last().PushData).GetSigOpCount(true);
923+
return !validSig ? 0 : new Script(scriptSig.ToOps().Last().PushData).GetSigOpCount(true, network);
922924
// ... and return its opcount:
923925
}
924926

src/Stratis.Bitcoin.Features.Consensus/Rules/CommonRules/CoinviewRule.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ private long CountWitnessSignatureOperation(Script scriptPubKey, WitScript witne
365365
if (witParams.Program.Length == 32 && witness.PushCount > 0)
366366
{
367367
Script subscript = Script.FromBytesUnsafe(witness.GetUnsafePush(witness.PushCount - 1));
368-
return subscript.GetSigOpCount(true);
368+
return subscript.GetSigOpCount(true, this.Parent.Network);
369369
}
370370
}
371371

src/Stratis.Bitcoin.Features.MemoryPool/Rules/CreateMempoolEntryMempoolRule.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,10 @@ private bool AreInputsStandard(Network network, Transaction tx, MempoolCoinView
234234
var redeemScript = new Script(ctx.Stack.Top(-1));
235235

236236
// TODO: Move this into a network-specific rule so that it only applies to Strax (the Cirrus validator already allows non-standard transactions)
237-
if (!redeemScript.ToOps().Select(o => o.Code).Contains(OpcodeType.OP_FEDERATION))
237+
if (redeemScript.GetSigOpCount(true, this.network) > MaxP2SHSigOps)
238238
{
239-
if (redeemScript.GetSigOpCount(true) > MaxP2SHSigOps)
240-
{
241-
this.logger.LogTrace("(-)[SIG_OP_MAX]:false");
242-
return false;
243-
}
239+
this.logger.LogTrace("(-)[SIG_OP_MAX]:false");
240+
return false;
244241
}
245242
}
246243
}

0 commit comments

Comments
 (0)