Skip to content

Commit 7e7fb4f

Browse files
feat: Enhance Stellar with concurrent transaction support (#423)
* feat: Enhance Stellar with concurrent transaction support Signed-off-by: Dylan Kilkenny <dylankilkenny95@gmail.com> * chore: Add default var Signed-off-by: Dylan Kilkenny <dylankilkenny95@gmail.com> * test: Add tests Signed-off-by: Dylan Kilkenny <dylankilkenny95@gmail.com> --------- Signed-off-by: Dylan Kilkenny <dylankilkenny95@gmail.com>
1 parent 3879b88 commit 7e7fb4f

14 files changed

Lines changed: 364 additions & 179 deletions

File tree

docs/modules/ROOT/pages/stellar.adoc

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,53 @@ For more configuration examples, visit the link:https://github.com/OpenZeppelin/
8686

8787
=== Relayer Policies
8888

89-
Stellar relayers support standard relayer configuration options. Check all options in xref:index.adoc#3_relayers[User Documentation - Relayers].
89+
Stellar relayers support standard relayer configuration options along with Stellar-specific policies:
90+
91+
[cols="1,1,1,2"]
92+
|===
93+
|Policy |Type |Default |Description
94+
95+
|`min_balance`
96+
|integer
97+
|None
98+
|Minimum balance in stroops (1 XLM = 10,000,000 stroops) required for the relayer account
99+
100+
|`max_fee`
101+
|integer
102+
|None
103+
|Maximum transaction fee in stroops the relayer is willing to pay
104+
105+
|`timeout_seconds`
106+
|integer
107+
|None
108+
|Transaction timeout in seconds
109+
110+
|`concurrent_transactions`
111+
|boolean
112+
|false
113+
|Enable concurrent transaction processing. When enabled, bypasses the lane gating mechanism that normally ensures sequential processing for each relayer. Only enable this when your relayer manages transactions from multiple accounts with independent sequence number pools.
114+
|===
115+
116+
Example configuration with policies:
117+
[source,json]
118+
----
119+
{
120+
"id": "stellar-example",
121+
"name": "Stellar Example",
122+
"network": "testnet",
123+
"paused": false,
124+
"network_type": "stellar",
125+
"signer_id": "local-signer",
126+
"policies": {
127+
"min_balance": 10000000,
128+
"max_fee": 1000000,
129+
"timeout_seconds": 30,
130+
"concurrent_transactions": false
131+
}
132+
}
133+
----
134+
135+
For general relayer configuration options, check xref:index.adoc#3_relayers[User Documentation - Relayers].
90136

91137
== API Reference
92138

docs/openapi.json

Lines changed: 50 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -3788,77 +3788,23 @@
37883788
"data": {
37893789
"oneOf": [
37903790
{
3791-
"allOf": [
3792-
{
3793-
"$ref": "#/components/schemas/SignTransactionResponseStellar"
3794-
},
3795-
{
3796-
"type": "object",
3797-
"required": [
3798-
"network"
3799-
],
3800-
"properties": {
3801-
"network": {
3802-
"type": "string",
3803-
"enum": [
3804-
"stellar"
3805-
]
3806-
}
3807-
}
3808-
}
3809-
]
3791+
"$ref": "#/components/schemas/SignTransactionResponseStellar"
38103792
},
38113793
{
3812-
"allOf": [
3813-
{
3814-
"type": "array",
3815-
"items": {
3816-
"type": "integer",
3817-
"format": "int32",
3818-
"minimum": 0
3819-
}
3820-
},
3821-
{
3822-
"type": "object",
3823-
"required": [
3824-
"network"
3825-
],
3826-
"properties": {
3827-
"network": {
3828-
"type": "string",
3829-
"enum": [
3830-
"evm"
3831-
]
3832-
}
3833-
}
3834-
}
3835-
]
3794+
"type": "array",
3795+
"items": {
3796+
"type": "integer",
3797+
"format": "int32",
3798+
"minimum": 0
3799+
}
38363800
},
38373801
{
3838-
"allOf": [
3839-
{
3840-
"type": "array",
3841-
"items": {
3842-
"type": "integer",
3843-
"format": "int32",
3844-
"minimum": 0
3845-
}
3846-
},
3847-
{
3848-
"type": "object",
3849-
"required": [
3850-
"network"
3851-
],
3852-
"properties": {
3853-
"network": {
3854-
"type": "string",
3855-
"enum": [
3856-
"solana"
3857-
]
3858-
}
3859-
}
3860-
}
3861-
]
3802+
"type": "array",
3803+
"items": {
3804+
"type": "integer",
3805+
"format": "int32",
3806+
"minimum": 0
3807+
}
38623808
}
38633809
]
38643810
},
@@ -6063,6 +6009,13 @@
60636009
"type": "object",
60646010
"description": "Stellar-specific relayer policy configuration",
60656011
"properties": {
6012+
"concurrent_transactions": {
6013+
"type": [
6014+
"boolean",
6015+
"null"
6016+
],
6017+
"description": "Allow concurrent transactions (essential for channel accounts using different accounts' sequence numbers)"
6018+
},
60666019
"max_fee": {
60676020
"type": [
60686021
"integer",
@@ -6125,9 +6078,13 @@
61256078
"type": "object",
61266079
"required": [
61276080
"transaction",
6128-
"signature"
6081+
"signature",
6082+
"id"
61296083
],
61306084
"properties": {
6085+
"id": {
6086+
"type": "string"
6087+
},
61316088
"signature": {
61326089
"type": "string"
61336090
},
@@ -6246,77 +6203,23 @@
62466203
"SignTransactionResponse": {
62476204
"oneOf": [
62486205
{
6249-
"allOf": [
6250-
{
6251-
"$ref": "#/components/schemas/SignTransactionResponseStellar"
6252-
},
6253-
{
6254-
"type": "object",
6255-
"required": [
6256-
"network"
6257-
],
6258-
"properties": {
6259-
"network": {
6260-
"type": "string",
6261-
"enum": [
6262-
"stellar"
6263-
]
6264-
}
6265-
}
6266-
}
6267-
]
6206+
"$ref": "#/components/schemas/SignTransactionResponseStellar"
62686207
},
62696208
{
6270-
"allOf": [
6271-
{
6272-
"type": "array",
6273-
"items": {
6274-
"type": "integer",
6275-
"format": "int32",
6276-
"minimum": 0
6277-
}
6278-
},
6279-
{
6280-
"type": "object",
6281-
"required": [
6282-
"network"
6283-
],
6284-
"properties": {
6285-
"network": {
6286-
"type": "string",
6287-
"enum": [
6288-
"evm"
6289-
]
6290-
}
6291-
}
6292-
}
6293-
]
6209+
"type": "array",
6210+
"items": {
6211+
"type": "integer",
6212+
"format": "int32",
6213+
"minimum": 0
6214+
}
62946215
},
62956216
{
6296-
"allOf": [
6297-
{
6298-
"type": "array",
6299-
"items": {
6300-
"type": "integer",
6301-
"format": "int32",
6302-
"minimum": 0
6303-
}
6304-
},
6305-
{
6306-
"type": "object",
6307-
"required": [
6308-
"network"
6309-
],
6310-
"properties": {
6311-
"network": {
6312-
"type": "string",
6313-
"enum": [
6314-
"solana"
6315-
]
6316-
}
6317-
}
6318-
}
6319-
]
6217+
"type": "array",
6218+
"items": {
6219+
"type": "integer",
6220+
"format": "int32",
6221+
"minimum": 0
6222+
}
63206223
}
63216224
]
63226225
},
@@ -6885,18 +6788,11 @@
68856788
"SolanaTransactionRequest": {
68866789
"type": "object",
68876790
"required": [
6888-
"fee_payer",
6889-
"instructions"
6791+
"transaction"
68906792
],
68916793
"properties": {
6892-
"fee_payer": {
6893-
"type": "string"
6894-
},
6895-
"instructions": {
6896-
"type": "array",
6897-
"items": {
6898-
"type": "string"
6899-
}
6794+
"transaction": {
6795+
"$ref": "#/components/schemas/EncodedSerializedTransaction"
69006796
}
69016797
}
69026798
},
@@ -6906,8 +6802,7 @@
69066802
"id",
69076803
"status",
69086804
"created_at",
6909-
"recent_blockhash",
6910-
"fee_payer"
6805+
"transaction"
69116806
],
69126807
"properties": {
69136808
"confirmed_at": {
@@ -6916,19 +6811,13 @@
69166811
"created_at": {
69176812
"type": "string"
69186813
},
6919-
"fee_payer": {
6920-
"type": "string"
6921-
},
6922-
"hash": {
6923-
"type": "string"
6924-
},
69256814
"id": {
69266815
"type": "string"
69276816
},
6928-
"recent_blockhash": {
6817+
"sent_at": {
69296818
"type": "string"
69306819
},
6931-
"sent_at": {
6820+
"signature": {
69326821
"type": "string"
69336822
},
69346823
"status": {
@@ -6939,6 +6828,9 @@
69396828
"string",
69406829
"null"
69416830
]
6831+
},
6832+
"transaction": {
6833+
"type": "string"
69426834
}
69436835
}
69446836
},
@@ -6955,6 +6847,9 @@
69556847
"type": "object",
69566848
"description": "Stellar policy response model for OpenAPI documentation",
69576849
"properties": {
6850+
"concurrent_transactions": {
6851+
"type": "boolean"
6852+
},
69586853
"max_fee": {
69596854
"type": "integer",
69606855
"format": "int32",

examples/launchtube-plugin-example/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ The LaunchTube plugin and relayer configurations are already set up for testnet.
121121
**`config/config.json`** (pre-configured):
122122

123123
- Three relayers defined: `launchtube-fund`, `launchtube-seq-001`, `launchtube-seq-002`
124+
- The Fund relayer has `concurrent_transactions: true` enabled in policies to allow parallel processing
124125
- Corresponding signers pointing to the key files you'll create
125126
- Plugin registered as `launchtube-plugin`
126127

@@ -284,6 +285,13 @@ const authXdrs = (op.auth ?? []).map(a => a.toXDR("base64"));
284285
5. **Fee Bumping**: Fund account wraps transaction with fee bump
285286
6. **Submission**: Sends to Stellar network
286287

288+
### Concurrent Transaction Processing
289+
290+
This example uses multiple Stellar accounts (fund account + sequence accounts) with `concurrent_transactions: true` enabled in the fund account relayer policy. This configuration:
291+
292+
- **Allows parallel processing**: Fund account leverages the sequence accounts sequence number, so transactions can be processed concurrently without blocking each other
293+
- **Improves throughput**: Multiple transactions can be in-flight simultaneously
294+
287295
## Troubleshooting
288296

289297
### Common issues

examples/launchtube-plugin-example/config/config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
"network": "testnet",
77
"paused": false,
88
"network_type": "stellar",
9-
"signer_id": "launchtube-fund-signer"
9+
"signer_id": "launchtube-fund-signer",
10+
"policies": {
11+
"concurrent_transactions": true
12+
}
1013
},
1114
{
1215
"id": "launchtube-seq-001",

src/api/controllers/relayer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ mod tests {
11351135
min_balance: Some(10000000),
11361136
max_fee: Some(100),
11371137
timeout_seconds: Some(30),
1138+
concurrent_transactions: None,
11381139
}));
11391140

11401141
let result = create_relayer(request, actix_web::web::ThinData(app_state)).await;

src/constants/relayer.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ pub const DEFAULT_EVM_EIP1559_ENABLED: bool = true;
1414
/// Default gas limit estimation enabled
1515
pub const DEFAULT_EVM_GAS_LIMIT_ESTIMATION: bool = true;
1616

17+
// === Stellar Policy Defaults ===
18+
/// Default concurrent transactions enabled setting for Stellar
19+
pub const DEFAULT_STELLAR_CONCURRENT_TRANSACTIONS: bool = false;
20+
1721
// === Solana Policy Defaults ===
1822
/// Default maximum transaction data size for Solana
1923
pub const DEFAULT_SOLANA_MAX_TX_DATA_SIZE: u16 = 1232;

0 commit comments

Comments
 (0)