Пример #1
0
        public void Validate_Determinism_AnonymousClassFloats()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new
            {
                Prop1 = 6.8
            };").Replace(ReplaceReferencesString, "");

            byte[] assemblyBytes = ContractCompiler.Compile(adjustedSource).Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #2
0
        public void Validate_Determinism_DynamicTypeAllowed()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, "dynamic test = 56; test = \"aString\"; ").Replace(ReplaceReferencesString, "");
            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.True(result.IsValid);
        }
Пример #3
0
        public void ValidateAnonymousClassesDisallowed()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new
            {
                Test = ""Stratis""
            };").Replace(ReplaceReferencesString, "");

            byte[] assemblyBytes = SmartContractCompiler.Compile(adjustedSource).Compilation;
            IContractModuleDefinition     moduleDefinition = SmartContractDecompiler.GetModuleDefinition(assemblyBytes);
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #4
0
        public void Validate_Determinism_GetHashCode()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, "int hashCode = GetHashCode();").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #5
0
        public void Validate_Determinism_KnownBadMethodCall()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"var floor = System.Math.Floor(12D);").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #6
0
        public void Validate_Determinism_Nullable_Fails()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, "int? test = null;").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource, OptimizationLevel.Debug);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #7
0
        public void Validate_Determinism_Fails_Array_Clone()
        {
            string code = @"
            var test = new int[25];
            var ret = test.Clone();";

            string adjustedSource = TestString.Replace(ReplaceCodeString, code).Replace(ReplaceReferencesString, "");

            byte[] assemblyBytes = ContractCompiler.Compile(adjustedSource).Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
        /// <summary>
        /// Invokes a method on an existing smart contract
        /// </summary>
        public VmExecutionResult ExecuteMethod(ISmartContractState contractState, MethodCall methodCall, byte[] contractCode, string typeName)
        {
            this.logger.LogTrace("(){0}:{1}", nameof(methodCall.Name), methodCall.Name);

            ContractByteCode code;

            using (IContractModuleDefinition moduleDefinition = this.moduleDefinitionReader.Read(contractCode))
            {
                moduleDefinition.InjectMethodGas(typeName, methodCall);

                code = moduleDefinition.ToByteCode();
            }

            Result <IContract> contractLoadResult = this.Load(
                code,
                typeName,
                contractState.Message.ContractAddress.ToUint160(this.network),
                contractState);

            if (!contractLoadResult.IsSuccess)
            {
                // TODO this is temporary until we improve error handling overloads
                var exception = new Exception(contractLoadResult.Error);

                LogException(exception);

                this.logger.LogTrace("(-)[LOAD_CONTRACT_FAILED]");

                return(VmExecutionResult.Error(exception));
            }

            IContract contract = contractLoadResult.Value;

            LogExecutionContext(this.logger, contract.State.Block, contract.State.Message, contract.Address);

            IContractInvocationResult invocationResult = contract.Invoke(methodCall);

            if (!invocationResult.IsSuccess)
            {
                this.logger.LogTrace("(-)[CALLCONTRACT_INSTANTIATION_FAILED]");
                return(VmExecutionResult.Error(new Exception("Method invocation failed!")));
            }

            this.logger.LogTrace("[CALL_CONTRACT_INSTANTIATION_SUCCEEDED]");

            this.logger.LogTrace("(-)");

            return(VmExecutionResult.Success(invocationResult.Return, typeName));
        }
        /// <summary>
        /// Invokes a method on an existing smart contract
        /// </summary>
        public VmExecutionResult ExecuteMethod(ISmartContractState contractState, MethodCall methodCall, byte[] contractCode, string typeName)
        {
            this.logger.LogTrace("(){0}:{1}", nameof(methodCall.Name), methodCall.Name);

            ContractByteCode code;

            // Code we're loading from database - can assume it's valid.
            using (IContractModuleDefinition moduleDefinition = this.moduleDefinitionReader.Read(contractCode).Value)
            {
                var observer = new Observer(contractState.GasMeter, MemoryUnitLimit);
                var rewriter = new ObserverRewriter(observer);
                moduleDefinition.Rewrite(rewriter);
                code = moduleDefinition.ToByteCode();
            }

            Result <IContract> contractLoadResult = this.Load(
                code,
                typeName,
                contractState.Message.ContractAddress.ToUint160(this.network),
                contractState);

            if (!contractLoadResult.IsSuccess)
            {
                LogErrorMessage(contractLoadResult.Error);

                this.logger.LogTrace("(-)[LOAD_CONTRACT_FAILED]");

                return(VmExecutionResult.Fail(VmExecutionErrorKind.LoadFailed, contractLoadResult.Error));
            }

            IContract contract = contractLoadResult.Value;

            LogExecutionContext(this.logger, contract.State.Block, contract.State.Message, contract.Address);

            IContractInvocationResult invocationResult = contract.Invoke(methodCall);

            if (!invocationResult.IsSuccess)
            {
                this.logger.LogTrace("(-)[CALLCONTRACT_INSTANTIATION_FAILED]");

                return(GetInvocationVmErrorResult(invocationResult));
            }

            this.logger.LogTrace("[CALL_CONTRACT_INSTANTIATION_SUCCEEDED]");

            this.logger.LogTrace("(-)");

            return(VmExecutionResult.Ok(invocationResult.Return, typeName));
        }
        public void Validate_Determinism_MethodParams_Private()
        {
            string adjustedSource = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {
                                                public Test(ISmartContractState state)
                                                    : base(state) {}         

                                                private void PrivateStruct(TestStruct test)
                                                {
                                                }

                                                private void PrivateIntArray(int[] test)
                                                {
                                                }
                                                
                                                public void PublicIntArray(int[] test)
                                                {
                                                }

                                                public void PublicStruct(TestStruct test)
                                                {
                                                }

                                                internal void InternalStruct(TestStruct test)
                                                {
                                                }

                                                public struct TestStruct
                                                {
                                                    public int TestInt;
                                                }
                                            }";

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource, OptimizationLevel.Debug);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Equal(2, result.Errors.Count());
            Assert.Contains("PublicIntArray", result.Errors.ElementAt(0).Message);
            Assert.Contains("PublicStruct", result.Errors.ElementAt(1).Message);
        }
