From efd8853c123b0d9ec123f239989b4bbd1fc55a29 Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 17:57:03 +1300 Subject: [PATCH 1/8] Add serializer V2 --- .../ContractPrimitiveSerializer.cs | 2 +- .../ContractPrimitiveSerializerV1.cs | 27 ++ .../ContractPrimitiveSerializerV2.cs | 268 ++++++++++++++++++ 3 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV1.cs create mode 100644 src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV2.cs diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs index 3a50b94439..29eaf58927 100644 --- a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs @@ -139,7 +139,7 @@ public T Deserialize(byte[] stream) return (T) deserialized; } - public object Deserialize(Type type, byte[] stream) + public virtual object Deserialize(Type type, byte[] stream) { if (stream == null) return null; diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV1.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV1.cs new file mode 100644 index 0000000000..0e8e10d6da --- /dev/null +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV1.cs @@ -0,0 +1,27 @@ +using System; +using NBitcoin; +using TracerAttributes; + +namespace Stratis.SmartContracts.CLR.Serialization +{ + /// + /// This class serializes and deserializes specific data types + /// when persisting items inside a smart contract. + /// + [NoTrace] + public class ContractPrimitiveSerializerV1 : ContractPrimitiveSerializerV2 + { + public ContractPrimitiveSerializerV1(Network network) + : base(network) + { + } + + public override object Deserialize(Type type, byte[] stream) + { + if (stream == null || stream.Length == 0) + return null; + + return base.DeserializeBytes(type, stream); + } + } +} diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV2.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV2.cs new file mode 100644 index 0000000000..f23c8a5a9d --- /dev/null +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializerV2.cs @@ -0,0 +1,268 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using NBitcoin; +using Nethereum.RLP; +using Stratis.SmartContracts.CLR.Exceptions; +using TracerAttributes; + +namespace Stratis.SmartContracts.CLR.Serialization +{ + /// + /// This class serializes and deserializes specific data types + /// when persisting items inside a smart contract. + /// + /// V1 returns empty strings rather than nulls. + /// + [NoTrace] + public class ContractPrimitiveSerializerV2 : IContractPrimitiveSerializer + { + private readonly Network network; + + public ContractPrimitiveSerializerV2(Network network) + { + this.network = network; + } + + public byte[] Serialize(object o) + { + return o switch + { + null => null, + byte[] bytes => bytes, + Array array => Serialize(array), + byte b1 => new byte[] { b1 }, + char c => Serialize(c), + Address address => Serialize(address), + bool b => Serialize(b), + int i => Serialize(i), + long l => Serialize(l), + UInt128 u => Serialize(u), + UInt256 u => Serialize(u), + uint u => Serialize(u), + ulong u => Serialize(u), + string s => Serialize(s), + _ when o.GetType().IsValueType => SerializeStruct(o), + _ => throw new ContractPrimitiveSerializationException(string.Format("{0} is not supported.", o.GetType().Name)) + }; + } + + #region Primitive serialization + + private byte[] Serialize(Address address) + { + return address.ToBytes(); + } + + private byte[] Serialize(bool b) + { + return BitConverter.GetBytes(b); + } + + private byte[] Serialize(int i) + { + return BitConverter.GetBytes(i); + } + + private byte[] Serialize(long l) + { + return BitConverter.GetBytes(l); + } + + private byte[] Serialize(uint u) + { + return BitConverter.GetBytes(u); + } + + private byte[] Serialize(ulong ul) + { + return BitConverter.GetBytes(ul); + } + + private byte[] Serialize(UInt128 u128) + { + return u128.ToBytes(); + } + + private byte[] Serialize(UInt256 u256) + { + return u256.ToBytes(); + } + + private byte[] Serialize(char c) + { + return BitConverter.GetBytes(c); + } + + private byte[] Serialize(string s) + { + return Encoding.UTF8.GetBytes(s); + } + + #endregion + + private byte[] SerializeStruct(object o) + { + List toEncode = new List(); + + foreach (FieldInfo field in o.GetType().GetFields()) + { + object value = field.GetValue(o); + byte[] serialized = this.Serialize(value); + toEncode.Add(RLP.EncodeElement(serialized)); + } + + return RLP.EncodeList(toEncode.ToArray()); + } + + private byte[] Serialize(Array array) + { + // Edge case, serializing nonsensical + if (array is byte[] a) + return a; + + List toEncode = new List(); + + for(int i=0; i< array.Length; i++) + { + object value = array.GetValue(i); + byte[] serialized = this.Serialize(value); + toEncode.Add(RLP.EncodeElement(serialized)); + } + + return RLP.EncodeList(toEncode.ToArray()); + } + + public T Deserialize(byte[] stream) + { + object deserialized = this.Deserialize(typeof(T), stream); + + return (T) deserialized; + } + + public virtual object Deserialize(Type type, byte[] stream) + { + if (stream == null) + return null; + + return DeserializeBytes(type, stream); + } + + protected object DeserializeBytes(Type type, byte[] stream) + { + return Type.GetTypeCode(type) switch + { + TypeCode.Byte => stream[0], + TypeCode.Char => ToChar(stream), + TypeCode.Boolean => ToBool(stream), + TypeCode.Int32 => ToInt32(stream), + TypeCode.Int64 => ToInt64(stream), + TypeCode.String => ToString(stream), + TypeCode.UInt32 => ToUInt32(stream), + TypeCode.UInt64 => ToUInt64(stream), + _ when type == typeof(byte[]) => stream, + _ when type == typeof(UInt128) => ToUInt128(stream), + _ when type == typeof(UInt256) => ToUInt256(stream), + _ when type == typeof(Address) => ToAddress(stream), + _ when type.IsArray => DeserializeArray(type.GetElementType(), stream), + _ when type.IsValueType => DeserializeStruct(type, stream), + _ => throw new ContractPrimitiveSerializationException(string.Format("{0} is not supported.", type.Name)), + }; + } + + public Address ToAddress(string address) + { + return address.ToAddress(this.network); + } + + #region Primitive Deserialization + + private bool ToBool(byte[] val) + { + return BitConverter.ToBoolean(val); + } + + private Address ToAddress(byte[] val) + { + return val.ToAddress(); + } + + private int ToInt32(byte[] val) + { + return BitConverter.ToInt32(val, 0); + } + + private uint ToUInt32(byte[] val) + { + return BitConverter.ToUInt32(val, 0); + } + + private long ToInt64(byte[] val) + { + return BitConverter.ToInt64(val, 0); + } + + private ulong ToUInt64(byte[] val) + { + return BitConverter.ToUInt64(val, 0); + } + + private UInt128 ToUInt128(byte[] val) + { + return new UInt128(val); + } + + private UInt256 ToUInt256(byte[] val) + { + return new UInt256(val); + } + + private char ToChar(byte[] val) + { + return BitConverter.ToChar(val, 0); + } + + private string ToString(byte[] val) + { + return Encoding.UTF8.GetString(val); + } + + #endregion + + private object DeserializeStruct(Type type, byte[] bytes) + { + RLPCollection collection = (RLPCollection) RLP.Decode(bytes); + + object ret = Activator.CreateInstance(type); + + FieldInfo[] fields = type.GetFields(); + + for (int i = 0; i < fields.Length; i++) + { + byte[] fieldBytes = collection[i].RLPData; + fields[i].SetValue(ret, this.Deserialize(fields[i].FieldType, fieldBytes)); + } + + return ret; + } + + private object DeserializeArray(Type elementType, byte[] bytes) + { + // Edge case, serializing nonsensical + if (elementType == typeof(byte)) + return bytes; + + RLPCollection collection = (RLPCollection)RLP.Decode(bytes); + + Array ret = Array.CreateInstance(elementType, collection.Count); + + for(int i=0; i< collection.Count; i++) + { + ret.SetValue(this.Deserialize(elementType, collection[i].RLPData), i); + } + + return ret; + } + } +} From d2021b4fd5f425ac325465b101781ce8408e690e Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 18:28:09 +1300 Subject: [PATCH 2/8] Dispatch based on height --- .../ContractPrimitiveSerializer.cs | 247 +----------------- 1 file changed, 12 insertions(+), 235 deletions(-) diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs index 29eaf58927..4e674aaaa1 100644 --- a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs @@ -4,6 +4,7 @@ using System.Text; using NBitcoin; using Nethereum.RLP; +using Stratis.Bitcoin.Consensus; using Stratis.SmartContracts.CLR.Exceptions; using TracerAttributes; @@ -14,248 +15,24 @@ namespace Stratis.SmartContracts.CLR.Serialization /// when persisting items inside a smart contract. /// [NoTrace] - public class ContractPrimitiveSerializer : IContractPrimitiveSerializer + public class ContractPrimitiveSerializer : ContractPrimitiveSerializerV2 { - private readonly Network network; + private readonly IConsensusManager consensusManager; + private readonly ContractPrimitiveSerializerV1 serializerV1; - public ContractPrimitiveSerializer(Network network) + public ContractPrimitiveSerializer(Network network, IConsensusManager consensusManager) + : base(network) { - this.network = network; + this.consensusManager = consensusManager; + this.serializerV1 = new ContractPrimitiveSerializerV1(network); } - public byte[] Serialize(object o) + public override object Deserialize(Type type, byte[] stream) { - return o switch - { - null => null, - byte[] bytes => bytes, - Array array => Serialize(array), - byte b1 => new byte[] { b1 }, - char c => Serialize(c), - Address address => Serialize(address), - bool b => Serialize(b), - int i => Serialize(i), - long l => Serialize(l), - UInt128 u => Serialize(u), - UInt256 u => Serialize(u), - uint u => Serialize(u), - ulong u => Serialize(u), - string s => Serialize(s), - _ when o.GetType().IsValueType => SerializeStruct(o), - _ => throw new ContractPrimitiveSerializationException(string.Format("{0} is not supported.", o.GetType().Name)) - }; - } - - #region Primitive serialization - - private byte[] Serialize(Address address) - { - return address.ToBytes(); - } - - private byte[] Serialize(bool b) - { - return BitConverter.GetBytes(b); - } - - private byte[] Serialize(int i) - { - return BitConverter.GetBytes(i); - } - - private byte[] Serialize(long l) - { - return BitConverter.GetBytes(l); - } - - private byte[] Serialize(uint u) - { - return BitConverter.GetBytes(u); - } - - private byte[] Serialize(ulong ul) - { - return BitConverter.GetBytes(ul); - } - - private byte[] Serialize(UInt128 u128) - { - return u128.ToBytes(); - } - - private byte[] Serialize(UInt256 u256) - { - return u256.ToBytes(); - } - - private byte[] Serialize(char c) - { - return BitConverter.GetBytes(c); - } - - private byte[] Serialize(string s) - { - return Encoding.UTF8.GetBytes(s); - } - - #endregion - - private byte[] SerializeStruct(object o) - { - List toEncode = new List(); - - foreach (FieldInfo field in o.GetType().GetFields()) - { - object value = field.GetValue(o); - byte[] serialized = this.Serialize(value); - toEncode.Add(RLP.EncodeElement(serialized)); - } - - return RLP.EncodeList(toEncode.ToArray()); - } - - private byte[] Serialize(Array array) - { - // Edge case, serializing nonsensical - if (array is byte[] a) - return a; - - List toEncode = new List(); - - for(int i=0; i< array.Length; i++) - { - object value = array.GetValue(i); - byte[] serialized = this.Serialize(value); - toEncode.Add(RLP.EncodeElement(serialized)); - } - - return RLP.EncodeList(toEncode.ToArray()); - } - - public T Deserialize(byte[] stream) - { - object deserialized = this.Deserialize(typeof(T), stream); - - return (T) deserialized; - } - - public virtual object Deserialize(Type type, byte[] stream) - { - if (stream == null) - return null; - - return Type.GetTypeCode(type) switch - { - TypeCode.Byte => stream[0], - TypeCode.Char => ToChar(stream), - TypeCode.Boolean => ToBool(stream), - TypeCode.Int32 => ToInt32(stream), - TypeCode.Int64 => ToInt64(stream), - TypeCode.String => ToString(stream), - TypeCode.UInt32 => ToUInt32(stream), - TypeCode.UInt64 => ToUInt64(stream), - _ when type == typeof(byte[]) => stream, - _ when type == typeof(UInt128) => ToUInt128(stream), - _ when type == typeof(UInt256) => ToUInt256(stream), - _ when type == typeof(Address) => ToAddress(stream), - _ when type.IsArray => DeserializeArray(type.GetElementType(), stream), - _ when type.IsValueType => DeserializeStruct(type, stream), - _ => throw new ContractPrimitiveSerializationException(string.Format("{0} is not supported.", type.Name)), - }; - } - - public Address ToAddress(string address) - { - return address.ToAddress(this.network); - } - - #region Primitive Deserialization - - private bool ToBool(byte[] val) - { - return BitConverter.ToBoolean(val); - } - - private Address ToAddress(byte[] val) - { - return val.ToAddress(); - } - - private int ToInt32(byte[] val) - { - return BitConverter.ToInt32(val, 0); - } - - private uint ToUInt32(byte[] val) - { - return BitConverter.ToUInt32(val, 0); - } - - private long ToInt64(byte[] val) - { - return BitConverter.ToInt64(val, 0); - } - - private ulong ToUInt64(byte[] val) - { - return BitConverter.ToUInt64(val, 0); - } - - private UInt128 ToUInt128(byte[] val) - { - return new UInt128(val); - } - - private UInt256 ToUInt256(byte[] val) - { - return new UInt256(val); - } - - private char ToChar(byte[] val) - { - return BitConverter.ToChar(val, 0); - } - - private string ToString(byte[] val) - { - return Encoding.UTF8.GetString(val); - } - - #endregion - - private object DeserializeStruct(Type type, byte[] bytes) - { - RLPCollection collection = (RLPCollection) RLP.Decode(bytes); - - object ret = Activator.CreateInstance(type); - - FieldInfo[] fields = type.GetFields(); - - for (int i = 0; i < fields.Length; i++) - { - byte[] fieldBytes = collection[i].RLPData; - fields[i].SetValue(ret, this.Deserialize(fields[i].FieldType, fieldBytes)); - } - - return ret; - } - - private object DeserializeArray(Type elementType, byte[] bytes) - { - // Edge case, serializing nonsensical - if (elementType == typeof(byte)) - return bytes; - - RLPCollection collection = (RLPCollection)RLP.Decode(bytes); - - Array ret = Array.CreateInstance(elementType, collection.Count); - - for(int i=0; i< collection.Count; i++) - { - ret.SetValue(this.Deserialize(elementType, collection[i].RLPData), i); - } + if (this.consensusManager.Tip.Height > 0) // TODO + return this.serializerV1.Deserialize(type, stream); - return ret; + return base.Deserialize(type, stream); } } } From 15f4d6a53cc5b0ffd164ad1b586cd504740a46df Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 18:30:06 +1300 Subject: [PATCH 3/8] Update tests --- .../ApiLogDeserializerTests.cs | 6 +++--- .../Consensus/Rules/ContractValidationRuleTest.cs | 2 +- .../Consensus/Rules/TestRulesContext.cs | 2 +- src/Stratis.SmartContracts.CLR.Tests/AuctionTests.cs | 2 +- .../CallDataSerializerTests.cs | 2 +- .../ContractExecutorTestContext.cs | 2 +- .../ContractExecutorTests.cs | 2 +- .../ContractLogHolderTests.cs | 2 +- ...izerTests.cs => ContractPrimitiveSerializerV2Tests.cs} | 8 ++++---- src/Stratis.SmartContracts.CLR.Tests/Logs/RawLogTests.cs | 2 +- .../MethodParameterByteSerializerTests.cs | 2 +- .../ObserverInstanceRewriterTests.cs | 2 +- src/Stratis.SmartContracts.CLR.Tests/ObserverTests.cs | 2 +- src/Stratis.SmartContracts.CLR.Tests/SerializerTests.cs | 2 +- .../ContractExecutionFailureTests.cs | 2 +- .../ContractParameterSerializationTests.cs | 2 +- .../PoW/SmartContractMemoryPoolTests.cs | 2 +- .../PoW/SmartContractMinerTests.cs | 6 +++--- 18 files changed, 25 insertions(+), 25 deletions(-) rename src/Stratis.SmartContracts.CLR.Tests/{ContractPrimitiveSerializerTests.cs => ContractPrimitiveSerializerV2Tests.cs} (97%) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/ApiLogDeserializerTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/ApiLogDeserializerTests.cs index 5befc77e6b..52bac55577 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/ApiLogDeserializerTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/ApiLogDeserializerTests.cs @@ -35,7 +35,7 @@ public struct TestLog public void Deserialize_Basic_Log_Success() { var network = new SmartContractsRegTest(); - var primitiveSerializer = new ContractPrimitiveSerializer(network); + var primitiveSerializer = new ContractPrimitiveSerializerV2(network); var testStruct = new TestLog { @@ -68,7 +68,7 @@ public void Deserialize_Basic_Log_Success() public void Deserialize_Logs_With_Different_Addresses_From_Cache() { var network = new SmartContractsRegTest(); - var primitiveSerializer = new ContractPrimitiveSerializer(network); + var primitiveSerializer = new ContractPrimitiveSerializerV2(network); var testStruct0 = new TestLog { @@ -119,7 +119,7 @@ public void Deserialize_Logs_With_Different_Addresses_From_Cache() public void MapTransferInfo_Success() { var network = new SmartContractsRegTest(); - var primitiveSerializer = new ContractPrimitiveSerializer(network); + var primitiveSerializer = new ContractPrimitiveSerializerV2(network); var stateRoot = new Mock(); stateRoot.Setup(r => r.GetCodeHash(It.IsAny())).Returns(uint256.Zero.ToBytes()); diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/ContractValidationRuleTest.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/ContractValidationRuleTest.cs index 1fa96ae60a..85d9568a7a 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/ContractValidationRuleTest.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/ContractValidationRuleTest.cs @@ -21,7 +21,7 @@ public class ContractValidationRuleTest public ContractValidationRuleTest() { this.network = new SmartContractsRegTest(); - this.callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(this.network)); + this.callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(this.network)); } private UnspentOutputSet GetMockOutputSet() diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/TestRulesContext.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/TestRulesContext.cs index d159b0853f..17dab4026d 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/TestRulesContext.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Consensus/Rules/TestRulesContext.cs @@ -108,7 +108,7 @@ public static TestRulesContext CreateAsync(Network network, [CallerMemberName] s testRulesContext.ChainIndexer, deployments, consensusSettings, testRulesContext.Checkpoints, null, testRulesContext.ChainState, new InvalidBlockHashStore(new DateTimeProvider()), new NodeStats(testRulesContext.DateTimeProvider, testRulesContext.NodeSettings, new Mock().Object), testRulesContext.AsyncProvider, new ConsensusRulesContainer()).SetupRulesEngineParent(); - testRulesContext.CallDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(network)); + testRulesContext.CallDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(network)); return testRulesContext; } diff --git a/src/Stratis.SmartContracts.CLR.Tests/AuctionTests.cs b/src/Stratis.SmartContracts.CLR.Tests/AuctionTests.cs index 36cfe45a97..71650ce2e2 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/AuctionTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/AuctionTests.cs @@ -34,7 +34,7 @@ public AuctionTests() }; var getBalance = new Func(() => Balance); var persistentState = new TestPersistentState(); - var serializer = new Serializer(new ContractPrimitiveSerializer(network)); + var serializer = new Serializer(new ContractPrimitiveSerializerV2(network)); this.smartContractState = new TestSmartContractState( block, message, diff --git a/src/Stratis.SmartContracts.CLR.Tests/CallDataSerializerTests.cs b/src/Stratis.SmartContracts.CLR.Tests/CallDataSerializerTests.cs index 1c1ad523be..caf7edb633 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/CallDataSerializerTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/CallDataSerializerTests.cs @@ -10,7 +10,7 @@ namespace Stratis.SmartContracts.CLR.Tests { public sealed class CallDataSerializerTests { - public ICallDataSerializer Serializer = new CallDataSerializer(new ContractPrimitiveSerializer(new SmartContractsRegTest())); + public ICallDataSerializer Serializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(new SmartContractsRegTest())); [Fact] public void SmartContract_CanSerialize_OP_CREATECONTRACT_WithoutMethodParameters() diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTestContext.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTestContext.cs index fce7fe9b1c..f8f7f93d58 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTestContext.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTestContext.cs @@ -40,7 +40,7 @@ public ContractExecutorTestContext() this.KeyEncodingStrategy = BasicKeyEncodingStrategy.Default; this.LoggerFactory = ExtendedLoggerFactory.Create(); this.State = new StateRepositoryRoot(new NoDeleteSource(new MemoryDictionarySource())); - this.ContractPrimitiveSerializer = new ContractPrimitiveSerializer(this.Network); + this.ContractPrimitiveSerializer = new ContractPrimitiveSerializerV2(this.Network); this.Serializer = new Serializer(this.ContractPrimitiveSerializer); this.AddressGenerator = new AddressGenerator(); this.Validator = new SmartContractValidator(); diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTests.cs index a17cb0059b..19ae959cdd 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractExecutorTests.cs @@ -54,7 +54,7 @@ public ContractExecutorTests() this.addressGenerator = new AddressGenerator(); this.assemblyLoader = new ContractAssemblyLoader(); this.moduleDefinitionReader = new ContractModuleDefinitionReader(); - this.contractPrimitiveSerializer = new ContractPrimitiveSerializer(this.network); + this.contractPrimitiveSerializer = new ContractPrimitiveSerializerV2(this.network); this.serializer = new Serializer(this.contractPrimitiveSerializer); this.contractCache = new ContractAssemblyCache(); this.vm = new ReflectionVirtualMachine(this.validator, this.loggerFactory, this.assemblyLoader, this.moduleDefinitionReader, this.contractCache); diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractLogHolderTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractLogHolderTests.cs index a76d10c283..9ec9040094 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractLogHolderTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractLogHolderTests.cs @@ -19,7 +19,7 @@ public class ContractLogHolderTests public ContractLogHolderTests() { this.network = new SmartContractsRegTest(); - this.serializer = new ContractPrimitiveSerializer(this.network); + this.serializer = new ContractPrimitiveSerializerV2(this.network); this.logHolder = new ContractLogHolder(); } diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs similarity index 97% rename from src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerTests.cs rename to src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs index 920873a1c2..1787cae741 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs @@ -10,15 +10,15 @@ namespace Stratis.SmartContracts.CLR.Tests { - public class ContractPrimitiveSerializerTests + public class ContractPrimitiveSerializerV2Tests { - private readonly ContractPrimitiveSerializer serializer; + private readonly IContractPrimitiveSerializer serializer; private readonly Network network; - public ContractPrimitiveSerializerTests() + public ContractPrimitiveSerializerV2Tests() { this.network = new SmartContractsRegTest(); - this.serializer = new ContractPrimitiveSerializer(this.network); + this.serializer = new ContractPrimitiveSerializerV2(this.network); } [Fact] diff --git a/src/Stratis.SmartContracts.CLR.Tests/Logs/RawLogTests.cs b/src/Stratis.SmartContracts.CLR.Tests/Logs/RawLogTests.cs index ca9db29bf5..6fa79b4edd 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/Logs/RawLogTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/Logs/RawLogTests.cs @@ -28,7 +28,7 @@ public Example(string name, uint amount) [Fact] public void RawLog_With_Null_Value_Serializes() { - var serializer = new ContractPrimitiveSerializer(new SmartContractsPoARegTest()); + var serializer = new ContractPrimitiveSerializerV2(new SmartContractsPoARegTest()); var exampleLog = new Example(null, 0); var rawLog = new RawLog(uint160.One, exampleLog); diff --git a/src/Stratis.SmartContracts.CLR.Tests/MethodParameterByteSerializerTests.cs b/src/Stratis.SmartContracts.CLR.Tests/MethodParameterByteSerializerTests.cs index 4de47c2f7b..16dd1848a8 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/MethodParameterByteSerializerTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/MethodParameterByteSerializerTests.cs @@ -12,7 +12,7 @@ namespace Stratis.SmartContracts.CLR.Tests public class MethodParameterByteSerializerTests { public static Network Network = new SmartContractsPoARegTest(); - public IMethodParameterSerializer Serializer = new MethodParameterByteSerializer(new ContractPrimitiveSerializer(Network)); + public IMethodParameterSerializer Serializer = new MethodParameterByteSerializer(new ContractPrimitiveSerializerV2(Network)); [Theory] [MemberData(nameof(GetData), parameters: 1)] diff --git a/src/Stratis.SmartContracts.CLR.Tests/ObserverInstanceRewriterTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ObserverInstanceRewriterTests.cs index b43b4ccb6c..1808d0ff05 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ObserverInstanceRewriterTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ObserverInstanceRewriterTests.cs @@ -118,7 +118,7 @@ public ObserverInstanceRewriterTests() var getBalance = new Func(() => Balance); var persistentState = new TestPersistentState(); var network = new SmartContractsRegTest(); - var serializer = new ContractPrimitiveSerializer(network); + var serializer = new ContractPrimitiveSerializerV2(network); this.state = new SmartContractState( new Block(1, this.TestAddress), new Message(this.TestAddress, this.TestAddress, 0), diff --git a/src/Stratis.SmartContracts.CLR.Tests/ObserverTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ObserverTests.cs index 9e4896992a..2dc80827bc 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ObserverTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ObserverTests.cs @@ -117,7 +117,7 @@ public ObserverTests() var getBalance = new Func(() => Balance); var persistentState = new TestPersistentState(); var network = new SmartContractsRegTest(); - var serializer = new ContractPrimitiveSerializer(network); + var serializer = new ContractPrimitiveSerializerV2(network); this.state = new SmartContractState( new Block(1, this.TestAddress), new Message(this.TestAddress, this.TestAddress, 0), diff --git a/src/Stratis.SmartContracts.CLR.Tests/SerializerTests.cs b/src/Stratis.SmartContracts.CLR.Tests/SerializerTests.cs index 2a359e2f48..4252007a78 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/SerializerTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/SerializerTests.cs @@ -259,7 +259,7 @@ public void SingleByteStringSerializesCorrectly() { const string test = "1"; - var testSerializer = new Serializer(new ContractPrimitiveSerializer(new SmartContractsPoARegTest())); + var testSerializer = new Serializer(new ContractPrimitiveSerializerV2(new SmartContractsPoARegTest())); byte[] bytes = testSerializer.Serialize(test); diff --git a/src/Stratis.SmartContracts.IntegrationTests/ContractExecutionFailureTests.cs b/src/Stratis.SmartContracts.IntegrationTests/ContractExecutionFailureTests.cs index d6dad303e9..22d55f34f6 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/ContractExecutionFailureTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/ContractExecutionFailureTests.cs @@ -38,7 +38,7 @@ protected ContractExecutionFailureTests(T fixture) public void ContractTransaction_Invalid_MethodParamSerialization() { // Create poorly serialized method params - var serializer = new CallDataSerializer(new ContractPrimitiveSerializer(this.node1.CoreNode.FullNode.Network)); + var serializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(this.node1.CoreNode.FullNode.Network)); var txData = serializer.Serialize(new ContractTxData(1, 1, (Gas)(GasPriceList.BaseCost + 1), new uint160(1), "Test")); diff --git a/src/Stratis.SmartContracts.IntegrationTests/ContractParameterSerializationTests.cs b/src/Stratis.SmartContracts.IntegrationTests/ContractParameterSerializationTests.cs index 6ec3b8ac06..b9eb17192b 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/ContractParameterSerializationTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/ContractParameterSerializationTests.cs @@ -24,7 +24,7 @@ protected ContractParameterSerializationTests(T fixture) this.mockChain = fixture.Chain; this.node1 = this.mockChain.Nodes[0]; this.node2 = this.mockChain.Nodes[1]; - this.serializer = new ContractPrimitiveSerializer(this.node1.CoreNode.FullNode.Network); + this.serializer = new ContractPrimitiveSerializerV2(this.node1.CoreNode.FullNode.Network); } [Retry] diff --git a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMemoryPoolTests.cs b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMemoryPoolTests.cs index 69f8935f8e..7881ee42e2 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMemoryPoolTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMemoryPoolTests.cs @@ -47,7 +47,7 @@ public void SmartContracts_AddToMempool_OnlyValid() { var stratisNodeSync = builder.CreateSmartContractPowNode().WithWallet().Start(); - var callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(stratisNodeSync.FullNode.Network)); + var callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(stratisNodeSync.FullNode.Network)); TestHelper.MineBlocks(stratisNodeSync, 2); // coinbase maturity = 0 for this network diff --git a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMinerTests.cs b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMinerTests.cs index d379e7120d..c3c2f7ef78 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMinerTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractMinerTests.cs @@ -340,13 +340,13 @@ private void InitializeSmartContractComponents(string callingMethod) this.AddressGenerator = new AddressGenerator(); this.assemblyLoader = new ContractAssemblyLoader(); - this.callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializer(this.network)); + this.callDataSerializer = new CallDataSerializer(new ContractPrimitiveSerializerV2(this.network)); this.moduleDefinitionReader = new ContractModuleDefinitionReader(); this.contractCache = new ContractAssemblyCache(); this.reflectionVirtualMachine = new ReflectionVirtualMachine(this.validator, this.loggerFactory, this.assemblyLoader, this.moduleDefinitionReader, this.contractCache); this.stateProcessor = new StateProcessor(this.reflectionVirtualMachine, this.AddressGenerator); this.internalTxExecutorFactory = new InternalExecutorFactory(this.loggerFactory, this.stateProcessor); - this.primitiveSerializer = new ContractPrimitiveSerializer(this.network); + this.primitiveSerializer = new ContractPrimitiveSerializerV2(this.network); this.serializer = new Serializer(this.primitiveSerializer); this.smartContractStateFactory = new SmartContractStateFactory(this.primitiveSerializer, this.internalTxExecutorFactory, this.serializer); this.stateFactory = new StateFactory(this.smartContractStateFactory); @@ -912,7 +912,7 @@ public async Task SmartContracts_TransferFunds_Invokes_Receive_Async() byte[] receiveInvoked = context.StateRoot.GetStorageValue(receiveContractAddress2, Encoding.UTF8.GetBytes("ReceiveInvoked")); byte[] fundsReceived = context.StateRoot.GetStorageValue(receiveContractAddress2, Encoding.UTF8.GetBytes("ReceivedFunds")); - var serializer = new ContractPrimitiveSerializer(context.network); + var serializer = new ContractPrimitiveSerializerV2(context.network); Assert.NotNull(receiveInvoked); Assert.NotNull(fundsReceived); From 543c4cde5b3eb7d97d87341ba4c4053d82e3160e Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 18:38:15 +1300 Subject: [PATCH 4/8] Add tests --- .../ContractPrimitiveSerializerV1Tests.cs | 26 +++++++++++++++++++ .../ContractPrimitiveSerializerV2Tests.cs | 7 +++++ 2 files changed, 33 insertions(+) create mode 100644 src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV1Tests.cs diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV1Tests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV1Tests.cs new file mode 100644 index 0000000000..206e043d59 --- /dev/null +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV1Tests.cs @@ -0,0 +1,26 @@ +using NBitcoin; +using Stratis.SmartContracts.CLR.Serialization; +using Stratis.SmartContracts.Networks; +using Xunit; + +namespace Stratis.SmartContracts.CLR.Tests +{ + public class ContractPrimitiveSerializerV1Tests + { + private readonly IContractPrimitiveSerializer serializer; + private readonly Network network; + + public ContractPrimitiveSerializerV1Tests() + { + this.network = new SmartContractsRegTest(); + this.serializer = new ContractPrimitiveSerializerV1(this.network); + } + + [Fact] + public void Test_ReferenceType_Serialization() + { + Assert.Null(this.serializer.Deserialize(typeof(string), this.serializer.Serialize(""))); + Assert.Null(this.serializer.Deserialize(typeof(byte[]), this.serializer.Serialize(new byte[0]))); + } + } +} \ No newline at end of file diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs index 1787cae741..bea7424a3e 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractPrimitiveSerializerV2Tests.cs @@ -173,6 +173,13 @@ public void Deserialize_Empty_Byte_Array() Assert.True(emptyByte.SequenceEqual(this.serializer.Deserialize(empty))); } + [Fact] + public void Test_ReferenceType_Serialization() + { + Assert.Equal("", this.serializer.Deserialize(typeof(string), this.serializer.Serialize(""))); + Assert.Equal(new byte[0], this.serializer.Deserialize(typeof(byte[]), this.serializer.Serialize(new byte[0]))); + } + private TestValueType NewTestValueType() { var instance = new TestValueType(); From 5f82caa3a8d4d1cb8933ce45ccd9dc563954e377 Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 18:55:02 +1300 Subject: [PATCH 5/8] Use activation height --- .../PoAConsensusOptions.cs | 6 ++++++ src/Stratis.Sidechains.Networks/CirrusTest.cs | 3 ++- .../Serialization/ContractPrimitiveSerializer.cs | 13 +++++++++---- .../Stratis.SmartContracts.CLR.csproj | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs b/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs index 488f130581..fa38cdcb0f 100644 --- a/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs +++ b/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs @@ -61,6 +61,12 @@ public class PoAConsensusOptions : ConsensusOptions /// public int PollExpiryBlocks { get; set; } + /// + /// Defines when V2 of the contract serializer will be used. + /// I.e if tip <= ContractSerializerV2ActivationHeight, V1 will be used + /// + public int ContractSerializerV2ActivationHeight { get; set; } + /// Initializes values for networks that use block size rules. public PoAConsensusOptions( uint maxBlockBaseSize, diff --git a/src/Stratis.Sidechains.Networks/CirrusTest.cs b/src/Stratis.Sidechains.Networks/CirrusTest.cs index e28445b1a8..3fa2e5a0f5 100644 --- a/src/Stratis.Sidechains.Networks/CirrusTest.cs +++ b/src/Stratis.Sidechains.Networks/CirrusTest.cs @@ -130,7 +130,8 @@ public CirrusTest() EnforcedMinProtocolVersion = ProtocolVersion.CIRRUS_VERSION, // minimum protocol version which will be enforced at block height defined in EnforceMinProtocolVersionAtBlockHeight VotingManagerV2ActivationHeight = 1_999_500, Release1100ActivationHeight = 2_796_000, - PollExpiryBlocks = 450 // 2 hours + PollExpiryBlocks = 450, // 2 hours + ContractSerializerV2ActivationHeight = 2842681 }; var buriedDeployments = new BuriedDeploymentsArray diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs index 4e674aaaa1..e14f130129 100644 --- a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs @@ -5,6 +5,7 @@ using NBitcoin; using Nethereum.RLP; using Stratis.Bitcoin.Consensus; +using Stratis.Bitcoin.Features.PoA; using Stratis.SmartContracts.CLR.Exceptions; using TracerAttributes; @@ -17,19 +18,23 @@ namespace Stratis.SmartContracts.CLR.Serialization [NoTrace] public class ContractPrimitiveSerializer : ContractPrimitiveSerializerV2 { - private readonly IConsensusManager consensusManager; + private readonly Network network; + private readonly ChainIndexer chainIndexer; private readonly ContractPrimitiveSerializerV1 serializerV1; - public ContractPrimitiveSerializer(Network network, IConsensusManager consensusManager) + public ContractPrimitiveSerializer(Network network, ChainIndexer chainIndexer) : base(network) { - this.consensusManager = consensusManager; + this.network = network; + this.chainIndexer = chainIndexer; this.serializerV1 = new ContractPrimitiveSerializerV1(network); } public override object Deserialize(Type type, byte[] stream) { - if (this.consensusManager.Tip.Height > 0) // TODO + var v2ActivationHeight = (this.network.Consensus.Options as PoAConsensusOptions).ContractSerializerV2ActivationHeight; + + if (this.chainIndexer.Tip.Height <= v2ActivationHeight) return this.serializerV1.Deserialize(type, stream); return base.Deserialize(type, stream); diff --git a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj index bc62647bbf..c0a462423b 100644 --- a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj +++ b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj @@ -17,6 +17,7 @@ + From 06487bebc7aa97176b772acd5517ddf6b9bdf70d Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 20:30:12 +1300 Subject: [PATCH 6/8] Style --- src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs b/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs index fa38cdcb0f..6899e76a8b 100644 --- a/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs +++ b/src/Stratis.Bitcoin.Features.PoA/PoAConsensusOptions.cs @@ -63,7 +63,7 @@ public class PoAConsensusOptions : ConsensusOptions /// /// Defines when V2 of the contract serializer will be used. - /// I.e if tip <= ContractSerializerV2ActivationHeight, V1 will be used + /// I.e if tip <= ContractSerializerV2ActivationHeight, V1 will be used. /// public int ContractSerializerV2ActivationHeight { get; set; } From 90dd4f74ff97b786f059ce2579d49dc64e368fea Mon Sep 17 00:00:00 2001 From: Rowan de Haas Date: Wed, 8 Dec 2021 20:30:25 +1300 Subject: [PATCH 7/8] Add activation height --- src/Stratis.Sidechains.Networks/CirrusMain.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stratis.Sidechains.Networks/CirrusMain.cs b/src/Stratis.Sidechains.Networks/CirrusMain.cs index 331850e1dc..627c9f3ca5 100644 --- a/src/Stratis.Sidechains.Networks/CirrusMain.cs +++ b/src/Stratis.Sidechains.Networks/CirrusMain.cs @@ -179,7 +179,8 @@ public CirrusMain() InterFluxV2MainChainActivationHeight = 460_000, VotingManagerV2ActivationHeight = 1_683_000, // Tuesday, 12 January 2021 9:00:00 AM (Estimated) Release1100ActivationHeight = 3_426_950, // Monday, 20 December 2021 10:00:00 AM (Estimated) - PollExpiryBlocks = 50_000 // Roughly 9 days + PollExpiryBlocks = 50_000, // Roughly 9 days + ContractSerializerV2ActivationHeight = 3364000 }; var buriedDeployments = new BuriedDeploymentsArray From 1f57b3e4e8a02c3eb083844df4916969b7dfd550 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Wed, 8 Dec 2021 12:57:52 +0000 Subject: [PATCH 8/8] Fix Tests --- .../Serialization/ContractPrimitiveSerializer.cs | 10 +--------- .../PoW/SmartContractWalletTests.cs | 1 - 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs index e14f130129..b407e1fa8a 100644 --- a/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs +++ b/src/Stratis.SmartContracts.CLR/Serialization/ContractPrimitiveSerializer.cs @@ -1,12 +1,6 @@ using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; using NBitcoin; -using Nethereum.RLP; -using Stratis.Bitcoin.Consensus; using Stratis.Bitcoin.Features.PoA; -using Stratis.SmartContracts.CLR.Exceptions; using TracerAttributes; namespace Stratis.SmartContracts.CLR.Serialization @@ -32,9 +26,7 @@ public ContractPrimitiveSerializer(Network network, ChainIndexer chainIndexer) public override object Deserialize(Type type, byte[] stream) { - var v2ActivationHeight = (this.network.Consensus.Options as PoAConsensusOptions).ContractSerializerV2ActivationHeight; - - if (this.chainIndexer.Tip.Height <= v2ActivationHeight) + if (this.network.Consensus.Options is PoAConsensusOptions poaConsensusOptions && this.chainIndexer.Tip.Height <= poaConsensusOptions.ContractSerializerV2ActivationHeight) return this.serializerV1.Deserialize(type, stream); return base.Deserialize(type, stream); diff --git a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractWalletTests.cs b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractWalletTests.cs index 6f67c38631..f3fd993764 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractWalletTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/PoW/SmartContractWalletTests.cs @@ -18,7 +18,6 @@ using Stratis.Bitcoin.Tests.Common; using Stratis.SmartContracts.CLR; using Stratis.SmartContracts.CLR.Compilation; -using Stratis.SmartContracts.CLR.Local; using Stratis.SmartContracts.CLR.Serialization; using Stratis.SmartContracts.Core; using Stratis.SmartContracts.Networks;