Skip to content

Add generate command and support for data-dependent endpoints#5

Open
cjonas9 wants to merge 82 commits intodevfrom
generate-command
Open

Add generate command and support for data-dependent endpoints#5
cjonas9 wants to merge 82 commits intodevfrom
generate-command

Conversation

@cjonas9
Copy link
Contributor

@cjonas9 cjonas9 commented Feb 11, 2026

What

Implements stellar-rpc-blaster generate, which collects seed data for data-dependent RPC endpoints. The data currently collected includes:

  • ledger_range: the first and last ledger in the range of sampled ledgers
  • txhash: list of hashes in specified ledger window and if they were successful
  • contract_id: list of contract IDs in the window
  • event_topics: list of unique contract event topics in the window
  • ledger_keys: list of ledger keys in the window for ledger entries that are of one of the following types:
    • Account
    • Contract data
    • Contract code
    • Trustline

Implements support for data-dependent endpoints in Blaster. The requests of these endpoints vary probabilistically based on constants defined in internal/util/constants.go. Namely, support was added for:

  • getLedgers, varies on: json/XDR, startLedger, pagination limit + cursor based/startLedger based
  • getLedgerEntries, varies on: json/XDR, 1 key/2-10 keys/50-200 keys, keys randomly chosen
  • getTransaction, varies on: json/XDR, hash found/not found -> successful/failed if found
  • getTransactions, varies on: json/XDR, startLedger, pagination limit + cursor based/startLedger based
  • getEvents, varies on: start/endLedger window, pagination limit, filters (include random contract ID/don't (if included, single ID/2-5 IDs), include 1 random topic filter/don't, include 1 random event type/don't)

Why

Blaster currently only supports parameter-free endpoints and it's useful to be able to load test parameter-dependent endpoints with representative sample data.
See #3 and #11 , which are parts of epic #2

Known limitations

N/A

@cjonas9 cjonas9 changed the base branch from main to dev February 17, 2026 21:34
@cjonas9 cjonas9 linked an issue Feb 23, 2026 that may be closed by this pull request
4 tasks
@cjonas9 cjonas9 marked this pull request as ready for review February 23, 2026 19:16
@cjonas9 cjonas9 requested a review from a team February 23, 2026 19:16

func getLedgerEntryChangesFromMeta(meta xdr.TransactionMeta) ([]xdr.LedgerEntryChange, bool) {
var changes []xdr.LedgerEntryChange
switch meta.V {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you might also be missing the top-level Operations field, yeah? It contains LedgerEntryChanges.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this feels like it belongs in the SDK, just for the future

Copy link
Contributor Author

@cjonas9 cjonas9 Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I addressed this recently, but given that this is new to me, it's worth a second look/huddle if you'd rather. To my knowledge this field is only set when V==0, which I had missed.


// SeedWriter accumulates seed data into an OutputSchema struct,
// then encodes it as a single ordered JSON object on Flush().
type SeedWriter struct {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be more idiomatic if it implemented the JSON encoder interface (MarshalJSON) rather than used composition, I think. Also you'd probably want this to implement io.WriteCloser, too.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then you'd be able to eliminate the OutputSchema construct

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminating any notion of OutputSchema is tough because it's used on both the read and write side of this (here in writer.go and also in loading in the parameters in run/parameters/load.go), but there's no reason it can't be embedded in SeedWriter instead of being a field, nor is there a reason why this can't implement those interfaces. I also renamed it to SeedData and moved it outside of the writer folder since it's not truly a writer-only object

if err != nil {
return errors.Wrap(err, "error marshalling JSON request")
var targeter vegeta.Targeter
if params, ok := paramCache[ep.DataPath]; ok && parameters.EndpointNeedsData(endpointKey) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't you remove this conditional and pass null/{} to the non-parameterized endpoints? Seems like it shouldn't matter to the calling context whether or not you need detailed params

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I disagree unless there's something I'm missing. In the "if" case, we make bodies (with type [][]byte), which has unique request bodies (that vary in parameters) in it, and in the "else", we're sending the same byte-for-byte request with the one body (of type []byte) in it. The rotating targeter vs. the non-rotating targeter take different arguments and are fundamentally different functions (as we don't have to deal with atomic increments/modulo in the one-body case), so I have them produce entirely different targeters that suit their needs respectively.

@cjonas9 cjonas9 requested a review from a team February 24, 2026 17:07
@cjonas9 cjonas9 moved this from To Do to Needs Review in Platform Scrum Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs Review

Development

Successfully merging this pull request may close these issues.

Client Load Testing: implement request data dependent endpoint tests Client Load Testing: Create tool 'generate' command

2 participants