Пример #11
0
        public void Validate_Determinism_Floats()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, "float test = (float) 3.5; test = test + 1;").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Contains(result.Errors, e => e is FloatValidator.FloatValidationResult);
        }
        private bool Rewrite(IContractModuleDefinition moduleDefinition, IILRewriter rewriter)
        {
            try
            {
                moduleDefinition.Rewrite(rewriter);
                return(true);
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[CONTRACT_REWRITE_FAILED]");
            }

            return(false);
        }
Пример #13
0
        public void Validate_Determinism_Globalisation()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString,
                                                       "var r = System.Globalization.CultureInfo.CurrentCulture;")
                                    .Replace(ReplaceReferencesString, "");

            SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = SmartContractDecompiler.GetModuleDefinition(assemblyBytes);
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #14
0
        public void Validate_Determinism_Decimal()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, "decimal test = (decimal) 3.5; test = test / 2;").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.True(result.Errors.All(e => e is WhitelistValidator.WhitelistValidationResult));
            Assert.True(result.Errors.All(e => e.Message.Contains("Decimal")));
        }
        private Result <ContractByteCode> GetByteCode(IContractModuleDefinition moduleDefinition)
        {
            try
            {
                ContractByteCode code = moduleDefinition.ToByteCode();

                return(Result.Ok(code));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[CONTRACT_TOBYTECODE_FAILED]");

                return(Result.Fail <ContractByteCode>("Exception occurred while serializing module"));
            }
        }
Пример #16
0
        public void Validate_Determinism_TaskAwaiter()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString,
                                                       "var r = new System.Runtime.CompilerServices.TaskAwaiter();")
                                    .Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource, OptimizationLevel.Debug);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
Пример #17
0
        public void Validate_Determinism_BitConverter()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = BitConverter.IsLittleEndian;").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Single(result.Errors);
            Assert.IsAssignableFrom <WhitelistValidator.WhitelistValidationResult>(result.Errors.Single());
        }
