Skip to content

feat: add updated fuzzer from tact-check repository #2340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 43 commits into
base: main
Choose a base branch
from

Conversation

Mell0r
Copy link

@Mell0r Mell0r commented Mar 9, 2025

No description provided.

@Mell0r Mell0r added kind: testing Tests (*.spec.ts) size: big This is a hard task, more like a project and will take a while to implement scope: codegen Code generation, a.k.a. compiler backend (src/generator) kind: fuzzing Application of fuzzing to testing labels Mar 9, 2025
@Mell0r Mell0r requested a review from a team as a code owner March 9, 2025 22:58
@Mell0r
Copy link
Author

Mell0r commented Mar 11, 2025

Right now there is the problem in one of the tests in the fuzzer - compilation.spec.ts:
Error from the compilator: [INTERNAL COMPILER ERROR]: Interval [0, 0[ is empty or out of source bounds (0)
Stacktrace:
at throwInternalCompilerError (src/error/errors.ts:98:11)
at show (src/grammar/src-info.ts:185:39)
at Object.show [as toString] (src/grammar/src-info.ts:227:29)
at Object.toString [as getLineAndColumnMessage] (src/grammar/src-info.ts:258:35)
at getLineAndColumnMessage (src/error/errors.ts:111:62)
at throwNonFatalErrorConstEval (src/optimizer/interpreter.ts:60:24)
at Interpreter.throwNonFatalErrorConstEval [as interpretStaticCall] (src/optimizer/interpreter.ts:1562:21)
at Interpreter.interpretStaticCall [as interpretExpressionInternal] (src/optimizer/interpreter.ts:924:29)
at interpretExpressionInternal (src/optimizer/interpreter.ts:770:18)
at Interpreter.code [as handleStackOverflow] (src/optimizer/interpreter.ts:1933:20)
at Interpreter.handleStackOverflow (src/optimizer/interpreter.ts:769:21)
at interpretExpression (src/optimizer/constEval.ts:221:32)
at writeExpression (src/generator/writers/writeExpression.ts:181:45)
at writeStatement (src/generator/writers/writeFunction.ts:186:40)
at writeReceiverBody (src/generator/writers/writeRouter.ts:502:23)
at writeReceiverBody (src/generator/writers/writeRouter.ts:492:9)
at Writer.handler [as inIndent] (src/utils/Writer.ts:9:9)
at Writer.inIndent [as inBlock] (src/utils/Writer.ts:15:14)
at WriterContext.inBlock (src/generator/Writer.ts:303:30)
at inBlock (src/generator/writers/writeRouter.ts:475:10)
at writeBouncedReceiver (src/generator/writers/writeRouter.ts:427:13)
at Array.forEach ()
at forEach (src/generator/writers/writeRouter.ts:426:33)
at Writer.handler [as inIndent] (src/utils/Writer.ts:9:9)
at Writer.inIndent [as inBlock] (src/utils/Writer.ts:15:14)
at WriterContext.inBlock (src/generator/Writer.ts:303:30)
at inBlock (src/generator/writers/writeRouter.ts:419:10)
at src/generator/writers/writeContract.ts:422:35
at Writer.handler [as inIndent] (src/utils/Writer.ts:9:9)
at Writer.inIndent [as inBlock] (src/utils/Writer.ts:15:14)
at WriterContext.inBlock (src/generator/Writer.ts:303:30)
at inBlock (src/generator/writers/writeContract.ts:404:14)
at handler (src/generator/Writer.ts:246:17)
at WriterContext.handler [as body] (src/generator/Writer.ts:236:9)
at body (src/generator/Writer.ts:245:18)
at WriterContext.handler [as fun] (src/generator/Writer.ts:187:9)
at WriterContext.fun [as main] (src/generator/Writer.ts:244:14)
at main (src/generator/writers/writeContract.ts:347:10)
at writeAll (src/generator/writeProgram.ts:437:22)
at writeAll (src/generator/writeProgram.ts:55:5) <--- first function called outside of the fuzzer and inside the compilator
at compile (fuzzer/test/testUtils.ts:62:20)
at fuzzer/test/compilation.spec.ts:47:21
at withNodeFS (fuzzer/src/util.ts:28:9)
at compileProgram (fuzzer/test/compilation.spec.ts:30:5)
at AsyncProperty.run (node_modules/fast-check/lib/check/property/AsyncProperty.generic.js:49:28)
at asyncRunIt (node_modules/fast-check/lib/check/runner/Runner.js:37:21)
at checkAsyncProperty (fuzzer/src/util.ts:100:5)
at compileAndCheckProperty (fuzzer/test/compilation.spec.ts:111:17)
at fuzzer/test/compilation.spec.ts:121:25
at async Promise.all (index 81)

As i understand, the problem is with provioding loc to all the AST items. Before the last commit i used dummySrcInfo from compilator code for all 'loc' fields, and now i tried to replace it with my own dummySrcInfoPrintable (./fuzzer/src/utils.ts, 236 line) with non-empty line interval, but error still persists. As i doesn't provide a source code and compile ast tree directly, in the place of the error (./src/grammar/src-info.ts, 186 line) the 'str' - source code itself - is empty, so the interval is empty too. But how can it not be?

@jeshecdom
Copy link
Contributor

Hello. Try to define your dummySrcInfoPrintable like this:

const dummySrcInfoPrintable = getSrcInfo(" ", 0, 0, null, "user");

Note that the first parameter to getSrcInfo is not an empty string, but has a single space character (you could add as many space characters as you like). The error is caused because using an empty string as first parameter to getSrcInfo produces invalid limits in the second and third parameters: an empty string does not have a 0th character.

@anton-trunov anton-trunov changed the title feat: added updated fuzzer from tact-check repositpry feat: add updated fuzzer from tact-check repository Mar 12, 2025
Comment on lines 1 to 6
import type {
ConstantDecl as AstConstantDecl,
ConstantDef as AstConstantDef,
ConstantAttribute as AstConstantAttribute,
Expression as AstExpression,
} from "../../../src/ast/ast";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import type {
ConstantDecl as AstConstantDecl,
ConstantDef as AstConstantDef,
ConstantAttribute as AstConstantAttribute,
Expression as AstExpression,
} from "../../../src/ast/ast";
import type * as Ast from "../ast/ast";

Copy link
Contributor

@jeshecdom jeshecdom left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it looks good. There are some minor details like the use of optional arguments in functions and the use of classes, but I think this is acceptable, since this code is for testing.

What I am more interested in is how good the generators are; for example, the ones for expressions. What is the distribution of the generated expressions? To tackle this question, for the moment let us focus on the expression generators.

We need to add a statistics function, probably in the expression.spec.ts file. The statistics function should count the frequencies of structurally different trees produced by the generators. By that I mean the following:

  • Given an AST T generated by the expression generator, traverse T in preorder and only keep the kind field of each node (for function calls also keep the name of the function). For example, if the AST is:
      {kind: "static_call", function: "do_something", ......}  
                        |                                 |    
The children are -->    |                                 |    
its arguments           |                                 |                                   
                        |                                 |
         {kind: "number", value: 5n, ...}       {kind: "string", value: "foo", ...}

Then, after keeping only the kind field and function names, and traversing in preorder, we get the list:

"static_call_do_something", "number", "string"

  • Join the string list into a single string (use a special symbol as separator, like @):

"static_call_do_something@number@string"

  • Keep a map with the counts for the produced strings.

  • Additionally, register the size of each produced tree (i.e., how many nodes it has), and its height (i.e., maximum distance from the root of the tree to a leaf node).

  • After producing, say 50,000 trees (or more). Dump all those counts into a file, so that we can then produce plots from the data. It would also be nice if we can produce the plots automatically, but let us postpone that for later, what matters right now is the counts.

@jeshecdom
Copy link
Contributor

After meeting with @Mell0r, we need to add the extensions described in #2721.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: fuzzing Application of fuzzing to testing kind: testing Tests (*.spec.ts) scope: codegen Code generation, a.k.a. compiler backend (src/generator) size: big This is a hard task, more like a project and will take a while to implement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants