feat: expose transaction_context::fee_payer and senders to Move#252
Conversation
Add two new natives in `initia_std::transaction_context` and
`minitia_std::transaction_context`:
- `senders(): vector<address>` — full sender vector of the current
transaction (previously only senders[0] was retained anywhere).
- `fee_payer(): Option<address>` — optional fee payer, plumbed from a
new `fee_payer` field on `types::Env` (BCS-breaking, Go binding
regenerated).
Plumbing:
- `Env` gains `fee_payer: Option<AccountAddress>` and a getter.
- `UserTransactionContext` now carries the full `senders` vector and the
optional fee_payer, populated for both Execute and Script payloads.
- VM passes `senders.clone()` and `env.fee_payer()` into the context.
- Two new gas params: `transaction_context.senders.{base,per_address}`
and `transaction_context.fee_payer.base`.
- Test-only setters (`set_senders_internal`, `set_fee_payer_internal`)
behind `#[cfg(feature = "testing")]` for Move unit tests, with
`ensure_user_transaction_context` initializing an empty context when
needed.
Tests:
- Move unit tests in both stdlibs (9 each): set/get, default, abort-on-
no-context via `#[expected_failure(abort_code = 393216)]`.
- Rust e2e (`test_fee_payer_flows_from_env_to_move`,
`test_senders_flow_from_env_to_move`) — publishes a probe module,
sets fee_payer / senders on Env, reads the stored resource back.
- Go (`TestExecuteEntryFunctionWithFeePayer`,
`TestExecuteEntryFunctionSenders`) — extends `publishModuleBundle`
with TxContextTests.mv, calls entry functions, verifies via view
function reads.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WalkthroughThis PR threads multi-sender and optional fee payer support throughout the Move VM stack: updating core type contracts ( ChangesTransaction Context Multi-Sender and Fee Payer
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
lib_test.go (1)
702-754: ⚡ Quick winStrengthen
senderscoverage with a multi-sender transaction.This test currently validates only a single sender, so it won’t catch regressions that truncate or reorder additional senders.
Proposed test adjustment
testAccount, err := types.NewAccountAddress("0x2") require.NoError(t, err) sender, err := types.NewAccountAddress("0x42") require.NoError(t, err) + sender2, err := types.NewAccountAddress("0x43") + require.NoError(t, err) @@ - []types.AccountAddress{sender}, + []types.AccountAddress{sender, sender2}, @@ - // vector<address> with one element serialized as JSON is ["0x42"]. - require.Equal(t, fmt.Sprintf("[\"%s\"]", sender.String()), viewRes.Ret) + require.Equal(t, fmt.Sprintf("[\"%s\",\"%s\"]", sender.String(), sender2.String()), viewRes.Ret) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib_test.go` around lines 702 - 754, Change the test to exercise multiple senders instead of only one: when calling vm.ExecuteEntryFunction use a sender slice with multiple distinct addresses (e.g., create extra types.NewAccountAddress values) so TxContextTests.store_senders is invoked with a multi-sender transaction, then call vm.ExecuteViewFunction on TxContextTests.read_stored_senders with the appropriate JSON-serialized argument(s) and assert viewRes.Ret contains all senders in the correct order (not just a single-element vector). Update the variables around ExecuteEntryFunction/ExecuteViewFunction and the final require.Equal assertion to reflect the expected JSON array of addresses so the test will catch truncation or reordering regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@lib_test.go`:
- Around line 702-754: Change the test to exercise multiple senders instead of
only one: when calling vm.ExecuteEntryFunction use a sender slice with multiple
distinct addresses (e.g., create extra types.NewAccountAddress values) so
TxContextTests.store_senders is invoked with a multi-sender transaction, then
call vm.ExecuteViewFunction on TxContextTests.read_stored_senders with the
appropriate JSON-serialized argument(s) and assert viewRes.Ret contains all
senders in the correct order (not just a single-element vector). Update the
variables around ExecuteEntryFunction/ExecuteViewFunction and the final
require.Equal assertion to reflect the expected JSON array of addresses so the
test will catch truncation or reordering regressions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e041fccf-2833-4635-afae-d56507f8867b
📒 Files selected for processing (17)
crates/e2e-move-tests/src/harness.rscrates/e2e-move-tests/src/tests/mod.rscrates/e2e-move-tests/src/tests/transaction_context.data/pack/Move.tomlcrates/e2e-move-tests/src/tests/transaction_context.data/pack/sources/TxContextTests.movecrates/e2e-move-tests/src/tests/transaction_context.rscrates/gas/src/initia_stdlib.rscrates/natives/src/transaction_context.rscrates/types/src/env.rscrates/types/src/user_transaction_context.rscrates/vm/src/initia_vm.rslib_test.goprecompile/binaries/minlib/transaction_context.mvprecompile/binaries/stdlib/transaction_context.mvprecompile/modules/initia_stdlib/sources/transaction_context.moveprecompile/modules/minitia_stdlib/sources/transaction_context.moveprecompile/modules/tests/sources/TxContextTests.movetypes/bcs.go
Summary
Exposes two new natives in
initia_std::transaction_contextandminitia_std::transaction_context:senders(): vector<address>— full sender vector of the current transaction.fee_payer(): Option<address>— optional fee payer, plumbed from a newfee_payerfield ontypes::Env.Plumbing
Envgainsfee_payer: Option<AccountAddress>(BCS-breaking; Go binding regenerated).UserTransactionContextnow carries the fullsendersvector and the optionalfee_payer, populated for both Execute and Script payloads.senders.clone()andenv.fee_payer()into the context.transaction_context.senders.{base,per_address}andtransaction_context.fee_payer.base.set_senders_internal,set_fee_payer_internal) behind#[cfg(feature = "testing")].Compatibility
EnvBCS layout changes — Go and Rust must ship together.UserTransactionContextis now populated for scripts too, butentry_function_payload()still returnsNone— observable Move behavior unchanged.Test plan
test_fee_payer_flows_from_env_to_move: publishes probe module, setsfee_payeronEnv, asserts Move reads back the same address.test_senders_flow_from_env_to_move: single-sender + two-sender cases viastore_senders/store_senders_two.TestExecuteEntryFunctionWithFeePayer: publishesTxContextTests, callsstore_fee_payer, reads back viaread_stored_fee_payerview function.TestExecuteEntryFunctionSenders: same pattern forstore_senders/read_stored_senders.cargo test --workspace: full suite passes (158 tests).go test ./...: all packages pass.cargo clippy --all-targets -- -D warnings: clean.🤖 Generated with Claude Code
Summary by CodeRabbit