-
Notifications
You must be signed in to change notification settings - Fork 123
soroban-rpc: Use in-memory event store in getEvents handler #385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
afa4858
Use in-memory event store in getEvents handler
tamirms ef3c84b
forgot to include cursor and cursor_test
tamirms cf13f78
Fix event.Type check
tamirms 2454ec4
Parse limit independently of cursor
tamirms a7a722d
fix tests
tamirms e65e065
address code review feedback
tamirms 83da834
fix lint errors
tamirms 39612aa
Use JSON RPC error codes
tamirms c8569bf
Merge branch 'main' into events-storage-handler
tamirms bf0d6a2
fix lint errors
tamirms 28791c5
address code review comments
tamirms a660457
fix readEvents()
tamirms File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| package events | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "math" | ||
| "strconv" | ||
| "strings" | ||
|
|
||
| "github.com/stellar/go/toid" | ||
| ) | ||
|
|
||
| // Cursor represents the position of a Soroban event. | ||
| // Soroban events are sorted in ascending order by | ||
| // ledger sequence, transaction index, operation index, | ||
| // and event index. | ||
| type Cursor struct { | ||
| // Ledger is the sequence of the ledger which emitted the event. | ||
| Ledger uint32 | ||
| // Tx is the index of the transaction within the ledger which emitted the event. | ||
| Tx uint32 | ||
| // Op is the index of the operation within the transaction which emitted the event. | ||
| Op uint32 | ||
| // Event is the index of the event within in the operation which emitted the event. | ||
| Event uint32 | ||
| } | ||
|
|
||
| // String returns a string representation of this cursor | ||
| func (c Cursor) String() string { | ||
| return fmt.Sprintf( | ||
| "%019d-%010d", | ||
| toid.New(int32(c.Ledger), int32(c.Tx), int32(c.Op)).ToInt64(), | ||
| c.Event, | ||
| ) | ||
| } | ||
|
|
||
| // ParseCursor parses the given string and returns the corresponding cursor | ||
| func ParseCursor(input string) (Cursor, error) { | ||
| parts := strings.SplitN(input, "-", 2) | ||
| if len(parts) != 2 { | ||
| return Cursor{}, fmt.Errorf("invalid event id %s", input) | ||
| } | ||
|
|
||
| // Parse the first part (toid) | ||
| idInt, err := strconv.ParseInt(parts[0], 10, 64) //lint:ignore gomnd | ||
| if err != nil { | ||
| return Cursor{}, fmt.Errorf("invalid event id %s: %w", input, err) | ||
| } | ||
| parsed := toid.Parse(idInt) | ||
|
|
||
| // Parse the second part (event order) | ||
| eventOrder, err := strconv.ParseInt(parts[1], 10, 64) //lint:ignore gomnd | ||
| if err != nil { | ||
| return Cursor{}, fmt.Errorf("invalid event id %s: %w", input, err) | ||
| } | ||
|
|
||
| return Cursor{ | ||
| Ledger: uint32(parsed.LedgerSequence), | ||
| Tx: uint32(parsed.TransactionOrder), | ||
| Op: uint32(parsed.OperationOrder), | ||
| Event: uint32(eventOrder), | ||
| }, nil | ||
| } | ||
|
|
||
| func cmp(a, b uint32) int { | ||
| if a < b { | ||
| return -1 | ||
| } | ||
| if a > b { | ||
| return 1 | ||
| } | ||
| return 0 | ||
| } | ||
|
|
||
| // Cmp compares two cursors. | ||
| // 0 is returned if the c is equal to other. | ||
| // 1 is returned if c is greater than other. | ||
| // -1 is returned if c is less than other. | ||
| func (c Cursor) Cmp(other Cursor) int { | ||
| if c.Ledger == other.Ledger { | ||
| if c.Tx == other.Tx { | ||
| if c.Op == other.Op { | ||
| return cmp(c.Event, other.Event) | ||
| } | ||
| return cmp(c.Op, other.Op) | ||
| } | ||
| return cmp(c.Tx, other.Tx) | ||
| } | ||
| return cmp(c.Ledger, other.Ledger) | ||
| } | ||
|
|
||
| var ( | ||
| // MinCursor is the smallest possible cursor | ||
| MinCursor = Cursor{} | ||
| // MaxCursor is the largest possible cursor | ||
| MaxCursor = Cursor{ | ||
| Ledger: math.MaxUint32, | ||
| Tx: math.MaxUint32, | ||
| Op: math.MaxUint32, | ||
| Event: math.MaxUint32, | ||
| } | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| package events | ||
|
|
||
| import ( | ||
| "math" | ||
| "testing" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| func TestParseCursor(t *testing.T) { | ||
| for _, cursor := range []Cursor{ | ||
| { | ||
| Ledger: math.MaxInt32, | ||
| Tx: 1048575, | ||
| Op: 4095, | ||
| Event: math.MaxInt32, | ||
| }, | ||
| { | ||
| Ledger: 0, | ||
| Tx: 0, | ||
| Op: 0, | ||
| Event: 0, | ||
| }, | ||
| { | ||
| Ledger: 123, | ||
| Tx: 10, | ||
| Op: 5, | ||
| Event: 1, | ||
| }, | ||
| } { | ||
| parsed, err := ParseCursor(cursor.String()) | ||
| assert.NoError(t, err) | ||
| assert.Equal(t, cursor, parsed) | ||
| } | ||
| } | ||
|
|
||
| func TestCursorCmp(t *testing.T) { | ||
| for _, testCase := range []struct { | ||
| a Cursor | ||
| b Cursor | ||
| expected int | ||
| }{ | ||
| {MinCursor, MaxCursor, -1}, | ||
| {MinCursor, MinCursor, 0}, | ||
| {MaxCursor, MaxCursor, 0}, | ||
| { | ||
| Cursor{Ledger: 1, Tx: 2, Op: 3, Event: 4}, | ||
| Cursor{Ledger: 1, Tx: 2, Op: 3, Event: 4}, | ||
| 0, | ||
| }, | ||
| { | ||
| Cursor{Ledger: 5, Tx: 2, Op: 3, Event: 4}, | ||
| Cursor{Ledger: 7, Tx: 2, Op: 3, Event: 4}, | ||
| -1, | ||
| }, | ||
| { | ||
| Cursor{Ledger: 5, Tx: 2, Op: 3, Event: 4}, | ||
| Cursor{Ledger: 5, Tx: 7, Op: 3, Event: 4}, | ||
| -1, | ||
| }, | ||
| { | ||
| Cursor{Ledger: 5, Tx: 2, Op: 3, Event: 4}, | ||
| Cursor{Ledger: 5, Tx: 2, Op: 7, Event: 4}, | ||
| -1, | ||
| }, | ||
| { | ||
| Cursor{Ledger: 5, Tx: 2, Op: 3, Event: 4}, | ||
| Cursor{Ledger: 5, Tx: 2, Op: 3, Event: 7}, | ||
| -1, | ||
| }, | ||
| } { | ||
| a := testCase.a | ||
| b := testCase.b | ||
| expected := testCase.expected | ||
|
|
||
| if got := a.Cmp(b); got != expected { | ||
| t.Fatalf("expected (%v).Cmp(%v) to be %v but got %v", a, b, expected, got) | ||
| } | ||
| a, b = b, a | ||
| expected *= -1 | ||
| if got := a.Cmp(b); got != expected { | ||
| t.Fatalf("expected (%v).Cmp(%v) to be %v but got %v", a, b, expected, got) | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.