-
Notifications
You must be signed in to change notification settings - Fork 0
SCP Gherkin Tests #10
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
base: main
Are you sure you want to change the base?
Changes from 8 commits
5e17c8f
6e1bf64
767f18c
16a55f4
6e030f5
c41fd02
fea6de7
f4c8d01
66243a3
6a1def7
ad3cb3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| Feature: Publisher Start Instance | ||
| The shared publisher is responsible for launching every SCP instance. | ||
| When an instance starts, it broadcasts the StartInstance message to each rollup that | ||
| appears in the XTRequest and starts a local timeout for the decision phase. | ||
|
|
||
| Background: | ||
| Given there is a shared publisher "SP" | ||
| And there is a chain "1" with sequencer "A" | ||
| And there is a chain "2" with sequencer "B" | ||
| And there is a chain "3" with sequencer "C" | ||
| And there is a chain "4" with sequencer "D" | ||
|
|
||
| @publisher @scp @start-instance | ||
| Scenario: Broadcasts StartInstance to all participating sequencers | ||
| When the shared publisher "SP" starts an instance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 7 | ||
| sequence_number: 3 | ||
| xtrequest: | ||
| 1: [tx1_1, tx1_2] | ||
| 2: [tx2] | ||
| 3: [tx3] | ||
| """ | ||
| Then sequencers "A,B,C" should receive StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 7 | ||
| sequence_number: 3 | ||
| xtrequest: | ||
| 1: [tx1_1, tx1_2] | ||
| 2: [tx2] | ||
| 3: [tx3] | ||
| """ | ||
| And a timer for instance "0x1" should start at the shared publisher | ||
|
|
||
| @publisher @scp @start-instance | ||
| Scenario: Notifies only chains referenced in the XTRequest | ||
| When the shared publisher "SP" starts an instance: | ||
| """ | ||
| instance_id: 0x2 | ||
| period_id: 8 | ||
| sequence_number: 4 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| Then sequencer "A" should receive StartInstance with instance ID "0x2" | ||
| And sequencer "B" should receive StartInstance with instance ID "0x2" | ||
| And sequencer "C" should not receive StartInstance for instance "0x2" | ||
| And sequencer "D" should not receive StartInstance for instance "0x2" | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||
| Feature: Publisher Timeout | ||||||
| The shared publisher starts a local timer when it launches an SCP instance. | ||||||
| If the timer expires before a decision is sent, it must reject the instance and notify | ||||||
| every participant. Once a decision is broadcast, any subsequent timeout should be ignored. | ||||||
|
|
||||||
| Background: | ||||||
| Given there is a shared publisher "SP" | ||||||
| And there is a chain "1" with sequencer "A" | ||||||
| And there is a chain "2" with sequencer "B" | ||||||
|
|
||||||
| @publisher @scp @timeout | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it redundant to have
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can argue that it adds clutter but adds convenience... |
||||||
| Scenario: Rejects instance when the timer expires before all votes are received | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe also add "before any votes" scenario
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added |
||||||
| Given the shared publisher "SP" started an instance: | ||||||
|
||||||
| Given the shared publisher "SP" started an instance: | |
| Given the shared publisher "SP" starts an instance: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Given the shared publisher "SP" started an instance: | |
| Given the shared publisher "SP" starts an instance: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feature file is missing a closing newline at the end. Gherkin feature files should end with a newline character for better compatibility with version control systems and text editors.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,128 @@ | ||||||
| Feature: Publisher Vote Processing | ||||||
| The shared publisher collects votes from the sequencers that were included in the XTRequest. | ||||||
| It keeps one vote per chain, rejects invalid senders, and finalizes the instance once the | ||||||
| voting rules are satisfied. | ||||||
|
|
||||||
| Background: | ||||||
| Given there is a shared publisher "SP" | ||||||
| And there is a chain "1" with sequencer "A" | ||||||
| And there is a chain "2" with sequencer "B" | ||||||
| And there is a chain "3" with sequencer "C" | ||||||
|
|
||||||
| @publisher @scp @votes | ||||||
| Scenario: Accepts instance after collecting all positive votes | ||||||
| Given the shared publisher "SP" started an instance: | ||||||
| """ | ||||||
| instance_id: 0x3 | ||||||
| period_id: 9 | ||||||
| sequence_number: 5 | ||||||
| xtrequest: | ||||||
| 1: [tx1] | ||||||
| 2: [tx2] | ||||||
| """ | ||||||
| When sequencer "A" publishes Vote with: | ||||||
| | field | value | | ||||||
| | instance_id | 0x3 | | ||||||
| | chain_id | 1 | | ||||||
| | vote | true | | ||||||
| And sequencer "B" publishes Vote with: | ||||||
| | field | value | | ||||||
| | instance_id | 0x3 | | ||||||
| | chain_id | 2 | | ||||||
| | vote | true | | ||||||
| Then the shared publisher "SP" should publish Decided with: | ||||||
|
||||||
| Then the shared publisher "SP" should publish Decided with: | |
| Then the shared publisher "SP" publishes Decided with: |
You don't have to take this.
I just think it reads better in case the step will be also used as an AND step.
But only some humans might care
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but isn't "should" the standard for "Then" clauses? For me both ways are fine, just wanted to confirm this w you first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc wise it is clear from this what will happen in other scenarios
But since we are trying to uncover bugs it is good to add more cases like a true voter that came before or after.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, adding it
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just note that since in this scenario you are not sending votes after, this step won't do much.
You can still leave it here though, no need to remove unless you want to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the logical difference between a simple: "sequencer A publishes Vote with"?
A goal that we have is that eventually we will have tests that can be ran with no changes in the golang side
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree 100%
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what did we decide with errors?
Do we want error codes (less readable) or creating error messages from text (text can also be a code)
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feature file is missing a closing newline at the end. Gherkin feature files should end with a newline character for better compatibility with version control systems and text editors.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| Feature: Sequencer Decision | ||
| On the sequencer perspective, an instance terminates in two cases: | ||
| - when it sends a rejection vote (either due simulation failure or timeout) | ||
| - when it receives a decision from the SP | ||
| If the instance is decided as rejected, the sequencer should not include its transactions in a block. | ||
| Else, it should include the transactions along with the created mailbox.putInbox ones. | ||
| Note that the shared publisher can only send a decision true if all sequencers have voted true. | ||
| Thus, receiving a decision true without having voted true is an invalid protocol state. | ||
|
|
||
| Background: | ||
| Given there is a chain "1" with sequencer "A" | ||
| And there is a chain "2" with sequencer "B" | ||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Rejects instance upon simulation failure | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| And the execution engine simulates "tx1" and returns an error other than "Read miss" | ||
| When sequencer "A" publishes Vote with: | ||
| | field | value | | ||
| | instance_id | 0x1 | | ||
| | chain_id | 1 | | ||
| | vote | false | | ||
| Then sequencer "A" should mark the instance "0x1" as rejected | ||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Rejects instance when decision is false | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| When sequencer "A" receives Decided for instance "0x1" with decision "false" | ||
| Then sequencer "A" should mark the instance "0x1" as rejected | ||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Errors when decision true arrives without a prior vote | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| And sequencer "A" has not published a Vote for instance "0x1" | ||
| When sequencer "A" receives Decided for instance "0x1" with decision "true" | ||
| Then an error occurs: | ||
| """ | ||
| decision true but no vote sent is an impossible state | ||
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Errors when decision true contradicts a prior false vote | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| And sequencer "A" previously published Vote with: | ||
| | field | value | | ||
| | instance_id | 0x1 | | ||
| | chain_id | 1 | | ||
| | vote | false | | ||
| When sequencer "A" receives Decided for instance "0x1" with decision "true" | ||
| Then an error occurs: | ||
| """ | ||
| decision true but previous vote was false is an impossible state | ||
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Finalizes instance when decision is received from SP | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| And the execution engine simulates "tx1" and returns success | ||
| And sequencer "A" previously published Vote with: | ||
| | field | value | | ||
| | instance_id | 0x1 | | ||
| | chain_id | 1 | | ||
| | vote | true | | ||
| When sequencer "A" receives Decided for instance "0x1" with decision <decision> | ||
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Then sequencer "A" should mark the instance "0x1" as <outcome> | ||
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Examples: | ||
| | decision | outcome | | ||
| | true | accepted | | ||
| | false | rejected | | ||
MatheusFranco99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| @sequencer @scp @decision | ||
| Scenario: Raises error when a decided instance receives a second decision | ||
| Given sequencer "A" receives StartInstance: | ||
| """ | ||
| instance_id: 0x1 | ||
| period_id: 2 | ||
| sequence_number: 2 | ||
| xtrequest: | ||
| 1: [tx1] | ||
| 2: [tx2] | ||
| """ | ||
| And sequencer "A" receives Decided for instance "0x1" with decision "false" | ||
| When sequencer "A" later receives Decided for instance "0x1" with decision "true" | ||
| Then an error occurs: | ||
| """ | ||
| instance already decided | ||
MatheusFranco99 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The feature file is missing a closing newline at the end. Gherkin feature files should end with a newline character for better compatibility with version control systems and text editors.