← Back to Transactors: Understanding the Lifecycle of a Transaction
Map out the conditions that lead to different TER codes for the CheckCreate transactor and create a decision tree.
Understanding which conditions lead to which result codes is essential for:
Building applications that handle errors correctly
Debugging transaction failures
Implementing new transactors with appropriate error handling
Part 1: Code Analysis
Review CreateCheck.cpp and identify every return statement with its result code.
Create a table:
Phase
Code
Condition
Description
!isLegalNet(sendMax) || sendMax.signum() <= 0
Part 2: Create a Decision Tree
Draw a flowchart showing how each result code can be reached:
You can use:
A drawing tool (Mermaid, draw.io, etc.)
Hand-drawn diagram (photo)
Part 3: Categorize by Phase
Group the result codes by phase:
Preflight (returns NotTEC):
Preclaim (can return TEC):
doApply (can return TEC):
Part 4: Identify Implicit Checks
Some checks are performed by the base Transactor class, not by CreateCheck itself:
Fee validation: Where is this checked?
Sequence validation: Where is this checked?
Signature validation: Where is this checked?
Add these to your decision tree.
Part 5: Create Test Scenarios
For each possible result code, describe a test scenario that would trigger it:
Create check with same source and destination account
Create check with SendMax = 0
Create check to non-existent account
Complete table of all return statements and conditions
Decision tree diagram showing all code paths
Phase categorization with explanations
Test scenario list for each result code
Analysis Questions
Answer the following:
Why can't preflight return tec codes?
Explain the security implications
What's the difference between tecNO_DST and temDST_NEEDED?
If a transaction fails with tecFROZEN, what exactly was frozen?
Identify all the freeze checks
Can a CheckCreate ever fail in doApply with a result other than tesSUCCESS, tefINTERNAL, tecINSUFFICIENT_RESERVE, or tecDIR_FULL?
What result code would you expect for each scenario:
Check with Expiration = 0
Check with SendMax = -100 XRP
Check to an AMM pool account
Check with destination tag when lsfRequireDestTag is set
Bonus Challenge
Create a similar analysis for CashCheck and compare the result code patterns. What codes are unique to each transaction type?
src/xrpld/app/tx/detail/CreateCheck.cpp - CheckCreate implementation
include/xrpl/protocol/TER.h - TER code definitions
src/xrpld/app/tx/detail/Transactor.cpp - Base class checks