public BatchExeResult Execute(string filename, out string expected, out string current) { BatchExeResult result = BatchExeResult.SolcError; string filePath = Path.Combine(testDirectory, filename); // compile the program SolidityCompiler compiler = new SolidityCompiler(); CompilerOutput compilerOutput = compiler.Compile(solcPath, filePath); if (compilerOutput.ContainsError()) { compilerOutput.PrintErrorsToConsole(); throw new SystemException("Compilation Error"); } // build the Solidity AST from solc output AST solidityAST = new AST(compilerOutput, Path.GetDirectoryName(filePath)); // translate Solidity to Boogie try { BoogieTranslator translator = new BoogieTranslator(); var translatorFlags = new TranslatorFlags(); translatorFlags.GenerateInlineAttributes = false; BoogieAST boogieAST = translator.Translate(solidityAST, new HashSet <Tuple <string, string> >(), translatorFlags); // dump the Boogie program to a file using (var outWriter = new StreamWriter(outFile)) { outWriter.WriteLine(boogieAST.GetRoot()); } } catch (Exception e) { Console.WriteLine($"VeriSol translation error: {e.Message}"); result = BatchExeResult.SolToBoogieError; expected = current = null; return(result); } // read the corral configuration from Json string configJsonPath = Path.Combine(configDirectory, Path.GetFileNameWithoutExtension(filename) + ".json"); string jsonString = File.ReadAllText(configJsonPath); CorralConfiguration corralConfig = JsonConvert.DeserializeObject <CorralConfiguration>(jsonString); string corralOutput = RunCorral(corralConfig); expected = corralConfig.ExpectedResult; current = corralOutput; result = CompareCorralOutput(corralConfig.ExpectedResult, corralOutput); return(result); }
public VeriSolExecutor(string solidityFilePath, string contractName, int corralRecursionLimit, HashSet <Tuple <string, string> > ignoreMethods, bool tryRefutation, bool tryProofFlag, ILogger logger, bool _printTransactionSequence, TranslatorFlags _translatorFlags = null) { this.SolidityFilePath = solidityFilePath; this.ContractName = contractName; this.SolidityFileDir = Path.GetDirectoryName(solidityFilePath); Console.WriteLine($"SpecFilesDir = {SolidityFileDir}"); this.CorralPath = ExternalToolsManager.Corral.Command; this.BoogiePath = ExternalToolsManager.Boogie.Command; this.SolcPath = ExternalToolsManager.Solc.Command; this.CorralRecursionLimit = corralRecursionLimit; this.ignoreMethods = new HashSet <Tuple <string, string> >(ignoreMethods); this.Logger = logger; this.TryProof = tryProofFlag; this.TryRefutation = tryRefutation; this.printTransactionSequence = _printTransactionSequence; //this.GenInlineAttrs = genInlineAttrs; this.translatorFlags = _translatorFlags; }
public static int Main(string[] args) { if (args.Length < 2) { ShowUsage(); return(1); } ExternalToolsManager.EnsureAllExisted(); string solidityFile, entryPointContractName; bool tryProofFlag, tryRefutation; int recursionBound; ILogger logger; HashSet <Tuple <string, string> > ignoredMethods; bool printTransactionSequence = false; TranslatorFlags translatorFlags = new TranslatorFlags(); ParseCommandLineArgs(args, out solidityFile, out entryPointContractName, out tryProofFlag, out tryRefutation, out recursionBound, out logger, out ignoredMethods, out printTransactionSequence, ref translatorFlags); var verisolExecuter = new VeriSolExecutor( Path.Combine(Directory.GetCurrentDirectory(), solidityFile), entryPointContractName, recursionBound, ignoredMethods, tryRefutation, tryProofFlag, logger, printTransactionSequence, translatorFlags); return(verisolExecuter.Execute()); }
private void ParseTranslatorFlags(TranslatorFlags translatorFlags, string args) { string solidityFile, entryPointContractName; bool tryProofFlag, tryRefutation; int recursionBound; ILogger logger; HashSet <Tuple <string, string> > ignoredMethods; bool printTransactionSequence = false; string verisolCmdLineArgs = "Foo Bar " + args; //Parser expects dirst two args to be present SolToBoogie.ParseUtils.ParseCommandLineArgs(verisolCmdLineArgs.Split(" "), out solidityFile, out entryPointContractName, out tryProofFlag, out tryRefutation, out recursionBound, out logger, out ignoredMethods, out printTransactionSequence, ref translatorFlags); }
private bool ExecuteSolToBoogie() { // compile the program Console.WriteLine($"\n----- Running Solc on {SpecFilePath}...."); SolidityCompiler compiler = new SolidityCompiler(); CompilerOutput compilerOutput = compiler.Compile(SolcPath, SpecFilePath); if (compilerOutput.ContainsError()) { compilerOutput.PrintErrorsToConsole(); throw new SystemException("Compilation Error"); } // build the Solidity AST from solc output AST solidityAST = new AST(compilerOutput, Path.GetDirectoryName(SpecFilePath)); // translate Solidity to Boogie try { BoogieTranslator translator = new BoogieTranslator(); Console.WriteLine($"\n----- Running SolToBoogie...."); var translatorFlags = new TranslatorFlags(); translatorFlags.GenerateInlineAttributes = true; BoogieAST boogieAST = translator.Translate(solidityAST, ignoreMethods, translatorFlags); // dump the Boogie program to a file var outFilePath = Path.Combine(SpecFileDir, outFileName); using (var outWriter = new StreamWriter(outFileName)) { outWriter.WriteLine(boogieAST.GetRoot()); } } catch (Exception e) { Console.WriteLine($"VeriSol translation error: {e.Message}"); return(false); } return(true); }
public static int Main(string[] args) { if (args.Length < 2) { ShowUsage(); return(1); } string solidityFile, entryPointContractName, solcName; bool tryProofFlag, tryRefutation; int recursionBound; ILogger logger; HashSet <Tuple <string, string> > ignoredMethods; bool printTransactionSequence = false; TranslatorFlags translatorFlags = new TranslatorFlags(); ParseCommandLineArgs(args, out solidityFile, out entryPointContractName, out tryProofFlag, out tryRefutation, out recursionBound, out solcName, out logger, out ignoredMethods, out printTransactionSequence, ref translatorFlags); var assemblyLocation = Assembly.GetExecutingAssembly().Location; string solcPath = Path.Combine( Path.GetDirectoryName(assemblyLocation), solcName); if (!File.Exists(solcPath)) { ShowUsage(); Console.WriteLine($"Cannot find {solcName} at {solcPath}"); return(1); } string corralPath = Path.Combine( Path.GetDirectoryName(assemblyLocation), "corral.dll"); if (!File.Exists(corralPath)) { ShowUsage(); Console.WriteLine($"Cannot find corral.dll at {corralPath}"); return(1); } string boogiePath = Path.Combine( Path.GetDirectoryName(assemblyLocation), "BoogieDriver.dll"); if (!File.Exists(boogiePath)) { ShowUsage(); Console.WriteLine($"Cannot find BoogieDriver.dll at {boogiePath}"); return(1); } var verisolExecuter = new VeriSolExecutor( Path.Combine(Directory.GetCurrentDirectory(), solidityFile), entryPointContractName, corralPath, boogiePath, solcPath, solcName, recursionBound, ignoredMethods, tryRefutation, tryProofFlag, logger, printTransactionSequence, translatorFlags); return(verisolExecuter.Execute()); }
private static void ParseCommandLineArgs(string[] args, out string solidityFile, out string entryPointContractName, out bool tryProofFlag, out bool tryRefutation, out int recursionBound, out string solcName, out ILogger logger, out HashSet <Tuple <string, string> > ignoredMethods, out bool printTransactionSeq, ref TranslatorFlags translatorFlags) { Console.WriteLine($"Command line args ==> {string.Join(", ", args.ToList())}"); solidityFile = args[0]; // Debug.Assert(!solidityFile.Contains("/"), $"Illegal solidity file name {solidityFile}"); //the file name can be foo/bar/baz.sol entryPointContractName = args[1]; Debug.Assert(!entryPointContractName.Contains("/"), $"Illegal contract name {entryPointContractName}"); tryProofFlag = args.Any(x => x.Equals("/tryProof")); tryRefutation = false; recursionBound = 2; if (args.Any(x => x.StartsWith("/tryRefutation:"))) { Debug.Assert(!tryRefutation, "Multiple declaration of /tryRefutation:k in command line"); var arg = args.First(x => x.StartsWith("/tryRefutation:")); tryRefutation = true; recursionBound = int.Parse(arg.Substring("/tryRefutation:".Length)); } solcName = GetSolcNameByOSPlatform(); ILoggerFactory loggerFactory = new LoggerFactory().AddConsole(LogLevel.Information); logger = loggerFactory.CreateLogger("VeriSol"); ignoredMethods = new HashSet <Tuple <string, string> >(); foreach (var arg in args.Where(x => x.StartsWith("/ignoreMethod:"))) { Debug.Assert(arg.Contains("@"), $"Error: incorrect use of /ignoreMethod in {arg}"); Debug.Assert(arg.LastIndexOf("@") == arg.IndexOf("@"), $"Error: incorrect use of /ignoreMethod in {arg}"); var str = arg.Substring("/ignoreMethod:".Length); var method = str.Substring(0, str.IndexOf("@")); var contract = str.Substring(str.IndexOf("@") + 1); ignoredMethods.Add(Tuple.Create(method, contract)); } if (args.Any(x => x.StartsWith("/ignoreMethod:"))) { Console.WriteLine($"Ignored method/contract pairs ==> \n\t {string.Join(",", ignoredMethods.Select(x => x.Item1 + "@" + x.Item2))}"); } translatorFlags.GenerateInlineAttributes = true; if (args.Any(x => x.Equals("/noInlineAttrs"))) { translatorFlags.GenerateInlineAttributes = false; if (tryProofFlag) { throw new Exception("/noInlineAttrs cannot be used when /tryProof is used"); } } if (args.Any(x => x.Equals("/break"))) { Debugger.Launch(); } if (args.Any(x => x.Equals("/omitSourceLineInfo"))) { translatorFlags.NoSourceLineInfoFlag = true; } if (args.Any(x => x.Equals("/omitDataValuesInTrace"))) { translatorFlags.NoDataValuesInfoFlag = true; } if (args.Any(x => x.Equals("/omitUnsignedSemantics"))) { translatorFlags.NoUnsignedAssumesFlag = true; } if (args.Any(x => x.Equals("/omitAxioms"))) { translatorFlags.NoAxiomsFlag = true; } if (args.Any(x => x.Equals("/omitHarness"))) { translatorFlags.NoHarness = true; } if (args.Any(x => x.Equals("/modelReverts"))) { translatorFlags.ModelReverts = true; } if (args.Any(x => x.Equals("/instrumentGas"))) { translatorFlags.InstrumentGas = true; } // don't perform verification for some of these omitFlags if (tryProofFlag || tryRefutation) { Debug.Assert(!translatorFlags.NoHarness && !translatorFlags.NoAxiomsFlag && !translatorFlags.NoUnsignedAssumesFlag && !translatorFlags.NoDataValuesInfoFlag && !translatorFlags.NoSourceLineInfoFlag, "Cannot perform verification when any of " + "/omitSourceLineInfo, " + "/omitDataValuesInTrace, " + "/omitAxioms, " + "/omitHarness, " + "/omitUnsignedSemantics are specified"); } printTransactionSeq = args.Any(x => x.Equals("/printTransactionSequence")); }
private static void ParseCommandLineArgs(string[] args, out string solidityFile, out string entryPointContractName, out bool tryProofFlag, out bool tryRefutation, out int recursionBound, out ILogger logger, out HashSet <Tuple <string, string> > ignoredMethods, out bool printTransactionSeq, ref TranslatorFlags translatorFlags) { Console.WriteLine($"Command line args = {{{string.Join(", ", args.ToList())}}}"); solidityFile = args[0]; // Debug.Assert(!solidityFile.Contains("/"), $"Illegal solidity file name {solidityFile}"); //the file name can be foo/bar/baz.sol entryPointContractName = args[1]; Debug.Assert(!entryPointContractName.Contains("/"), $"Illegal contract name {entryPointContractName}"); tryProofFlag = !(args.Any(x => x.Equals("/noPrf")) || args.Any(x => x.Equals("/noChk"))); //args.Any(x => x.Equals("/tryProof")); tryRefutation = !args.Any(x => x.Equals("/noChk")); recursionBound = 4; var txBounds = args.Where(x => x.StartsWith("/txBound:")); if (txBounds.Count() > 0) { Debug.Assert(txBounds.Count() == 1, $"At most 1 /txBound:k expected, found {txBounds.Count()}"); recursionBound = int.Parse(txBounds.First().Substring("/txBound:".Length)); Debug.Assert(recursionBound > 0, $"Argument of /txBound:k should be positive, found {recursionBound}"); } ILoggerFactory loggerFactory = new LoggerFactory().AddConsole(LogLevel.Information); logger = loggerFactory.CreateLogger("VeriSol"); ignoredMethods = new HashSet <Tuple <string, string> >(); foreach (var arg in args.Where(x => x.StartsWith("/ignoreMethod:"))) { Debug.Assert(arg.Contains("@"), $"Error: incorrect use of /ignoreMethod in {arg}"); Debug.Assert(arg.LastIndexOf("@") == arg.IndexOf("@"), $"Error: incorrect use of /ignoreMethod in {arg}"); var str = arg.Substring("/ignoreMethod:".Length); var method = str.Substring(0, str.IndexOf("@")); var contract = str.Substring(str.IndexOf("@") + 1); ignoredMethods.Add(Tuple.Create(method, contract)); } if (args.Any(x => x.StartsWith("/ignoreMethod:"))) { Console.WriteLine($"Ignored method/contract pairs ==> \n\t {string.Join(",", ignoredMethods.Select(x => x.Item1 + "@" + x.Item2))}"); } translatorFlags.GenerateInlineAttributes = true; if (args.Any(x => x.Equals("/noInlineAttrs"))) { translatorFlags.GenerateInlineAttributes = false; if (tryProofFlag) { throw new Exception("/noInlineAttrs cannot be used when /tryProof is used"); } } if (args.Any(x => x.Equals("/break"))) { Debugger.Launch(); } if (args.Any(x => x.Equals("/omitSourceLineInfo"))) { translatorFlags.NoSourceLineInfoFlag = true; } if (args.Any(x => x.Equals("/omitDataValuesInTrace"))) { translatorFlags.NoDataValuesInfoFlag = true; } if (args.Any(x => x.Equals("/useModularArithmetic"))) { translatorFlags.UseModularArithmetic = true; } if (args.Any(x => x.Equals("/omitUnsignedSemantics"))) { translatorFlags.NoUnsignedAssumesFlag = true; } if (args.Any(x => x.Equals("/omitAxioms"))) { translatorFlags.NoAxiomsFlag = true; } if (args.Any(x => x.Equals("/omitHarness"))) { translatorFlags.NoHarness = true; } if (args.Any(x => x.Equals("/modelReverts"))) { translatorFlags.ModelReverts = true; } if (args.Any(x => x.Equals("/instrumentGas"))) { translatorFlags.InstrumentGas = true; } var stubModels = args.Where(x => x.StartsWith("/stubModel:")); if (stubModels.Count() > 0) { Debug.Assert(stubModels.Count() == 1, "Multiple instances of /stubModel:"); var model = stubModels.First().Substring("/stubModel:".Length); Debug.Assert(model.Equals("skip") || model.Equals("havoc") || model.Equals("callback"), $"The argument to /stubModel: can be either {{skip, havoc, callback}}, found {model}"); translatorFlags.ModelOfStubs = model; } if (args.Any(x => x.StartsWith("/inlineDepth:"))) { var depth = args.Where(x => x.StartsWith("/inlineDepth:")).First(); translatorFlags.InlineDepthForBoogie = int.Parse(depth.Substring("/inlineDepth:".Length)); } if (args.Any(x => x.Equals("/doModSet"))) { translatorFlags.DoModSetAnalysis = true; } translatorFlags.PerformContractInferce = args.Any(x => x.StartsWith("/contractInfer")); // don't perform verification for some of these omitFlags if (tryProofFlag || tryRefutation) { Debug.Assert(!translatorFlags.NoHarness && !translatorFlags.NoAxiomsFlag && !translatorFlags.NoUnsignedAssumesFlag && !translatorFlags.NoDataValuesInfoFlag && !translatorFlags.NoSourceLineInfoFlag, "Cannot perform verification when any of " + "/omitSourceLineInfo, " + "/omitDataValuesInTrace, " + "/omitAxioms, " + "/omitHarness, " + "/omitUnsignedSemantics are specified"); } printTransactionSeq = !args.Any(x => x.Equals("/noTxSeq")); }