Пример #18
0
        public void Validate_Determinism_ActivatorNotAllowed()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"Address ts = System.Activator.CreateInstance<Address>();").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Single(result.Errors);
            Assert.IsAssignableFrom <WhitelistValidator.WhitelistValidationResult>(result.Errors.Single());
        }
Пример #19
0
        private IContract GetContractAfterRewrite(string filename)
        {
            ContractCompilationResult compilationResult = ContractCompiler.CompileFile(filename);

            Assert.True(compilationResult.Success);

            byte[] originalAssemblyBytes = compilationResult.Compilation;

            IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value;

            module.Rewrite(this.rewriter);

            CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode());

            return(Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null));
        }
Пример #20
0
        public void Validate_Determinism_ValidateActionDisallowed()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new Action(() =>
            {
                var insideAction = DateTime.Now;
            });
            test();").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
        }
        public void SmartContractValidator_Allow_SingleContract()
        {
            const string source = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {                                              
                                                public Test(ISmartContractState state)
                                                    : base(state) { }
                                            }";

            IContractModuleDefinition decompilation = CompileToModuleDef(source);

            SmartContractValidationResult result = new SmartContractValidator().Validate(decompilation.ModuleDefinition);

            Assert.True(result.IsValid);
            Assert.Empty(result.Errors);
        }
        public void SmartContractValidator_Should_Allow_Consts()
        {
            const string source = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {                                              
                                                public const string Item = ""Test"";
                                                public Test(ISmartContractState state)
                                                    : base(state) { var abc = Item.Length; }
                                            }";

            IContractModuleDefinition decompilation = CompileToModuleDef(source);

            SmartContractValidationResult result = new SmartContractValidator().Validate(decompilation.ModuleDefinition);

            Assert.True(result.IsValid);
        }
Пример #23
0
        public void SmartContractValidator_Should_Validate_Internal_Types()
        {
            var adjustedSource = @"
using System;
using Stratis.SmartContracts;

[Deploy]
public class Test : SmartContract
{
    public Test(ISmartContractState state): base(state) 
    {
        Create<Test2>();
    }
}

public class Test2 : SmartContract {
    public Test2(ISmartContractState state): base(state) {
        PersistentState.SetString(""dt"", DateTime.Now.ToString());
    }
}
";
            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition decompilation = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;

            var moduleDefinition = decompilation.ModuleDefinition;

            var moduleType = moduleDefinition.GetType("<Module>");

            moduleDefinition.Types.Remove(moduleType);

            var internalType = moduleDefinition.GetType("Test2");

            internalType.Name = "<Module>";

            SmartContractValidationResult result = new SmartContractValidator().Validate(moduleDefinition);

            Assert.False(result.IsValid);
            Assert.NotEmpty(result.Errors);
            Assert.True(result.Errors.All(e => e is WhitelistValidator.WhitelistValidationResult));
        }
Пример #24
0
        public void Validate_Determinism_ErrorMessages_Referenced_ThreeLevels()
        {
            string source = @"
                    using Stratis.SmartContracts;

                    public class MessageTest : SmartContract
                    {
                        public MessageTest(ISmartContractState smartContractState)
                            : base(smartContractState)
                        {
                        }

                        public void MessageTestValid()
                        {
                            MessageTestValid1();
                        }

                        public void MessageTestValid1()
                        {
                            MessageTestValid2();
                        }

                        public void MessageTestValid2()
                        {
                            MessageTestFloat1();
                        }

                        public void MessageTestFloat1()
                        {
                            float test = (float) 3.5;
                        }
                    }";

            SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(source);

            Assert.True(compilationResult.Success);

            IContractModuleDefinition     moduleDefinition = SmartContractDecompiler.GetModuleDefinition(compilationResult.Compilation);
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Single(result.Errors);
            Assert.Equal("Float usage", result.Errors.First().ValidationType);
        }
