public void Validate_Determinism_ErrorMessages_Simple_DateTime() { string source = @" using Stratis.SmartContracts; using System; public class MessageTest : SmartContract { public MessageTest(ISmartContractState smartContractState) : base(smartContractState) { } public void MessageTestDateTime() { var test = DateTime.Now; } }"; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(source); Assert.True(compilationResult.Success); SmartContractDecompilation decompilation = SmartContractDecompiler.GetModuleDefinition(compilationResult.Compilation); SmartContractValidationResult result = this.validator.Validate(decompilation); Assert.False(result.IsValid); Assert.Single(result.Errors); Assert.Equal(SmartContractDeterminismValidator.NonDeterministicMethodReference, result.Errors.First().ValidationType); }
public void Validate_Determinism_DisallowedMethodParams() { string adjustedSource = @"using System; using Stratis.SmartContracts; public class Test : SmartContract { public Test(ISmartContractState state) : base(state) {} public void DateTime1(DateTime param) { } public void F(float param) { } }"; 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); Assert.Equal(2, result.Errors.Count()); Assert.True(result.Errors.All(e => e is MethodParamValidator.MethodParamValidationResult)); Assert.Contains(result.Errors, e => e.Message.Contains("System.DateTime")); Assert.Contains(result.Errors, e => e.Message.Contains("System.Single")); }
public void SmartContracts_GasInjector_MultipleParamConstructorGasInjectedSuccess() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestMultipleConstructorSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var gasLimit = (Gas)500000; var gasMeter = new GasMeter(gasLimit); var internalTxExecutorFactory = new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network); var vm = new ReflectionVirtualMachine(this.validator, internalTxExecutorFactory, this.loggerFactory, this.network, this.addressGenerator); var callData = new CreateData(gasLimit, originalAssemblyBytes, new[] { "Test Owner" }); var transactionContext = new TransactionContext( txHash: uint256.One, blockHeight: 0, coinbase: TestAddress.ToUint160(this.network), sender: TestAddress.ToUint160(this.network), amount: 0 ); VmExecutionResult result = vm.Create(gasMeter, this.repository, callData, transactionContext); // Constructor: 15 // Property setter: 12 // Storage: 150 Assert.Equal((Gas)177, result.GasConsumed); }
public void Validate_Determinism_ErrorMessages_Referenced_OneLevel() { string source = @" using Stratis.SmartContracts; public class MessageTest : SmartContract { public MessageTest(ISmartContractState smartContractState) : base(smartContractState) { } public void MessageTestValid() { MessageTestFloat1(); } public void MessageTestFloat1() { float test = (float) 3.5; test = test + 1; } }"; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(source); Assert.True(compilationResult.Success); SmartContractDecompilation decompilation = SmartContractDecompiler.GetModuleDefinition(compilationResult.Compilation); SmartContractValidationResult result = this.validator.Validate(decompilation); Assert.False(result.IsValid); Assert.Single(result.Errors); Assert.Equal("Float usage", result.Errors.First().ValidationType); }
public void SmartContracts_GasInjector_MultipleParamConstructorGasInjectedSuccess() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestMultipleConstructorSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var gasLimit = (Gas)500000; var gasMeter = new GasMeter(gasLimit); var persistenceStrategy = new MeteredPersistenceStrategy(this.repository, gasMeter, new BasicKeyEncodingStrategy()); var persistentState = new PersistentState(persistenceStrategy, TestAddress.ToUint160(this.network), this.network); var internalTxExecutorFactory = new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network); var vm = new ReflectionVirtualMachine(internalTxExecutorFactory, this.loggerFactory); var executionContext = new SmartContractExecutionContext(new Block(0, TestAddress), new Message(TestAddress, TestAddress, 0, (Gas)500000), TestAddress.ToUint160(this.network), 1, new[] { "Tset Owner" }); var result = vm.Create( originalAssemblyBytes, executionContext, gasMeter, persistentState, repository); // Constructor: 15 // Property setter: 12 // Storage: 150 Assert.Equal((Gas)177, result.GasConsumed); }
public void Validate_Determinism_Recursion() { string source = @" using Stratis.SmartContracts; public class RecursionTest : SmartContract { public RecursionTest(ISmartContractState smartContractState) : base(smartContractState) { } public void Bid() { Job(5); } public void Job(int index) { if (index > 0) Job(index - 1); } }"; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(source); Assert.True(compilationResult.Success); IContractModuleDefinition moduleDefinition = SmartContractDecompiler.GetModuleDefinition(compilationResult.Compilation); SmartContractValidationResult result = this.validator.Validate(moduleDefinition.ModuleDefinition); Assert.True(result.IsValid); }
public void SmartContract_ValidateFormat_TwoTypes() { var adjustedSource = @" using System; using Stratis.SmartContracts; public class Test : SmartContract { public Test(ISmartContractState state) : base(state) {} } public class Test2 { } "; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.True(compilationResult.Success); var validator = new SmartContractFormatValidator(); byte[] assemblyBytes = compilationResult.Compilation; IContractModuleDefinition decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); var result = validator.Validate(decomp.ModuleDefinition); Assert.False(result.IsValid); Assert.Equal(2, result.Errors.Count()); }
public void Validate_Determinism_ErrorMessages_Simple_DateTime() { string source = @" using Stratis.SmartContracts; using System; public class MessageTest : SmartContract { public MessageTest(ISmartContractState smartContractState) : base(smartContractState) { } public void MessageTestDateTime() { var test = DateTime.Now; } }"; 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.True(result.Errors.All(e => e is WhitelistValidator.WhitelistValidationResult)); }
public void SmartContracts_GasInjector_SingleParamConstructorGasInjectedSuccess() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSingleConstructorSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var gasLimit = (Gas)500000; var gasMeter = new GasMeter(gasLimit); var callData = new CreateData(gasLimit, originalAssemblyBytes); var transactionContext = new TransactionContext( txHash: uint256.One, blockHeight: 0, coinbase: TestAddress.ToUint160(this.network), sender: TestAddress.ToUint160(this.network), amount: 0 ); VmExecutionResult result = this.vm.Create(gasMeter, this.repository, callData, transactionContext); // TODO: Un-hard-code this. // Constructor: 15 // Property setter: 12 // Storage: 150 Assert.Equal((Gas)177, result.GasConsumed); }
public void Validate_Determinism_ErrorMessages_TwoMethods() { string source = @" using Stratis.SmartContracts; public class MessageTest : SmartContract { public MessageTest(ISmartContractState smartContractState) : base(smartContractState) { } public void MessageTestFloat1() { float test = (float) 3.5; } public void MessageTestFloat2() { 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.Equal(2, result.Errors.Count()); Assert.Equal("Float usage", result.Errors.First().ValidationType); Assert.Equal("Float usage", result.Errors.Skip(1).Take(1).First().ValidationType); }
public void SmartContract_ValidateFormat_One_CustomStruct() { var adjustedSource = @" using System; using Stratis.SmartContracts; public class StructTest : SmartContract { public struct Item { public int Number; public string Name; } public StructTest(ISmartContractState state) : base(state) { } } "; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.True(compilationResult.Success); var validator = new NestedTypeValidator(); byte[] assemblyBytes = compilationResult.Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); IEnumerable <ValidationResult> result = validator.Validate(decomp.ContractType); Assert.Empty(result); }
public void Validate_Determinism_Async() { string adjustedSource = @"using System; using Stratis.SmartContracts; using System.Threading.Tasks; public class Test : SmartContract { public Test(ISmartContractState state) : base(state) {} public async void Bid() { await Task.Run(job); } public async Task job() { int w = 9; } }"; 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); }
public void SmartContract_ValidateFormat_InitializedReadonlyField_Fails() { var adjustedSource = @" using System; using Stratis.SmartContracts; public class FieldTest : SmartContract { private readonly int field1 = 1234567; public FieldTest(ISmartContractState state) : base(state) { } } "; SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.True(compilationResult.Success); var validator = new FieldDefinitionValidator(); byte[] assemblyBytes = compilationResult.Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); IEnumerable <ValidationResult> result = validator.Validate(decomp.ContractType); Assert.NotEmpty(result); }
public void SmartContract_Compiler_ReturnsTrue() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile("class C{static void M(){}}"); Assert.True(compilationResult.Success); Assert.Empty(compilationResult.Diagnostics); Assert.NotNull(compilationResult.Compilation); }
public void SmartContract_Compiler_ReturnsFalse() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile("Uncompilable"); Assert.False(compilationResult.Success); Assert.NotEmpty(compilationResult.Diagnostics); Assert.Null(compilationResult.Compilation); }
public void Validate_Determinism_AppDomain() { // AppDomain should not be available // We do not compile contracts with a reference to System.Runtime.Extensions string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = AppDomain.CurrentDomain; var test2 = test.Id;").Replace(ReplaceReferencesString, ""); SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.False(compilationResult.Success); }
public void Validate_Determinism_Environment() { // Environment should not be available // We do not compile contracts with a reference to System.Runtime.Extensions string adjustedSource = TestString.Replace(ReplaceCodeString, "int test = Environment.TickCount;").Replace(ReplaceReferencesString, ""); SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.False(compilationResult.Success); }
public void Validate_Determinism_Fails_MultiDimensional_Arrays() { string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new int[50,50];").Replace(ReplaceReferencesString, ""); byte[] assemblyBytes = SmartContractCompiler.Compile(adjustedSource).Compilation; IContractModuleDefinition moduleDefinition = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(moduleDefinition.ModuleDefinition); Assert.False(result.IsValid); }
public void Validate_Determinism_Passes_ArrayConstruction_LessThan2() { string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new int[]{10167};").Replace(ReplaceReferencesString, ""); byte[] assemblyBytes = SmartContractCompiler.Compile(adjustedSource).Compilation; IContractModuleDefinition moduleDefinition = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(moduleDefinition.ModuleDefinition); Assert.True(result.IsValid); }
public SmartContractDecompilation CompileToModuleDef(string source) { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(source); Assert.True(compilationResult.Success); byte[] assemblyBytes = compilationResult.Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); return(decomp); }
public void Validate_Determinism_AnonymousClassFloats() { string adjustedSource = TestString.Replace(ReplaceCodeString, @"var test = new { Prop1 = 6.8 };").Replace(ReplaceReferencesString, ""); byte[] assemblyBytes = SmartContractCompiler.Compile(adjustedSource).Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(decomp); Assert.False(result.IsValid); }
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); }
public void Validate_Determinism_DynamicTypeAllowed() { string adjustedSource = TestString.Replace(ReplaceCodeString, "dynamic test = 56; test = \"aString\"; ").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.True(result.IsValid); }
public void Validate_Determinism_ActivatorNotAllowed() { string adjustedSource = TestString.Replace(ReplaceCodeString, @"Address ts = System.Activator.CreateInstance<Address>();").Replace(ReplaceReferencesString, ""); SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.True(compilationResult.Success); byte[] assemblyBytes = compilationResult.Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(decomp); Assert.False(result.IsValid); }
public void Validate_Determinism_KnownBadMethodCall() { string adjustedSource = TestString.Replace(ReplaceCodeString, @"var floor = System.Math.Floor(12D);").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); }
public void Validate_Determinism_GetHashCode() { string adjustedSource = TestString.Replace(ReplaceCodeString, "int hashCode = GetHashCode();").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); }
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 = SmartContractCompiler.Compile(adjustedSource).Compilation; IContractModuleDefinition moduleDefinition = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(moduleDefinition.ModuleDefinition); Assert.False(result.IsValid); }
public void Validate_Determinism_Decimal() { string adjustedSource = TestString.Replace(ReplaceCodeString, "decimal test = (decimal) 3.5; test = test / 2;").Replace(ReplaceReferencesString, ""); SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(adjustedSource); Assert.True(compilationResult.Success); byte[] assemblyBytes = compilationResult.Compilation; SmartContractDecompilation decomp = SmartContractDecompiler.GetModuleDefinition(assemblyBytes); SmartContractValidationResult result = this.validator.Validate(decomp); Assert.False(result.IsValid); }
public void TestGasInjector() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(AppContext.BaseDirectory); int aimGasAmount; using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule( new MemoryStream(originalAssemblyBytes), new ReaderParameters { AssemblyResolver = resolver })) { TypeDefinition contractType = moduleDefinition.GetType(ContractName); MethodDefinition testMethod = contractType.Methods.FirstOrDefault(x => x.Name == MethodName); aimGasAmount = testMethod?.Body?.Instructions? .Count ?? 10000000; } var gasLimit = (Gas)500000; var gasMeter = new GasMeter(gasLimit); var persistenceStrategy = new MeteredPersistenceStrategy(this.repository, gasMeter, this.keyEncodingStrategy); var persistentState = new PersistentState(persistenceStrategy, TestAddress.ToUint160(this.network), this.network); var internalTxExecutorFactory = new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network); var vm = new ReflectionVirtualMachine(internalTxExecutorFactory, this.loggerFactory); var executionContext = new SmartContractExecutionContext( new Block(0, TestAddress), new Message(TestAddress, TestAddress, 0, (Gas)500000), TestAddress.ToUint160(this.network), 1, new object[] { 1 }); var result = vm.ExecuteMethod( originalAssemblyBytes, MethodName, executionContext, gasMeter, persistentState, this.repository); Assert.Equal(aimGasAmount, Convert.ToInt32(result.GasConsumed)); }
public void TestGasInjector() { SmartContractCompilationResult compilationResult = SmartContractCompiler.Compile(TestSource); Assert.True(compilationResult.Success); byte[] originalAssemblyBytes = compilationResult.Compilation; var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(AppContext.BaseDirectory); int aimGasAmount; using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule( new MemoryStream(originalAssemblyBytes), new ReaderParameters { AssemblyResolver = resolver })) { TypeDefinition contractType = moduleDefinition.GetType(ContractName); MethodDefinition testMethod = contractType.Methods.FirstOrDefault(x => x.Name == MethodName); aimGasAmount = testMethod?.Body?.Instructions? .Count ?? 10000000; } var gasLimit = (Gas)500000; var gasMeter = new GasMeter(gasLimit); var internalTxExecutorFactory = new InternalTransactionExecutorFactory(this.keyEncodingStrategy, this.loggerFactory, this.network); var vm = new ReflectionVirtualMachine(this.validator, internalTxExecutorFactory, this.loggerFactory, this.network, this.addressGenerator); uint160 address = TestAddress.ToUint160(this.network); var callData = new CallData(gasLimit, address, "TestMethod", new object[] { 1 }); var transactionContext = new TransactionContext(uint256.One, 0, address, address, 0); this.repository.SetCode(callData.ContractAddress, originalAssemblyBytes); this.repository.SetContractType(callData.ContractAddress, "Test"); VmExecutionResult result = vm.ExecuteMethod(gasMeter, this.repository, callData, transactionContext); Assert.Equal((ulong)aimGasAmount, result.GasConsumed); }