From ea3ac5cc324e0f6972f5a1c7f7fa1aab7aaf28da Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 12 Aug 2019 09:12:09 +0200 Subject: [PATCH 1/7] Max witness size --- .../Network/P2P/Payloads/UT_Transaction.cs | 2 +- .../Network/P2P/Payloads/UT_Witness.cs | 101 ++++++++++++++++++ neo/Network/P2P/Payloads/Witness.cs | 4 +- 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs index 2c81e91537..f6df15a4fb 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs @@ -84,7 +84,7 @@ public void Size_Get() uut.Size.Should().Be(83); } - private NEP6Wallet GenerateTestWallet() + internal static NEP6Wallet GenerateTestWallet() { JObject wallet = new JObject(); wallet["name"] = "noname"; diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index ec3525931e..0ae820ddcc 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -1,13 +1,62 @@ using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.IO; using Neo.IO.Json; using Neo.Network.P2P.Payloads; +using Neo.Persistence; +using Neo.SmartContract; +using Neo.Wallets; +using Neo.Wallets.NEP6; +using System; +using System.IO; +using System.Linq; namespace Neo.UnitTests.Network.P2P.Payloads { [TestClass] public class UT_Witness { + class dummyVerificable : IVerifiable + { + private UInt160 _hash; + + public Witness[] Witnesses { get; set; } + + public int Size => 1; + + public dummyVerificable(UInt160 hash) + { + _hash = hash; + } + + public void Deserialize(BinaryReader reader) + { + DeserializeUnsigned(reader); + Witnesses = reader.ReadSerializableArray(16); + } + + public void DeserializeUnsigned(BinaryReader reader) + { + reader.ReadByte(); + } + + public UInt160[] GetScriptHashesForVerifying(Snapshot snapshot) + { + return new UInt160[] { _hash }; + } + + public void Serialize(BinaryWriter writer) + { + SerializeUnsigned(writer); + writer.Write(Witnesses); + } + + public void SerializeUnsigned(BinaryWriter writer) + { + writer.Write((byte)1); + } + } + Witness uut; [TestInitialize] @@ -22,6 +71,58 @@ public void InvocationScript_Get() uut.InvocationScript.Should().BeNull(); } + [TestMethod] + public void MaxSize() + { + var store = TestBlockchain.GetStore(); + var wallet = UT_Transaction.GenerateTestWallet(); + var snapshot = store.GetSnapshot(); + + // Prepare + + var maxAccounts = 14; + var address = new WalletAccount[maxAccounts]; + var wallets = new NEP6Wallet[maxAccounts]; + var walletsUnlocks = new IDisposable[maxAccounts]; + + for (int x = 0; x < maxAccounts; x++) + { + wallets[x] = UT_Transaction.GenerateTestWallet(); + walletsUnlocks[x] = wallets[x].Unlock("123"); + address[x] = wallets[x].CreateAccount(); + } + + // Generate multisignature + + var multiSignContract = Contract.CreateMultiSigContract(maxAccounts, address.Select(a => a.GetKey().PublicKey).ToArray()); + + for (int x = 0; x < maxAccounts; x++) + { + wallets[x].CreateAccount(multiSignContract, address[x].GetKey()); + } + + // Sign + + var data = new ContractParametersContext(new dummyVerificable(multiSignContract.ScriptHash)); + + for (int x = 0; x < maxAccounts; x++) + { + Assert.IsTrue(wallets[x].Sign(data)); + } + + Assert.IsTrue(data.Completed); + var witnesses = data.GetWitnesses()[0]; + + // Check max size + + Assert.IsTrue(witnesses.Size < 1500); + + var copy = witnesses.ToArray().AsSerializable(); + + CollectionAssert.AreEqual(witnesses.InvocationScript, copy.InvocationScript); + CollectionAssert.AreEqual(witnesses.VerificationScript, copy.VerificationScript); + } + [TestMethod] public void InvocationScript_Set() { diff --git a/neo/Network/P2P/Payloads/Witness.cs b/neo/Network/P2P/Payloads/Witness.cs index d352882e17..2cc6b592c6 100644 --- a/neo/Network/P2P/Payloads/Witness.cs +++ b/neo/Network/P2P/Payloads/Witness.cs @@ -28,8 +28,8 @@ public virtual UInt160 ScriptHash void ISerializable.Deserialize(BinaryReader reader) { - InvocationScript = reader.ReadVarBytes(65536); - VerificationScript = reader.ReadVarBytes(65536); + InvocationScript = reader.ReadVarBytes(1024); + VerificationScript = reader.ReadVarBytes(512); } void ISerializable.Serialize(BinaryWriter writer) From 086c1c9a815589d29540462346ac209f562b86aa Mon Sep 17 00:00:00 2001 From: Shargon Date: Mon, 12 Aug 2019 09:16:56 +0200 Subject: [PATCH 2/7] Add error test --- .../Network/P2P/Payloads/UT_Witness.cs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 0ae820ddcc..7ba2788d7e 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -71,8 +71,7 @@ public void InvocationScript_Get() uut.InvocationScript.Should().BeNull(); } - [TestMethod] - public void MaxSize() + private Witness PrepareDummyWitness(int maxAccounts) { var store = TestBlockchain.GetStore(); var wallet = UT_Transaction.GenerateTestWallet(); @@ -80,7 +79,6 @@ public void MaxSize() // Prepare - var maxAccounts = 14; var address = new WalletAccount[maxAccounts]; var wallets = new NEP6Wallet[maxAccounts]; var walletsUnlocks = new IDisposable[maxAccounts]; @@ -111,16 +109,33 @@ public void MaxSize() } Assert.IsTrue(data.Completed); - var witnesses = data.GetWitnesses()[0]; + return data.GetWitnesses()[0]; + } + + [TestMethod] + public void MaxSize_OK() + { + var witness = PrepareDummyWitness(14); // Check max size - Assert.IsTrue(witnesses.Size < 1500); + Assert.IsTrue(witness.Size < 1400); + + var copy = witness.ToArray().AsSerializable(); - var copy = witnesses.ToArray().AsSerializable(); + CollectionAssert.AreEqual(witness.InvocationScript, copy.InvocationScript); + CollectionAssert.AreEqual(witness.VerificationScript, copy.VerificationScript); + } + + [TestMethod] + public void MaxSize_Error() + { + var witness = PrepareDummyWitness(15); + + // Check max size - CollectionAssert.AreEqual(witnesses.InvocationScript, copy.InvocationScript); - CollectionAssert.AreEqual(witnesses.VerificationScript, copy.VerificationScript); + Assert.IsTrue(witness.Size > 1400); + Assert.ThrowsException(() => witness.ToArray().AsSerializable()); } [TestMethod] From 37646d0d603360a772efb0f85156e810629ed221 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 13 Aug 2019 09:11:47 +0200 Subject: [PATCH 3/7] Rename class --- neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 7ba2788d7e..ac163d3519 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -16,7 +16,7 @@ namespace Neo.UnitTests.Network.P2P.Payloads [TestClass] public class UT_Witness { - class dummyVerificable : IVerifiable + class DummyVerificable : IVerifiable { private UInt160 _hash; @@ -24,7 +24,7 @@ class dummyVerificable : IVerifiable public int Size => 1; - public dummyVerificable(UInt160 hash) + public DummyVerificable(UInt160 hash) { _hash = hash; } @@ -101,7 +101,7 @@ private Witness PrepareDummyWitness(int maxAccounts) // Sign - var data = new ContractParametersContext(new dummyVerificable(multiSignContract.ScriptHash)); + var data = new ContractParametersContext(new DummyVerificable(multiSignContract.ScriptHash)); for (int x = 0; x < maxAccounts; x++) { From dc84504cf37ce4af748333bfe8b57e8c50150918 Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Wed, 14 Aug 2019 16:58:22 -0300 Subject: [PATCH 4/7] allow 10/10 --- neo/Network/P2P/Payloads/Witness.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/neo/Network/P2P/Payloads/Witness.cs b/neo/Network/P2P/Payloads/Witness.cs index 2cc6b592c6..32530670a0 100644 --- a/neo/Network/P2P/Payloads/Witness.cs +++ b/neo/Network/P2P/Payloads/Witness.cs @@ -28,8 +28,11 @@ public virtual UInt160 ScriptHash void ISerializable.Deserialize(BinaryReader reader) { - InvocationScript = reader.ReadVarBytes(1024); - VerificationScript = reader.ReadVarBytes(512); + // This is designed to allow a MultiSig 10/10 (around 1000 bytes) + // Invocation = 10 * 64 + 10 = 650 + InvocationScript = reader.ReadVarBytes(650); + // Verification = 10 * 33 = 330 ~ 350 + VerificationScript = reader.ReadVarBytes(350); } void ISerializable.Serialize(BinaryWriter writer) From 7d516bef6da26d80f59612417bc79f5df824a154 Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Wed, 14 Aug 2019 21:53:41 -0300 Subject: [PATCH 5/7] rounding up to 1024 bytes --- neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs | 8 ++++++-- neo/Network/P2P/Payloads/Witness.cs | 10 +++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index ac163d3519..9c8d249d62 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -115,11 +115,15 @@ private Witness PrepareDummyWitness(int maxAccounts) [TestMethod] public void MaxSize_OK() { - var witness = PrepareDummyWitness(14); + var witness = PrepareDummyWitness(10); // Check max size - Assert.IsTrue(witness.Size < 1400); + witness.Size.Should().Be(1003); + witness.InvocationScript.GetVarSize().Should().Be(653); + witness.VerificationScript.GetVarSize().Should().Be(350); + + Assert.IsTrue(witness.Size <= 1024); var copy = witness.ToArray().AsSerializable(); diff --git a/neo/Network/P2P/Payloads/Witness.cs b/neo/Network/P2P/Payloads/Witness.cs index 32530670a0..52a2186ee8 100644 --- a/neo/Network/P2P/Payloads/Witness.cs +++ b/neo/Network/P2P/Payloads/Witness.cs @@ -28,11 +28,11 @@ public virtual UInt160 ScriptHash void ISerializable.Deserialize(BinaryReader reader) { - // This is designed to allow a MultiSig 10/10 (around 1000 bytes) - // Invocation = 10 * 64 + 10 = 650 - InvocationScript = reader.ReadVarBytes(650); - // Verification = 10 * 33 = 330 ~ 350 - VerificationScript = reader.ReadVarBytes(350); + // 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(664); + // Verification = 10 * 33 + 10 = 340 ~ 360 (exact is 350) + VerificationScript = reader.ReadVarBytes(360); } void ISerializable.Serialize(BinaryWriter writer) From cbc5e8600f05cdd198e440578f651cf90bc6569e Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 15 Aug 2019 08:32:18 +0300 Subject: [PATCH 6/7] Error with 11 --- neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 9c8d249d62..79db03be5a 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -134,11 +134,11 @@ public void MaxSize_OK() [TestMethod] public void MaxSize_Error() { - var witness = PrepareDummyWitness(15); + var witness = PrepareDummyWitness(11); // Check max size - Assert.IsTrue(witness.Size > 1400); + Assert.IsTrue(witness.Size > 1024); Assert.ThrowsException(() => witness.ToArray().AsSerializable()); } @@ -193,4 +193,4 @@ public void ToJson() Assert.AreEqual(json["verification"].AsString(), "202020"); } } -} \ No newline at end of file +} From 8ad3066c684f81580d99dda0fa6cefd59c0d8fe6 Mon Sep 17 00:00:00 2001 From: Shargon Date: Tue, 20 Aug 2019 08:48:44 +0200 Subject: [PATCH 7/7] Fix ut --- neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs index 79db03be5a..01a76eeee4 100644 --- a/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs +++ b/neo.UnitTests/Network/P2P/Payloads/UT_Witness.cs @@ -74,7 +74,7 @@ public void InvocationScript_Get() private Witness PrepareDummyWitness(int maxAccounts) { var store = TestBlockchain.GetStore(); - var wallet = UT_Transaction.GenerateTestWallet(); + var wallet = TestUtils.GenerateTestWallet(); var snapshot = store.GetSnapshot(); // Prepare @@ -85,7 +85,7 @@ private Witness PrepareDummyWitness(int maxAccounts) for (int x = 0; x < maxAccounts; x++) { - wallets[x] = UT_Transaction.GenerateTestWallet(); + wallets[x] = TestUtils.GenerateTestWallet(); walletsUnlocks[x] = wallets[x].Unlock("123"); address[x] = wallets[x].CreateAccount(); }