Пример #25
0
        public void Validate_Determinism_StringIteration()
        {
            string adjustedSource = TestString.Replace(ReplaceCodeString,
                                                       @"int randomNumber = 0;
                  foreach (byte c in ""Abcdefgh"")
                  {
                    randomNumber += c;
                  }").Replace(ReplaceReferencesString, "");

            ContractCompilationResult compilationResult = ContractCompiler.Compile(adjustedSource);

            Assert.True(compilationResult.Success);

            byte[] assemblyBytes = compilationResult.Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.True(result.IsValid);
        }
Пример #26
0
        public void SmartContractValidator_Should_Not_Allow_New_NestedReferenceType()
        {
            const string source = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {
                                                public class A {}

                                                public Test(ISmartContractState state)
                                                    : base(state) { }
                                            }";

            IContractModuleDefinition decompilation = CompileToModuleDef(source);

            SmartContractValidationResult result = new SmartContractValidator().Validate(decompilation.ModuleDefinition);

            Assert.Contains(result.Errors, e => e is NestedTypeIsValueTypeValidator.NestedTypeIsValueTypeValidationResult);
        }
Пример #27
0
        public void Validate_Determinism_Passes_Array_AllowedMembers()
        {
            string code = @"
            var test = new int[25];
            var test2 = new int[25];
            test[0] = 123;
            int ret = test[0];
            int len = test.Length;
            Array.Resize(ref test, 50);
            Array.Copy(test, test2, len);";

            string adjustedSource = TestString.Replace(ReplaceCodeString, code).Replace(ReplaceReferencesString, "");

            byte[] assemblyBytes = ContractCompiler.Compile(adjustedSource).Compilation;
            IContractModuleDefinition     moduleDefinition = ContractDecompiler.GetModuleDefinition(assemblyBytes).Value;
            SmartContractValidationResult result           = this.validator.Validate(moduleDefinition.ModuleDefinition);

            Assert.True(result.IsValid);
        }
        public void SmartContractValidator_Should_Not_Allow_Static_Constructors()
        {
            const string source = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {                                              
                                                static Test() {}                                                

                                                public Test(ISmartContractState state)
                                                    : base(state) { }
                                            }";

            IContractModuleDefinition decompilation = CompileToModuleDef(source);

            SmartContractValidationResult result = new SmartContractValidator().Validate(decompilation.ModuleDefinition);

            Assert.False(result.IsValid);
            Assert.Contains(result.Errors, e => e is StaticConstructorValidator.StaticConstructorValidationResult);
        }
        public void TestGasInjector_NestedType_GasInjectionSucceeds()
        {
            ContractCompilationResult compilationResult = ContractCompiler.Compile(@"
using System;
using Stratis.SmartContracts;

public class Test : SmartContract
{
    public Test(ISmartContractState state): base(state) {
        var other = new Other.NestedOther();
        other.Loop();
    }
}

public static class Other
{
    public struct NestedOther {
        public void Loop() { while(true) {}}
    }
}
");

            Assert.True(compilationResult.Success);

            byte[] originalAssemblyBytes = compilationResult.Compilation;

            IContractModuleDefinition module = this.moduleReader.Read(originalAssemblyBytes).Value;

            module.Rewrite(this.rewriter);

            CSharpFunctionalExtensions.Result <IContractAssembly> assembly = this.assemblyLoader.Load(module.ToByteCode());

            assembly.Value.SetObserver(new Observer(this.gasMeter, new MemoryMeter(ReflectionVirtualMachine.MemoryUnitLimit)));

            IContract contract = Contract.CreateUninitialized(assembly.Value.GetType(module.ContractType.Name), this.state, null);

            IContractInvocationResult result = contract.InvokeConstructor(null);

            Assert.False(result.IsSuccess);
            Assert.Equal(this.gasMeter.GasLimit, this.gasMeter.GasConsumed);
        }
        public void SmartContractValidator_Should_Allow_New_NestedType()
        {
            const string source = @"using System;
                                            using Stratis.SmartContracts;

                                            public class Test : SmartContract
                                            {
                                                public struct A {}

                                                public Test(ISmartContractState state)
                                                    : base(state) { }

                                                public void B() { var test = new A(); }
                                            }";

            IContractModuleDefinition decompilation = CompileToModuleDef(source);

            SmartContractValidationResult result = new SmartContractValidator().Validate(decompilation.ModuleDefinition);

            Assert.Empty(result.Errors);
        }