Repository navigation
feat: align account transaction validation with other checks - #7087
halibobo1205 wants to merge 2 commits into
Conversation
waynercheung
left a comment
There was a problem hiding this comment.
LGTM. Checkstyle/CI green, no debug code, no Math usage, no new logs, no DB/config/dependency change. Impact tables match the code paths I traced (Wallet.createTransactionCapsule, Manager.pushTransaction/rePush, TronNetDelegate, generateBlock, processBlock). Non-blocking items below; a follow-up PR is fine.
[SHOULD] AccountPermissionUpdateActuator.execute() still writes the new permissions before charging the fee. With the new validate() check this path should no longer fail, but charging first (adjustBalance before updatePermissions/put) keeps execute() from leaving writes that are later rolled back, and the final state is identical.
[SHOULD] Tests for isAccountCreateNonNormalType: add an unrecognized enum value (e.g. setTypeValue(3)), a non-AccountCreateContract transaction, and an Any that fails to unpack. Changing the catch branch to return true currently passes all tests.
[NIT]
- Build path:
/wallet/createaccount,CreateAccount2andcreateCommonTransactionstill build anAccountCreateContractwith a non-Normaltype that this node then refuses to broadcast; rejecting it inWallet.createTransactionCapsulewould let callers fail at build time. - Please mention the build-time
AccountPermissionUpdatechange andCONTRACT_EXE_ERROR->CONTRACT_VALIDATE_ERRORin the release notes for clients that build before funding. insufficientBalanceToCoverFee: useassertThrowsand assert the full message; the owner-permission-unchanged assertion adds nothing sincevalidate()does not write state.isAccountCreateNonNormalTypeis a pending-pool rule only; consider a private helper inManagernext toisShieldedTransaction/isExchangeTransactionrather than a public method onTransactionCapsule.- The two changes are unrelated; splitting them into separate PRs would keep history and release notes clearer.
| throw new ContractValidateException("Transaction auths are not supported."); | ||
| } | ||
|
|
||
| if (trx.isAccountCreateNonNormalType()) { |
There was a problem hiding this comment.
[DISCUSS] This only gates pushTransaction, so an AccountCreateContract with a non-Normal type is still valid in a block (CreateAccountActuator copies type into the new account). Is a validate-level check behind a proposal planned for the fork line? If yes, please open an issue and list it under "Follow up" instead of "None".
What does this PR do?
Adds two account transaction checks:
AccountPermissionUpdateActuator.validate()now ends with a fee check: the owner's balance must covercalcFee().execute()is unchanged.Manager.pushTransactionnow rejects anAccountCreateContractwhosetypeisn'tNormal.Why are these changes required?
calcFee()returns a configured fee (AssetIssue,CreateAccount,ExchangeCreate,MarketSellAsset,MarketCancelOrder,WitnessCreate) already makes this fee check invalidate(), andAGENTS.mdrequires it.AccountPermissionUpdatereported a short balance fromexecute()instead.Normalis the defaulttypeofAccountCreateContract. Other types are now rejected at the start ofpushTransaction.Impact
AccountPermissionUpdateContractwhose owner can't pay a fee:/wallet/accountpermissionupdate,/wallet/createCommonTransaction; gRPCAccountPermissionUpdate,CreateCommonTransaction{"Error":"<owner> insufficient balance, balance: <b>, amount: <fee>"}. gRPC:CONTRACT_VALIDATE_ERROR/wallet/broadcasttransaction,/wallet/broadcasthex; gRPCBroadcastTransactionCONTRACT_EXE_ERROR,Contract execute error : <owner> insufficient balance, ...CONTRACT_VALIDATE_ERROR,Contract validate error : <owner> insufficient balance, ...pushTransaction,rePush,TronNetDelegate.pushTransactionexecute()withContractExeException; not added to pendingvalidate()withContractValidateException; not added to pending.TronNetDelegatestill throwsP2pExceptiontypeTRX_EXE_FAILEDgenerateBlockpushBlock,TronNetDelegate.processBlockTronNetDelegatethrowsP2pExceptiontypeBAD_BLOCKP2pExceptiontype; the underlying exception is nowContractValidateExceptionAccountCreateContractwithtypeAssetIssueorContract:/wallet/createaccount,/wallet/createCommonTransaction; gRPCCreateAccount,CreateAccount2,CreateCommonTransaction/wallet/broadcasttransaction,/wallet/broadcasthex; gRPCBroadcastTransactionCONTRACT_VALIDATE_ERROR,Contract validate error : AccountCreateContract only supports the Normal account type.pushTransaction,rePush,TronNetDelegate.pushTransactionWalletandTransactionsMsgHandlerthen relay itContractValidateExceptionbefore signature validation, so it isn't added to pending or relayed.TronNetDelegatethrowsP2pExceptiontypeTRX_EXE_FAILEDgenerateBlockpushBlock,TronNetDelegate.processBlockAPI clients:
AccountPermissionUpdateContracttransaction. A flow that builds first and funds before broadcasting now fails at build.CONTRACT_EXE_ERRORfor that case.AccountCreateContractwith anothertypestill builds, but a node running this PR rejects its broadcast. Callers that leavetypeunset aren't affected.Proposal:
AccountPermissionUpdateat a fee of 0:execute()skips the deduction, so a negative balance used to pass and is now rejected. Mainnet's fee is currently 100 TRX and its only negative genesis balance isBlackhole, so reaching this there takes a proposal setting the fee to 0 and a signature fromBlackhole, whose key no one is known to hold. A private chain at a fee of 0 that holds the key of a negative balance should upgrade all nodes together.AccountCreateContract: the check runs only inpushTransaction, so block execution doesn't change and this doesn't need a proposal.This PR has been tested by:
Follow up
None.
Extra details
None.