From 3ce81ae575bc8b0f0c960fde5fa07bd625e42a5d Mon Sep 17 00:00:00 2001 From: Tommo-L Date: Tue, 26 May 2020 16:26:44 +0800 Subject: [PATCH 1/3] fix policy check --- src/neo/SmartContract/Native/PolicyContract.cs | 17 ++++++++--------- .../SmartContract/Native/Tokens/NeoToken.cs | 6 ++++++ .../SmartContract/Native/UT_PolicyContract.cs | 18 +++++++++++------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 17fc28c0ad..6a0a539671 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -38,11 +38,10 @@ internal bool CheckPolicy(Transaction tx, StoreView snapshot) return true; } - private bool CheckValidators(ApplicationEngine engine) + private bool CheckCommittees(ApplicationEngine engine) { - UInt256 prev_hash = engine.Snapshot.PersistingBlock.PrevHash; - TrimmedBlock prev_block = engine.Snapshot.Blocks[prev_hash]; - return InteropService.Runtime.CheckWitnessInternal(engine, prev_block.NextConsensus); + UInt160 committeeMultiSigAddr = NEO.GetCommitteeMultiSigAddress(engine.Snapshot); + return InteropService.Runtime.CheckWitnessInternal(engine, committeeMultiSigAddr); } internal override bool Initialize(ApplicationEngine engine) @@ -114,7 +113,7 @@ public UInt160[] GetBlockedAccounts(StoreView snapshot) [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetMaxBlockSize(ApplicationEngine engine, Array args) { - if (!CheckValidators(engine)) return false; + if (!CheckCommittees(engine)) return false; uint value = (uint)args[0].GetBigInteger(); if (Network.P2P.Message.PayloadMaxSize <= value) return false; StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxBlockSize)); @@ -125,7 +124,7 @@ private StackItem SetMaxBlockSize(ApplicationEngine engine, Array args) [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, Array args) { - if (!CheckValidators(engine)) return false; + if (!CheckCommittees(engine)) return false; uint value = (uint)args[0].GetBigInteger(); StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_MaxTransactionsPerBlock)); storage.Value = BitConverter.GetBytes(value); @@ -135,7 +134,7 @@ private StackItem SetMaxTransactionsPerBlock(ApplicationEngine engine, Array arg [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Integer }, ParameterNames = new[] { "value" })] private StackItem SetFeePerByte(ApplicationEngine engine, Array args) { - if (!CheckValidators(engine)) return false; + if (!CheckCommittees(engine)) return false; long value = (long)args[0].GetBigInteger(); StorageItem storage = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_FeePerByte)); storage.Value = BitConverter.GetBytes(value); @@ -145,7 +144,7 @@ private StackItem SetFeePerByte(ApplicationEngine engine, Array args) [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] private StackItem BlockAccount(ApplicationEngine engine, Array args) { - if (!CheckValidators(engine)) return false; + if (!CheckCommittees(engine)) return false; UInt160 account = new UInt160(args[0].GetSpan()); StorageKey key = CreateStorageKey(Prefix_BlockedAccounts); StorageItem storage = engine.Snapshot.Storages[key]; @@ -159,7 +158,7 @@ private StackItem BlockAccount(ApplicationEngine engine, Array args) [ContractMethod(0_03000000, ContractParameterType.Boolean, CallFlags.AllowModifyStates, ParameterTypes = new[] { ContractParameterType.Hash160 }, ParameterNames = new[] { "account" })] private StackItem UnblockAccount(ApplicationEngine engine, Array args) { - if (!CheckValidators(engine)) return false; + if (!CheckCommittees(engine)) return false; UInt160 account = new UInt160(args[0].GetSpan()); StorageKey key = CreateStorageKey(Prefix_BlockedAccounts); StorageItem storage = engine.Snapshot.Storages[key]; diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index 67e6260eee..0018f57bda 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -246,6 +246,12 @@ public ECPoint[] GetCommittee(StoreView snapshot) return GetCommitteeMembers(snapshot, ProtocolSettings.Default.MaxCommitteeMembersCount).OrderBy(p => p).ToArray(); } + public UInt160 GetCommitteeMultiSigAddress(StoreView snapshot) + { + ECPoint[] committees = NEO.GetCommittee(snapshot); + return Contract.CreateMultiSigRedeemScript(committees.Length - (committees.Length - 1) / 3, committees).ToScriptHash(); + } + private IEnumerable GetCommitteeMembers(StoreView snapshot, int count) { return GetCandidates(snapshot).OrderByDescending(p => p.Votes).ThenBy(p => p.PublicKey).Select(p => p.PublicKey).Take(count); diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index a173585182..b3b6fa0914 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -61,6 +61,8 @@ public void Check_SetMaxBlockSize() snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero }; snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero }); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0)).Should().BeTrue(); // Without signature @@ -76,7 +78,7 @@ public void Check_SetMaxBlockSize() // More than expected - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "setMaxBlockSize", new ContractParameter(ContractParameterType.Integer) { Value = Neo.Network.P2P.Message.PayloadMaxSize }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeFalse(); @@ -87,7 +89,7 @@ public void Check_SetMaxBlockSize() // With signature - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "setMaxBlockSize", new ContractParameter(ContractParameterType.Integer) { Value = 1024 }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); @@ -122,7 +124,7 @@ public void Check_SetMaxTransactionsPerBlock() // With signature - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot)), "setMaxTransactionsPerBlock", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); @@ -156,8 +158,8 @@ public void Check_SetFeePerByte() ret.GetBigInteger().Should().Be(1000); // With signature - - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "setFeePerByte", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); @@ -177,6 +179,8 @@ public void Check_Block_UnblockAccount() snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero }; snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero }); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0)).Should().BeTrue(); // Block without signature @@ -192,7 +196,7 @@ public void Check_Block_UnblockAccount() // Block with signature - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "blockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); @@ -216,7 +220,7 @@ public void Check_Block_UnblockAccount() // Unblock with signature - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(UInt160.Zero), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "unblockAccount", new ContractParameter(ContractParameterType.Hash160) { Value = UInt160.Zero }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); From 4442a0654745134c590b28fe5e7a406717281560 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 May 2020 20:27:46 +0800 Subject: [PATCH 2/3] Rename --- src/neo/SmartContract/Native/PolicyContract.cs | 2 +- src/neo/SmartContract/Native/Tokens/NeoToken.cs | 4 ++-- .../SmartContract/Native/UT_PolicyContract.cs | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/neo/SmartContract/Native/PolicyContract.cs b/src/neo/SmartContract/Native/PolicyContract.cs index 6a0a539671..552227f7be 100644 --- a/src/neo/SmartContract/Native/PolicyContract.cs +++ b/src/neo/SmartContract/Native/PolicyContract.cs @@ -40,7 +40,7 @@ internal bool CheckPolicy(Transaction tx, StoreView snapshot) private bool CheckCommittees(ApplicationEngine engine) { - UInt160 committeeMultiSigAddr = NEO.GetCommitteeMultiSigAddress(engine.Snapshot); + UInt160 committeeMultiSigAddr = NEO.GetCommitteeAddress(engine.Snapshot); return InteropService.Runtime.CheckWitnessInternal(engine, committeeMultiSigAddr); } diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index 0018f57bda..caefc4e6be 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -246,9 +246,9 @@ public ECPoint[] GetCommittee(StoreView snapshot) return GetCommitteeMembers(snapshot, ProtocolSettings.Default.MaxCommitteeMembersCount).OrderBy(p => p).ToArray(); } - public UInt160 GetCommitteeMultiSigAddress(StoreView snapshot) + public UInt160 GetCommitteeAddress(StoreView snapshot) { - ECPoint[] committees = NEO.GetCommittee(snapshot); + ECPoint[] committees = GetCommittee(snapshot); return Contract.CreateMultiSigRedeemScript(committees.Length - (committees.Length - 1) / 3, committees).ToScriptHash(); } diff --git a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs index b3b6fa0914..22442e08cf 100644 --- a/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs +++ b/tests/neo.UnitTests/SmartContract/Native/UT_PolicyContract.cs @@ -61,7 +61,7 @@ public void Check_SetMaxBlockSize() snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero }; snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero }); - UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0)).Should().BeTrue(); @@ -124,7 +124,7 @@ public void Check_SetMaxTransactionsPerBlock() // With signature - ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot)), + ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(NativeContract.NEO.GetCommitteeAddress(snapshot)), "setMaxTransactionsPerBlock", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); ret.ToBoolean().Should().BeTrue(); @@ -158,7 +158,7 @@ public void Check_SetFeePerByte() ret.GetBigInteger().Should().Be(1000); // With signature - UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); ret = NativeContract.Policy.Call(snapshot, new Nep5NativeContractExtensions.ManualWitness(committeeMultiSigAddr), "setFeePerByte", new ContractParameter(ContractParameterType.Integer) { Value = 1 }); ret.Should().BeOfType(); @@ -179,7 +179,7 @@ public void Check_Block_UnblockAccount() snapshot.PersistingBlock = new Block() { Index = 1000, PrevHash = UInt256.Zero }; snapshot.Blocks.Add(UInt256.Zero, new Neo.Ledger.TrimmedBlock() { NextConsensus = UInt160.Zero }); - UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeMultiSigAddress(snapshot); + UInt160 committeeMultiSigAddr = NativeContract.NEO.GetCommitteeAddress(snapshot); NativeContract.Policy.Initialize(new ApplicationEngine(TriggerType.Application, null, snapshot, 0)).Should().BeTrue(); From 1663ffc36ca58918465dce9438e462e07031e7d9 Mon Sep 17 00:00:00 2001 From: erikzhang Date: Tue, 26 May 2020 20:28:15 +0800 Subject: [PATCH 3/3] Fix GetCommitteeAddress() --- src/neo/SmartContract/Native/Tokens/NeoToken.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/neo/SmartContract/Native/Tokens/NeoToken.cs b/src/neo/SmartContract/Native/Tokens/NeoToken.cs index caefc4e6be..3793765c12 100644 --- a/src/neo/SmartContract/Native/Tokens/NeoToken.cs +++ b/src/neo/SmartContract/Native/Tokens/NeoToken.cs @@ -249,7 +249,7 @@ public ECPoint[] GetCommittee(StoreView snapshot) public UInt160 GetCommitteeAddress(StoreView snapshot) { ECPoint[] committees = GetCommittee(snapshot); - return Contract.CreateMultiSigRedeemScript(committees.Length - (committees.Length - 1) / 3, committees).ToScriptHash(); + return Contract.CreateMultiSigRedeemScript(committees.Length - (committees.Length - 1) / 2, committees).ToScriptHash(); } private IEnumerable GetCommitteeMembers(StoreView snapshot, int count)