Feature/factory upgrade
Summary by CodeRabbit
-
New Features
- Upgradeable factory flows: per-child upgrades, batch upgrades and batch-upgrade argument support.
- New example contracts: BetterCounter and FToken (with factory variants).
- Public entry-point API exposed and ergonomics improved; batch-args type for batched upgrades.
-
Breaking Changes
- Factory entry renamed from "factory" to "new_contract"; added "upgrade_child_contract" and "batch_upgrade_child_contract" endpoints and updated signatures.
-
Chores
- Updated examples, contract schemas, re-exports, and a cargo alias for running with livenet.
✏️ Tip: You can customize this high-level summary in your review settings.
Walkthrough
Adds a typed EntryPoint API and re-exports it; introduces factory-focused entrypoint variants (new_contract, upgrade_child_contract, batch_upgrade_child_contract) and BatchUpgradeArgs; refactors macro codegen to support multi-context factory flows; updates wasm host to support factory-caller override and factory runtime flags; updates examples and schemas accordingly.
Changes
| Cohort / File(s) | Summary |
|---|---|
Core consts core/src/consts.rs |
Added pub const IS_FACTORY_UPGRADE_ARG: &str = "odra_cfg_is_factory_upgrade";. |
Entry point API core/src/entry_point.rs, core/src/lib.rs, odra/src/lib.rs |
New EntryPoint enum, EntityEntryPointsExt trait/impl, conversions to/from casper_types::EntityEntryPoint; entry_point module exported and re-exported from odra. |
Batch upgrade args core/src/args.rs |
Added BatchUpgradeArgs<T> type and EntrypointArgument implementation for batching upgrade runtime args. |
Wasm host & consts odra-casper/wasm-env/src/host_functions.rs, odra-casper/wasm-env/src/consts.rs, odra-casper/wasm-env/Cargo.toml |
Added FACTORY_GROUP_NAME; host: override_factory_caller() and override flag; caller logic respects override; install/upgrade paths inspect IS_FACTORY_UPGRADE_ARG and branch for factory upgrade flows; minor Cargo.toml spacing change. |
VM formatting odra-casper/test-vm/src/vm/casper_vm.rs |
Adjusted ExecError string formatting in parse_error. |
Macro IR & Fn taxonomy odra-macros/src/ir/mod.rs |
Added public FnType enum and fn_type(); generate new_contract, factory_upgrade_fn, factory_batch_upgrade_fn; added upgrader_args(); updated protected names. |
Macro codegen (wasm parts & utils) odra-macros/src/ast/wasm_parts.rs, odra-macros/src/ast/wasm_parts_utils.rs, odra-macros/src/utils/expr.rs, odra-macros/src/utils/ty.rs, odra-macros/src/utils/ident.rs |
Introduced generic NoMangleFnItem<C>, Module/Factory/Installer/Batch contexts; replaced legacy entrypoint builders with explicit helpers (constructor_ep, regular_ep, factory_ep, factory_upgrade_ep, factory_batch_upgrade_ep, template_ep); added use_entity_entry_points_ext(); added bytes() and batch_upgrade_args_of_t(); renamed ident helpers. |
Factory macro parts odra-macros/src/ast/factory/* (multiple files) |
Reworked factory codegen: replaced factory with new_contract; added upgrade_child_contract and batch_upgrade_child_contract; factory_fn → factory_fns: Vec<_>; multi-entrypoint generation and contexts added; tests updated. |
Ref utils & runtime args odra-macros/src/ast/ref_utils.rs |
Runtime-arg construction branches on FnType, injects appropriate odra_cfg flags (including IS_FACTORY_UPGRADE_ARG) and handles batch-upgrade arg encoding; generics propagated to signatures. |
Host/ref/test wiring (macros) odra-macros/src/ast/{factory,ref,host_ref,host_ref_item,test_parts}.rs |
Renamed factory → new_contract in host/ref/test APIs; added host/ref methods for upgrade_child_contract and batch_upgrade_child_contract; updated dispatch, argument types, and tests. |
Remove unnecessary clones odra-macros/src/ast/{contract_ref_item.rs,external_contract_item.rs,host_ref_item.rs,test_parts.rs} |
Replaced several .clone() uses with moved-owned values when calling EntrypointArgument::insert_runtime_arg. |
Macro codegen signatures & helpers odra-macros/src/ast/wasm_parts_utils.rs, odra-macros/src/ast/wasm_parts.rs, odra-macros/src/utils/expr.rs |
Simplified param handling, replaced NewEntryPointItem with syn::Expr-driven entry point expressions, added vec_try_into helper. |
Schemas & examples examples/resources/**/*_schema.json, examples/Odra.toml, examples/.cargo/config.toml |
Added/updated JSON schemas to reflect new_contract, upgrade_child_contract, batch_upgrade_child_contract; updated Odra.toml contract entries; added cargo alias rl = "run --features=livenet". |
Examples: factory & token examples/src/factory/{counter.rs,token.rs}, examples/src/factory/mod.rs, examples/bin/factory_example.rs |
Added BetterCounter and FToken examples; added factory upgrade and batch-upgrade flows; added deploy_with_cfg, new_contract, try_upgrade, upgrade_child_contract, batch_upgrade_child_contract usages and tests. |
Sequence Diagram(s)
sequenceDiagram
autonumber
actor User
participant Factory as Factory Contract (new_contract)
participant Host as Wasm Host
participant Child as Child Contract
User->>Factory: new_contract(name, init_args)
Factory->>Host: install (installer + entry_points)
Host-->>Factory: returns (Child Address, URef)
User->>Factory: upgrade_child_contract(name, upgrade_args)
Factory->>Host: invoke factory_upgrade entry (sets IS_FACTORY_UPGRADE_ARG)
Host->>Host: override_factory_caller() (enable override)
Host->>Child: call child's upgrader with forwarded args
Child-->>Host: upgrade result
Host-->>Factory: success/failure
Estimated code review effort
🎯 5 (Critical) | ⏱️ ~120+ minutes
Areas needing extra attention:
- odra-macros (large, cross-cutting codegen refactor: new contexts, FnType, new entrypoint variants, many touched files and updated tests).
- odra-casper wasm-env/host_functions.rs (caller override, IS_FACTORY_UPGRADE_ARG handling, install/upgrade branching).
- core entry_point API (conversions and public re-export) and consistency of renames across macros, host, examples, and schemas.
Possibly related PRs
- odradev/odra#615 — Related factory codegen and runtime-argument wiring changes in odra-macros and factory flows.
- odradev/odra#514 — Related changes around odra_cfg constants and wasm-host behavior.
- odradev/odra#436 — Related entrypoint name/type adjustments and macro codegen updates.
Suggested reviewers
- kubaplas
- zie1ony
Poem
🐇 I hopped through macros, entrypoints anew,
New_contracts sprouted where factories grew,
Callers don masks for the upgrade parade,
Tokens and counters in batch upgrades made,
A joyful thump — a rabbit's build review!
Pre-merge checks and finishing touches
❌ Failed checks (1 warning, 1 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | ⚠️ Warning | Docstring coverage is 34.06% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
| Title check | ❓ Inconclusive | The title 'Feature/factory upgrade' is vague and uses a generic prefix pattern that doesn't clearly convey the main change or specific feature being added. | Use a more descriptive title that clearly indicates the main feature, e.g., 'Add factory contract upgrade capabilities' or 'Implement child contract upgrades for factory contracts'. |
✅ Passed checks (1 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
feature/factory-upgrade
📜 Recent review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📥 Commits
Reviewing files that changed from the base of the PR and between 0eda2827846f6a8fa55b1a93038032fcbd3c83dd and e4ddbfe655f4ab8d751e8df34562fea74395711d.
📒 Files selected for processing (5)
odra-macros/src/ast/factory/impl_item.rs(11 hunks)odra-macros/src/ast/factory/parts/ref_item.rs(2 hunks)odra-macros/src/ast/factory/parts/test_parts.rs(3 hunks)odra-macros/src/ast/factory/parts/wasm_parts.rs(23 hunks)odra-macros/src/ast/schema/entry_points.rs(4 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
odra-macros/src/ast/factory/parts/ref_item.rs (4)
odra-macros/src/ir/mod.rs (13)
syn(205-205)syn(206-206)syn(210-210)syn(213-213)syn(477-477)syn(830-830)factory_fn(367-377)factory_upgrade_fn(379-386)factory_batch_upgrade_fn(388-395)contract_name(138-144)new(730-732)new(748-750)new(774-776)odra-macros/src/ast/factory/parts/wasm_parts.rs (15)
try_from(18-45)try_from(63-81)try_from(159-175)try_from(212-219)try_from(225-238)try_from(244-250)try_from(256-263)try_from(269-274)try_from(314-318)try_from(330-339)try_from(405-420)module(74-79)module(161-165)module(166-170)module(408-413)odra-macros/src/ast/schema/entry_points.rs (4)
try_from(17-51)try_from(126-131)fns(62-97)args(114-120)odra-macros/src/ast/ref_utils.rs (2)
fun(99-107)contract_function_item(48-58)
odra-macros/src/ast/factory/parts/test_parts.rs (6)
odra-casper/test-vm/src/vm/casper_vm.rs (5)
new_contract(440-464)value(815-820)value(827-832)call_contract(308-378)new(75-77)odra-macros/src/utils/ty.rs (6)
string(167-169)address(4-6)from(216-218)vec(196-198)call_def(44-46)entry_point(80-82)core/src/args.rs (10)
unwrap(32-37)unwrap(98-98)unwrap(116-121)unwrap(137-142)unwrap(179-184)from(149-151)insert_runtime_arg(96-96)insert_runtime_arg(110-114)insert_runtime_arg(133-135)insert_runtime_arg(166-177)odra-casper/wasm-env/src/host_functions.rs (1)
call_contract(574-595)core/src/entry_point.rs (2)
from(67-79)entry_point(165-178)odra-macros/src/ast/factory/parts/has_entrypoints_item.rs (1)
vec(77-99)
odra-macros/src/ast/schema/entry_points.rs (5)
odra-macros/src/ast/entrypoints_item.rs (3)
ir(61-98)vec(80-83)f(103-111)odra-macros/src/ir/mod.rs (4)
ty(796-801)factory_fn(367-377)factory_upgrade_fn(379-386)factory_batch_upgrade_fn(388-395)odra-macros/src/ast/factory/parts/has_entrypoints_item.rs (1)
vec(77-99)odra-macros/src/utils/ty.rs (5)
vec(196-198)bytes(276-278)schema(99-101)string(167-169)entry_point(80-82)odra-schema/src/lib.rs (8)
schema(169-222)schema(456-456)argument(70-76)argument(323-323)argument(330-330)argument(337-337)entry_point(79-94)entry_point(338-338)
odra-macros/src/ast/factory/impl_item.rs (5)
core/src/entry_point.rs (4)
entry_point(165-178)from(67-79)add(57-57)add(61-63)core/src/args.rs (20)
parameter(189-194)parameter(255-263)parameter(256-256)parameter(257-257)parameter(258-258)parameter(259-259)from(149-151)insert_runtime_arg(96-96)insert_runtime_arg(110-114)insert_runtime_arg(133-135)insert_runtime_arg(166-177)unwrap(32-37)unwrap(98-98)unwrap(116-121)unwrap(137-142)unwrap(179-184)cl_type(94-94)cl_type(106-108)cl_type(129-131)cl_type(159-164)odra-casper/test-vm/src/vm/casper_vm.rs (4)
new_contract(440-464)call_contract(308-378)new(75-77)upgrade_contract(467-484)core/src/host.rs (16)
new_contract(385-390)new_contract(543-560)env(33-33)call_contract(377-382)call_contract(606-618)address(45-47)address(1038-1040)new(24-24)new(177-183)new(195-201)new(443-450)new(1035-1037)from(134-136)upgrade_contract(394-400)upgrade_contract(564-588)contract_address(31-31)odra-casper/wasm-env/src/host_functions.rs (7)
call_contract(574-595)override_factory_caller(1072-1076)runtime(232-232)runtime(233-233)runtime(966-966)runtime(980-980)upgrade_contract(196-312)
odra-macros/src/ast/factory/parts/wasm_parts.rs (8)
odra-macros/src/ir/mod.rs (23)
syn(205-205)syn(206-206)syn(210-210)syn(213-213)syn(477-477)syn(830-830)try_from(202-223)try_from(583-587)try_from(593-597)try_from(828-832)host_functions(356-358)factory_upgrade_fn(379-386)ty(796-801)upgrader_args(420-427)name(609-611)name(782-790)named_args(643-648)new(730-732)new(748-750)new(774-776)contract_name(138-144)is_non_reentrant(630-633)is_payable(625-628)odra-macros/src/ast/factory/parts/ref_item.rs (1)
try_from(30-36)core/src/entry_point.rs (4)
try_from(85-149)entry_point(165-178)add(57-57)add(61-63)odra-macros/src/ast/wasm_parts.rs (8)
try_from(40-58)try_from(81-99)try_from(123-184)try_from(221-248)try_from(266-283)module(51-56)module(92-96)std(246-246)odra-macros/src/ast/wasm_parts_utils.rs (4)
func(8-14)use_entity_entry_points_ext(35-37)param_parameters(7-16)param_ret_ty(18-23)odra-macros/src/utils/ident.rs (8)
ident(86-88)result(11-13)entry_points(47-49)child_contract_entry_points(51-53)add_entry_point(55-57)named_args(3-5)env(19-21)cl_type(106-108)odra-macros/src/utils/expr.rs (9)
new_wasm_contract_env(73-75)args(177-180)constructor_ep(209-213)upgrader_ep(215-219)regular_ep(221-235)factory_ep(237-241)factory_upgrade_ep(243-247)factory_batch_upgrade_ep(249-251)vec(145-147)odra-casper/wasm-env/src/host_functions.rs (5)
override_factory_caller(1072-1076)runtime(232-232)runtime(233-233)runtime(966-966)runtime(980-980)
🔇 Additional comments (20)
odra-macros/src/ast/factory/parts/ref_item.rs (3)
22-36: LGTM! Clean refactor to support multiple factory entry points.The change from a single
factory_fnto a vectorfactory_fnscleanly supports the new upgrade-related entry points while maintaining the existing pattern.
39-48: LGTM! Correctly emits all factory functions.The use of
#(#fns)*properly expands the vector of functions in the impl block.
90-168: LGTM! Test expectations correctly reflect ContractRef behavior.The generated
ContractRefmethods properly:
- Use the updated entry point names (
new_contract,upgrade_child_contract,batch_upgrade_child_contract)- Apply
EntrypointArgument::insert_runtime_argfor parameter handling- Omit
odra_cfg_*flags (these belong inHostRef, notContractRef)odra-macros/src/ast/factory/parts/wasm_parts.rs (7)
15-46: LGTM! Correct factory context override implementation.The
override_factory_caller()invocation properly ensures that factory context functions resolve the caller from the call stack rather than the immediate caller.
48-82: LGTM! Structure extended for upgrade functionality.The addition of
factory_upgrade_fnandentry_pointsfields properly supports the new upgrade-related entry points.
113-176: LGTM! Well-designed separation of factory and child entry points.The introduction of
child_contract_entry_points()alongsideentry_points()correctly separates:
- Factory-level entry points (Factory, FactoryUpgrade, FactoryBatchUpgrade, Template)
- Child contract entry points (Constructor, Regular with Upgrader)
This supports the factory's role in managing child contract lifecycles.
178-275: LGTM! Clean context-based entry point generation.The context marker types and associated
TryFromimplementations provide a well-structured approach to generating different entry point variants based on the execution context.
321-393: LGTM! new_contract implementation looks correct.The generated
new_contract()entry point properly:
- Calls
override_factory_caller()for correct context resolution- Uses
child_contract_entry_points()when installing the child contract- Emits the deployment event with contract name and address
- Returns the expected
(Address, URef)tuple
534-608: LGTM! Test expectations correctly reflect dual entry point sets.The test properly validates:
entry_points()containing Template and Factory variants for the factory contract itselfchild_contract_entry_points()containing Constructor and Regular variants for child contracts
629-768: Test expectations reveal override_factory_caller inconsistency.Note that the test expectations show
new_contract(line 630),init(line 742),total_supply(line 748),pay_to_mint(line 759), andapprove(line 765) all calloverride_factory_caller(), butupgrade_child_contract(line 666) andbatch_upgrade_child_contract(line 705) do not. This confirms the inconsistency flagged in the generation code above (lines 444 and 480).odra-macros/src/ast/schema/entry_points.rs (2)
1-52: LGTM! Schema generation updated for multiple factory entry points.The chaining of
factory_fn(),factory_upgrade_fn(), andfactory_batch_upgrade_fn()(line 45) correctly extends schema generation to include all factory-related entry points.
59-111: LGTM! Correct special handling for FactoryBatchUpgrader.The special case for
FactoryBatchUpgrader(lines 77-82) correctly generates a singlebytesargument instead of expanding typed arguments, which aligns with the batch upgrade's need to accept serializedRuntimeArgsfor multiple contracts.odra-macros/src/ast/factory/parts/test_parts.rs (2)
118-136: LGTM! Public HostRef methods correctly delegate to try_ variants.*The public methods properly unwrap the results from their corresponding
try_*variants, maintaining the standard pattern for HostRef methods.
138-209: LGTM! Correct odra_cfg flags for each operation type.The
try_*methods properly set operation-specific configuration flags:
try_new_contract: Configures initial deployment withis_upgradable=true,is_upgrade=false,allow_key_override=truetry_upgrade_child_contractandtry_batch_upgrade_child_contract: Configure upgrade withis_factory_upgrade=true,allow_key_override=true,create_upgrade_group=falseThese flags correctly control host behavior for factory operations in the test environment.
odra-macros/src/ast/factory/impl_item.rs (6)
72-88: LGTM! Entry points correctly use new EntryPoint enum variants.The
HasEntrypointsimplementation properly usesConstructor,Factory,FactoryUpgrade, andFactoryBatchUpgradevariants with appropriate arguments, aligning with the core API changes.
119-179: LGTM! ContractRef methods correctly call factory entry points.The
ContractRefimplementation properly invokes the renamed and new entry points (new_contract,upgrade_child_contract,batch_upgrade_child_contract) with correct argument handling.
239-320: LGTM! HostRef implementation mirrors test_parts.rs correctly.The
HostRefmethods properly setodra_cfg_*flags for test environment operations, consistent with the test scaffolding in test_parts.rs.
422-496: LGTM! Test validates correct dual entry point structure.The test expectations confirm the proper separation of factory-level entry points (Template, Factory, FactoryUpgrade, FactoryBatchUpgrade) from child contract entry points (Constructor, Regular).
516-627: Test expectations reflect the override_factory_caller inconsistency.Note that these test expectations confirm the issue flagged in wasm_parts.rs:
upgrade_child_contract(line 555) andbatch_upgrade_child_contract(line 594) do not calloverride_factory_caller(), whilenew_contract(line 518) and all regular entry points do.
678-718: LGTM! Schema entry points match implementation.The schema correctly reflects the entry point signatures:
new_contractwithcontract_name: odra::prelude::string::Stringandvalue: u32upgrade_child_contractwithcontract_name: odra::prelude::string::Stringbatch_upgrade_child_contractwithargs: Bytes
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.690934248 CSPR (0.22%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.690934248 CSPR (0.22%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.690934248 CSPR (0.22%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.690934248 CSPR (0.22%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.646323918 CSPR (0.21%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.646323918 CSPR (0.21%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.646323918 CSPR (0.21%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.651911853 CSPR (0.21%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.651911853 CSPR (0.21%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |
Benchmark report
| Action | Details | Gas diff |
|---|---|---|
| Wasm Deploy | Filename: Benchmark.wasm | :red_circle: +0.628442526 CSPR (0.20%) |
| Contract Call | Entry point: init_submodule | :red_circle: +0.00001065 CSPR (0.00%) |
| Contract Call | Entry point: transfer_back | :red_circle: +0.00001065 CSPR (0.00%) |