Skip to content

Commit

Permalink
Fix Witness limits (#1958)
Browse files Browse the repository at this point in the history
* Fix Witness max size

* Fix comment

* Fix comment

* Change it to use constants

* Changed to 1024

* Fix UT
  • Loading branch information
shargon authored Oct 3, 2020
1 parent 588cd98 commit f37638b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
18 changes: 13 additions & 5 deletions src/neo/Network/P2P/Payloads/Witness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ namespace Neo.Network.P2P.Payloads
{
public class Witness : ISerializable
{
/// <summary>
/// This is designed to allow a MultiSig 21/11 (committee)
/// Invocation = 11 * (64 + 2) = 726
/// </summary>
private const int MaxInvocationScript = 1024;

/// <summary>
/// Verification = m + (PUSH_PubKey * 21) + length + null + syscall = 1 + ((2 + 33) * 21) + 2 + 1 + 5 = 744
/// </summary>
private const int MaxVerificationScript = 1024;

public byte[] InvocationScript;
public byte[] VerificationScript;

Expand All @@ -32,11 +43,8 @@ public virtual UInt160 ScriptHash

void ISerializable.Deserialize(BinaryReader reader)
{
// This is designed to allow a MultiSig 10/10 (around 1003 bytes) ~1024 bytes
// Invocation = 10 * 64 + 10 = 650 ~ 664 (exact is 653)
InvocationScript = reader.ReadVarBytes(663);
// Verification = 10 * 33 + 10 = 340 ~ 360 (exact is 351)
VerificationScript = reader.ReadVarBytes(361);
InvocationScript = reader.ReadVarBytes(MaxInvocationScript);
VerificationScript = reader.ReadVarBytes(MaxVerificationScript);
}

void ISerializable.Serialize(BinaryWriter writer)
Expand Down
31 changes: 20 additions & 11 deletions tests/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ public void InvocationScript_Get()
uut.InvocationScript.Should().BeNull();
}

private Witness PrepareDummyWitness(int maxAccounts)
private Witness PrepareDummyWitness(int pubKeys, int m)
{
var address = new WalletAccount[maxAccounts];
var wallets = new NEP6Wallet[maxAccounts];
var walletsUnlocks = new IDisposable[maxAccounts];
var address = new WalletAccount[pubKeys];
var wallets = new NEP6Wallet[pubKeys];
var walletsUnlocks = new IDisposable[pubKeys];

for (int x = 0; x < maxAccounts; x++)
for (int x = 0; x < pubKeys; x++)
{
wallets[x] = TestUtils.GenerateTestWallet();
walletsUnlocks[x] = wallets[x].Unlock("123");
Expand All @@ -43,9 +43,9 @@ private Witness PrepareDummyWitness(int maxAccounts)

// Generate multisignature

var multiSignContract = Contract.CreateMultiSigContract(maxAccounts, address.Select(a => a.GetKey().PublicKey).ToArray());
var multiSignContract = Contract.CreateMultiSigContract(m, address.Select(a => a.GetKey().PublicKey).ToArray());

for (int x = 0; x < maxAccounts; x++)
for (int x = 0; x < pubKeys; x++)
{
wallets[x].CreateAccount(multiSignContract, address[x].GetKey());
}
Expand All @@ -69,7 +69,7 @@ private Witness PrepareDummyWitness(int maxAccounts)
Witnesses = new Witness[0]
});

for (int x = 0; x < maxAccounts; x++)
for (int x = 0; x < m; x++)
{
Assert.IsTrue(wallets[x].Sign(data));
}
Expand All @@ -81,7 +81,7 @@ private Witness PrepareDummyWitness(int maxAccounts)
[TestMethod]
public void MaxSize_OK()
{
var witness = PrepareDummyWitness(10);
var witness = PrepareDummyWitness(10, 10);

// Check max size

Expand All @@ -100,11 +100,20 @@ public void MaxSize_OK()
[TestMethod]
public void MaxSize_Error()
{
var witness = PrepareDummyWitness(11);
var witness = new Witness
{
InvocationScript = new byte[1025],
VerificationScript = new byte[10]
};

// Check max size

Assert.ThrowsException<FormatException>(() => witness.ToArray().AsSerializable<Witness>());

// Check max size

Assert.IsTrue(witness.Size > 1024);
witness.InvocationScript = new byte[10];
witness.VerificationScript = new byte[1025];
Assert.ThrowsException<FormatException>(() => witness.ToArray().AsSerializable<Witness>());
}

Expand Down

0 comments on commit f37638b

Please sign in to comment.