perf: lazy constant resolution in ErgoTree evaluation#858
Conversation
…tion Add Option<&'ctx [Constant]> to Context<'ctx> with a with_constants() method that clones the context with a constants slice set. This enables the evaluator to resolve ConstPlaceholder nodes on-demand without cloning the entire ErgoTree AST. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These return references into the parsed tree without cloning, enabling the evaluator to work directly with the stored AST. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of erroring on ConstPlaceholder, look up the constant by id from ctx.constants. This enables evaluation without the upfront clone and tree-walk that substitute_constants() performs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For the common case (no deserialize nodes), reduce_to_crypto now borrows the root Expr and constants slice directly from the ErgoTree instead of cloning the entire AST and walking it to substitute ConstPlaceholder nodes. ConstPlaceholder nodes are resolved on-demand during evaluation by indexing into ctx.constants. The deserialize path (rare) retains the existing proposition() clone for substitute_deserialize compatibility. Diagnostic paths (false-reduction, eval errors) fall back to proposition() for fully-resolved pretty-printing — these are rare and don't affect the hot path. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rebase guidance update (re: #876 — "JIT Costing: The Definitive PR")
#876 and this PR overlap in If #876 merges first → this PR rebases:
If this PR merges first → #876 rebases: add Net: whichever merges first, the |
Resolve ConstPlaceholder from the eval context on demand instead of deep-cloning the AST via proposition() each reduce_to_crypto call. Mainnet-sync profiling in ergo-node-rust showed the per-input clone-and-substitute was 8-12% of total CPU.
Adds root_expr() / constants() accessors and Context::with_constants(). Deserialize trees fall back to proposition() (incompatible with lazy resolution). proposition() itself unchanged.
Beware of conflicts with #854, see comments below