Problem
A single action can spend tokens owned by different enrollment IDs. Request.Transfer with WithTokenIDs goes through parseInputIDs, which validates only the token type and the sum — never that the tokens belong to the wallet the request was given; the wallet-scoped selector runs only when no token IDs are supplied. Request.Upgrade takes an explicit token list too.
The transaction-record model cannot represent such an action: ttxdb keeps a single sender per action, and TransactionRecords rejects a multi-EID action with expected at most 1 input enrollment id (token/services/storage/ttxdb/store.go).
Since #2199 the auditor rejects such an action at Audit time with an error naming the multi-owner cause, so it fails the audit cleanly instead of surfacing as a storage error from Append. That makes the rejection deliberate and diagnosable, but the underlying limitation remains.
Question
Should the store learn to represent a multi-sender action — e.g. one transaction record per (action, sender enrollment ID), with amounts split per sender's tokens — or is rejecting such actions the intended model? If rejection is intended, Request.Transfer could enforce wallet ownership on explicitly passed token IDs instead, failing at request-building time rather than at audit time.
Raised by @AkramBitar during the review of #2199.
Problem
A single action can spend tokens owned by different enrollment IDs.
Request.TransferwithWithTokenIDsgoes throughparseInputIDs, which validates only the token type and the sum — never that the tokens belong to the wallet the request was given; the wallet-scoped selector runs only when no token IDs are supplied.Request.Upgradetakes an explicit token list too.The transaction-record model cannot represent such an action:
ttxdbkeeps a single sender per action, andTransactionRecordsrejects a multi-EID action withexpected at most 1 input enrollment id(token/services/storage/ttxdb/store.go).Since #2199 the auditor rejects such an action at
Audittime with an error naming the multi-owner cause, so it fails the audit cleanly instead of surfacing as a storage error fromAppend. That makes the rejection deliberate and diagnosable, but the underlying limitation remains.Question
Should the store learn to represent a multi-sender action — e.g. one transaction record per (action, sender enrollment ID), with amounts split per sender's tokens — or is rejecting such actions the intended model? If rejection is intended,
Request.Transfercould enforce wallet ownership on explicitly passed token IDs instead, failing at request-building time rather than at audit time.Raised by @AkramBitar during the review of #2199.